A12 Timing Question

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
A12 Timing Question
by on (#239953)
I am trying to understand when PPU A12 is changed in order to correctly implement the MMC3 IRQ, but I'm not understanding something.

The wiki says that if using 8x8 sprites and BG uses $0000 and sprites use $1000, the IRQ counter should decrement on PPU cycle 260. However, when I look at the frame timing diagram, I notice that on PPU cycle 260, the garbage attribute table fetch occurs. Since the attribute table is in the $2000 page, PPU A12 should still remain low. On PPU cycle 262, the low sprite tile byte is fetched and its address is in the $1000 page, so A12 should become high then.

I don't understand why A12 first becomes high on PPU cycle 260 instead of PPU cycle 262. Am I misinterpreting the diagram or is there is something else I'm missing?
Re: A12 Timing Question
by on (#239958)
Parts of the wiki were written before the discovery of the 1-based pixel counting convention, which was observed through decapping the PPU. Under this convention, where background fetches occur at X=1 through X=256, the garbage nametable fetch occurs at X=257 through 260, and the sprite pattern fetch that triggers the MMC3 timer occurs at X=261 through 264.
Re: A12 Timing Question
by on (#239970)
Thank you! That makes much more sense.
Re: A12 Timing Question
by on (#239971)
I had another question. I'm currently failing the scanline timing test, but if I delay the first sprite and BG tile fetches by 1 PPU cycle (reading sprite on 263 and BG on 327), it passes.

I logged when I'm doing the reads and I'm doing them on the right cycle, and I passed the ppu_vbl_nmi tests. I'm not sure where else I could go wrong to receive this error. Are you aware of some other place that could cause this error?
Re: A12 Timing Question
by on (#240023)
Trace logs. Among the instructions, put a warning in the log when the IRQ is requested, then another when the IRQ is ready to trigger (meaning ready for its code execution). Analyse cycle and scanline, and see why it's happening there.