NMIs triggered inside VBlank

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NMIs triggered inside VBlank
by on (#103)
(Wow, i'm using phpbb!) ;)

I recently added a little thing to my emu:
If $2000.7 toggles 0->1 when $2002.7 is high, an NMI is triggered.
This seems 100% logical to me, but it screwed up Laser Invasion:

Before:ImageAfter:Image
(The VRAM address gets screwed up during nametable filling)

I was just wondering if anybody's found any other game where this functionality makes a difference, or else I'll just omit it.
Perhaps someone doesn't have this problem at all with Laser Invasion?

/Martin
Re: NMIs triggered inside VBlank
by on (#105)
Nessie wrote:
I recently added a little thing to my emu:


Not so little when it comes to games such as Dynamite Bowl and Spelunker (probably lots of others too). If these two games work fine on your emulator then I don't know what could be the problem (perhaps the fact that the game uses MMC5 has to do something with it).

by on (#106)
Hmm, they both work, regardless of the NMI thing. Where are they supposed to glitch?
Did you get Laser Invasion to work with this NMI thing?

by on (#108)
I use said 'NMI thing' in my emulator, and Laser Invasion works perfectly.

by on (#109)
Ok, thanks. I guess it's my MMC5 code then. Probably the IRQs... :?
- $5204.7 is set on the scanline ($5203) if rendering is enabled.
- If IRQs are enabled, an IRQ is also triggered.
- Both the bit and the pending IRQ are cleared when reading $5204.
- Are they cleared under any other condition? I tried clearing them on scanline 240, without luck.

Or else i'll just ignore that 'NMI thing' and hope most games work anyway :)

by on (#143)
Try to clear both $5204.7 and the IRQ if the scanline ($5203)+1 is reatched without clearing it by reading.

by on (#1510)
I know I'm bumping a very old topic with this... but I've recently been running into problems with this implimentation.

Not with Laser Invasion... but with Eggerland, and Adventures of Lolo 2 & 3.. causing hangups in all 3 games. I've been looking at Eggerland, specifically... and it seems to do a large drawing routine in when rendering is turned off, during which times it enables, then shortly after disables NMIs (without waiting for NMIs). It does it several times in the frame, spilling into next frame's VBlank, where enabling NMIs triggers an NMI... which screws the whole thing up -- it eventually goes in a wait-for-NMI infinite loop without NMIs enabled (locking up the game)

Is there some sort of delay between the $2000 write and the following NMI? Or does it happen immediately? Did anyone else have these problems with these games? Any ideas?

by on (#1511)
Try triggering the NMI right after the instruction that follows sta $xxxx or whatever. Like so:

sta $2000
(some instruction)
jsr 8000; trigger the NMI right before this occurs

by on (#1512)
I thought about doing that -- from what I looked at Eggerland's code it looks like it would solve its problem. However that seems awfully hackish....

edit: I guess -- if there's a short delay between the start of VBlank and an NMI... perhaps it does make sense that there's a delay between the $2000 write and an NMI.

by on (#1513)
Hyde wrote:
Try triggering the NMI right after the instruction that follows sta $xxxx or whatever. Like so:

sta $2000
(some instruction)
jsr 8000; trigger the NMI right before this occurs


This is exactly what should be done - a small test I wrote verifies this behaviour on a real NES.