It is currently Sun Sep 15, 2019 5:31 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Sun May 05, 2019 1:22 pm 
Offline

Joined: Sun May 05, 2019 12:55 pm
Posts: 2
Hi all! I have a question about how Mesen handles NMI interrupts. I tried to search on this forum without any success, so I decided to write my first post here :)

I'm developing my first NES emulator using javascript, and I'm comparing Donkey Kong tracelogs from Mesen with the ones generated from my emulator.

Here's what I've got from Mesen when the first NMI happens:

...
86944 F4EF A:00 X:00 Y:00 P:IZ SP:FD CYC:338 SL:240
86946 F4F1 A:00 X:00 Y:00 P:IZ SP:FD CYC:3 SL:241
[NMI - Cycle: 86955]
86956 C85F A:00 X:00 Y:00 P:IZ SP:FA CYC:33 SL:241
86959 C860 A:00 X:00 Y:00 P:IZ SP:F9 CYC:42 SL:241
86962 C862 A:90 X:00 Y:00 P:NI SP:F9 CYC:51 SL:241
...

My assumption is that a single line is referred to an instruction BEFORE its execution, so my question is:
why the NMI is handled after F4F1 (STA, Zero page, 3 cycles) if this instruction is executed when the vBlank (and so the NMI) is already started (241/3)?

And in any case why there is this delay of 9 cycles between the F4F1 instruction (which happens at CPU cycle 86946) and the NMI (which happens at CPU cycle 86955) even if this STA should last 3 cycles?

Thanks in advance for your help :)
-Marco


Top
 Profile  
 
PostPosted: Sun May 05, 2019 2:00 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21591
Location: NE Indiana, USA (NTSC)
NMI waits for the current instruction to finish before pushing a modified BRK instruction into the instruction register. This BRK takes an additional 7 cycles to push the return address and status and read the vector. NMI modifies the BRK instruction's behavior in two ways: read the vector from $FFFA and $FFFB rather than $FFFE and $FFFF, and bit 4 of the pushed status is 0 (signifying a hardware interrupt) rather than 1 (which would signify a BRK or PHP). So if you have a STA zp instruction followed by NMI, the start of the STA zp instruction and the start of the NMI handler will be 10 CPU cycles apart: 3 for the STA zp and three for the BRK instruction injected by NMI. This corresponds to 30 dots on NTSC.

As for why the delay: The CPU checks for interrupts on the last cycle of the preceding instruction, the one that was at $F4EF. Because /NMI had not yet been pulled low on the last cycle of that instruction, the STA zp at $F4F1 was able to squeeze in.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Sun May 05, 2019 3:02 pm 
Offline

Joined: Sun May 05, 2019 12:55 pm
Posts: 2
Thanks for your reply!
Now it’s clear what happens during an NMI.

The only point that I didn’t get is why the NMI is after the STA given that this istruction is executed when the vBlank is already started and the NMI is generated. So the at the end of the previous instruction there should already be an NMI ready to be dispatched, at least as far as I

Thanks again :)

EDIT: I misread your answer, it was already explained. Sorry :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: JediJoey and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group