auto APU::runsequencer() -> void { auto& r = sequencer; if(r.base == 0) { //512hz if(r.step == 0 || r.step == 2 || r.step == 4 || r.step == 6) { //256hz square1.clocklength(); square2.clocklength(); wave.clocklength(); noise.clocklength(); } if(r.step == 2 || r.step == 6) { //128hz square1.clocksweep(); } if(r.step == 7) { //64hz square1.clockenvelope(); square2.clockenvelope(); noise.clockenvelope(); } r.step++; } r.base++; if(square1.enable) square1.run(); if(square2.enable) square2.run(); if(wave.enable) wave.run(); if(noise.enable) noise.run(); } auto APU::Sequencer::read(uint addr) const -> uint8 { switch(addr) { case 0: return (rvolume << 0) | (lvolume << 4); case 1: return ( (renable[0] << 0) | (renable[1] << 1) | (renable[2] << 2) | (renable[3] << 3) | (lenable[0] << 4) | (lenable[1] << 5) | (lenable[2] << 6) | (lenable[3] << 7) ); case 2: return ( (apu.square1.enable << 0) | (apu.square2.enable << 1) | (apu.wave.enable << 2) | (apu.noise.enable << 3) | (masterenable << 7) ); } } auto APU::Sequencer::write(uint addr, uint8 byte) -> void { switch(addr) { case 0: //NR50 rvolume = byte >> 0; lvolume = byte >> 4; break; case 1: //NR51 renable[0] = byte >> 0; renable[1] = byte >> 1; renable[2] = byte >> 2; renable[3] = byte >> 3; lenable[0] = byte >> 4; lenable[1] = byte >> 5; lenable[2] = byte >> 6; lenable[3] = byte >> 7; break; case 2: //NR52 masterenable = byte >> 7; break; } } auto APU::Sequencer::power() -> void { lvolume = 0; rvolume = 0; for(auto& n : lenable) n = 0; for(auto& n : renable) n = 0; masterenable = 0; base = 0; step = 0; lsample = 0; rsample = 0; }