Do 2002.7 = 1 and NMI occur at the same time?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Do 2002.7 = 1 and NMI occur at the same time?
by on (#148110)
Is it correct to wait for 262x341* PPU cycles have passed and then set 2002.7 to 1 and immediately start NMI?
Should one of them start earlier? how much?

*: I'm not accounting for the 340 cycle scanline odd frames yet, and this is NTSC only of course.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148121)
I think they happen at the same time. But note that your typical read instruction does the read at the last cycle, so it's possible to begin a read instruction before NMI happens. The read instruction will read the vblank flag before the NMI happens, and that would cancel the NMI from ever happening.
Also, if the read happens on the exact cycle when NMI is set, it will read back 0 for that bit, and cancel NMI as well.

In PocketNES, I used a hack so that any pollable flag will be set 4 CPU cycles before the event happens, so the read instruction will see the flag change before the event happens.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148186)
Oh, so this might happen very frequently, as the main game loop usually enters a loop { LDA $2002; BPL } to wait for the next frame, right?
PS: Do you have an emulator written in other than Assembler?
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148190)
Petruza wrote:
Oh, so this might happen very frequently, as the main game loop usually enters a loop { LDA $2002; BPL } to wait for the next frame, right?

This is what early homebrew programs did, before we found out about this issue. In order to reliably detect VBlank, you have to use the NMI.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148221)
I don't know why, but im my emu i do the following "hack" to pass Blargg's test: at cc 1 of vblank i set the flag then at cc 3 check if vblank flag is set and if nmi_on_vblank is set and set a preliminay "ppu_nmi_pending" flag. Now if this ppu_nmi_pending flag is set i delay to cc 15 to set the "nmi_pending" flag on the cpu. This throw me an error in 1942 that leaves screen letters unredeable. And at the same way if i trigger the nmi the same time the flag is set Bomberman hangs in its init screen.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148253)
tokumaru wrote:
This is what early homebrew programs did, before we found out about this issue. In order to reliably detect VBlank, you have to use the NMI.

Oh ok, so they set some flag in RAM from the NMI subroutine and then check for that instead of 2002.7? because the main game loop has to know where to stop and loop again.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148254)
That's correct.
Re: Do 2002.7 = 1 and NMI occur at the same time?
by on (#148255)
Quote:
so they set some flag in RAM from the NMI subroutine and then check for that instead of 2002.7?

NMI#Race condition describes how this works.