@@ -2,17 +2,25 @@ auto APU::FrameCounter::main() -> void {
22 --counter;
33 odd = !odd;
44
5- if (delay && --delayCounter == 0 ) {
6- delay = false ;
7- step = 0 ;
8- counter = getPeriod () + 2 ;
9- if (mode == Freq48Hz) {
10- apu.clockHalfFrame ();
5+ if (!odd ) {
6+ // IRQ is reset on next GET cycle
7+ if (delayIRQ) {
8+ delayIRQ = false ;
9+ irqPending = 0 ;
10+ apu.setIRQ ();
1111 }
12+
13+ // counter is reloaded on GET cycle after next
14+ if (delayCounter[0 ]) {
15+ step = 0 ;
16+ counter = getPeriod ();
17+ if (mode == Freq48Hz) apu.clockHalfFrame ();
18+ }
19+ delayCounter[0 ] = delayCounter[1 ];
20+ delayCounter[1 ] = false ;
1221 }
1322
14- if (counter != 0 )
15- return ;
23+ if (counter != 0 ) return ;
1624
1725 switch (step) {
1826 case 0 :
@@ -29,21 +37,22 @@ auto APU::FrameCounter::main() -> void {
2937 break ;
3038 case 3 :
3139 step = 4 ;
32- if (mode == Freq60Hz && irqInhibit == 0 )
33- irqPending = 1 ;
40+ if (mode == Freq60Hz) irqPending = 1 ;
3441 break ;
3542 case 4 :
3643 step = 5 ;
3744 apu.clockHalfFrame ();
38- if (mode == Freq60Hz && irqInhibit == 0 ) {
45+ if (mode == Freq60Hz) {
3946 irqPending = 1 ;
4047 apu.setIRQ ();
4148 }
4249 break ;
4350 case 5 :
4451 step = 0 ;
45- if (mode == Freq60Hz && irqInhibit == 0 )
46- irqPending = 1 ;
52+ if (mode == Freq60Hz) {
53+ irqPending = ~irqInhibit;
54+ apu.setIRQ ();
55+ }
4756 break ;
4857 }
4958
@@ -52,30 +61,24 @@ auto APU::FrameCounter::main() -> void {
5261
5362auto APU::FrameCounter::power (bool reset) -> void {
5463 irqInhibit = 0 ;
55- if (!reset) mode = Freq60Hz;
64+ if (!reset) mode = Freq60Hz;
5665
5766 irqPending = 0 ;
5867 step = 0 ;
5968 counter = getPeriod ();
6069
6170 odd = true ;
62- delay = false ;
63- delayCounter = 0 ;
71+ delayIRQ = false ;
72+ delayCounter[0 ] = false ;
73+ delayCounter[1 ] = false ;
6474}
6575
6676auto APU::FrameCounter::write (n8 data) -> void {
6777 mode = data.bit (7 );
68- delay = true ;
69-
70- // If the write occurs during an APU cycle,
71- // the effects occur 3 CPU cycles after the
72- // $4017 write cycle, and if the write occurs
73- // between APU cycles, the effects occurs 4 CPU
74- // cycles after the write cycle.
75- delayCounter = odd ? 1 : 2 ;
78+ delayCounter[1 ] = true ;
7679
7780 irqInhibit = data.bit (6 );
78- if (irqInhibit) {
81+ if (irqInhibit) {
7982 irqPending = 0 ;
8083 apu.setIRQ ();
8184 }
0 commit comments