Need your help for APU timing issue

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Need your help for APU timing issue
by on (#135872)
I have implemented APU emulation for ffnes.
After run some of APU test rom, I found there are lots of timing issue of my APU emulation.

run 4-jitter.nes, it says:

Frame irq is set too soon
4-jitter
Failed #2

As I known, The Frame sequencer's divider generates an output clock rate of just under 240 Hz, may be 21.47727 MHz master clock, divided by 89490. My implemention of apu, I using ppu clock, which is divided by 4 of master clock, to clock the divider, instead of master clock.
so I using 21477272 / 4 / 240 = 22372.158333333333333333333333333 = (int)22372 as the period of Frame sequencer divider.
I checked all related code of apu, could't found any problem, except the period of Frame sequencer divider, which is not divisible but using 22372 approximately instead.

If I use 22372 + 1 instead of 22372, then run the 4-jitter.nes, it says:

Odd jitter not handled
properly
4-jitter
Failed #5

We can see the test result is related to the period, when change the period, test result will be changed. so.
I think the divider period is the root cause. Anyone could help me to explain the details of the timming, and the real root cause of this issue.
And also give me a method how to fix this issue.

Thanks.
Re: Need your help for APU timing issue
by on (#135874)
The APU is strictly locked to the CPU (exactly half), and the "240Hz" is actually (APU Clock = 39375000 Hz ÷ 44) ÷ 3728.5 ≈ 240.0124 Hz.

Using exactly 21477273 Hz ÷ 4 ÷ 22372 would have the frame interrupt happening too fast by 1 APU cycle = 2 CPU cycles.

See http://wiki.nesdev.com/w/index.php/APU_Frame_Counter
Re: Need your help for APU timing issue
by on (#135936)
lidnariq wrote:
The APU is strictly locked to the CPU (exactly half), and the "240Hz" is actually (APU Clock = 39375000 Hz ÷ 44) ÷ 3728.5 ≈ 240.0124 Hz.

Using exactly 21477273 Hz ÷ 4 ÷ 22372 would have the frame interrupt happening too fast by 1 APU cycle = 2 CPU cycles.

See http://wiki.nesdev.com/w/index.php/APU_Frame_Counter


By the article itself, the rate is not 240.0124 Hz, but 239.996 Hz - the first clock happens after 3728.5 APU cycles, but the second one happens 3728 cycles later, then 3729 cycles for the next one, and 3729 more cycles for the last one, plus an extra half cycle to round it off when it repeats. The end result is 14915 APU cycles per 4 quarter-frames, or (APU Clock = 39375000 Hz ÷ 44) ÷ 14915 * 4 ≈ 239.996 Hz.

In other words, the 240Hz "clock" is not generated by a flat 240Hz divider - it is instead clocked by a ~60Hz counter at 4 specific cycles within the sequence. The 120Hz "clock" is done the same way.