NMI question in regards to cycles

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
Bowie90333212391
Posts: 11
Joined: Sun Aug 16, 2015 9:02 am

NMI question in regards to cycles

Post by Bowie90333212391 »

According to http://wiki.nesdev.com/w/index.php/CPU_ ... _execution, it takes 7 cycles to perform the NMI. The NMI gets triggered when the PPU is on dot 1 (second dot) of scanline 241, according to http://wiki.nesdev.com/w/index.php/PPU_rendering.

Is it correct to believe that, by the time the CPU starts executing the NMI handler pointed to by FFFA/FFFB, the PPU will be dot 8 of scanline 241, OR should the PPU also stop while these 7 cycles are being performed?


Also -- How does the NMI work if it was in the middle of executing an instruction? For example, If the CPU had two cycles left until it completed its instruction that was a total of 4 cycles, when the NMI handler completes and returns back to that instruction, does it start it from the beginning (4 cycles) or where it left off (2 cycles)?
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: NMI question in regards to cycles

Post by thefox »

CPU cannot and will not stop PPU under any condition.

If NMI occurs in the middle of an instruction, the current instruction is finished before the execution is taken to the NMI handler.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: NMI question in regards to cycles

Post by tokumaru »

Interrupting a instruction could have disastrous results. The way the CPU works is that it only checks for interrupts when instructions finish, so even if the IRQ signal is asserted in the middle of an instruction, the CPU will only notice it when the instruction ends.
Bowie90333212391
Posts: 11
Joined: Sun Aug 16, 2015 9:02 am

Re: NMI question in regards to cycles

Post by Bowie90333212391 »

My understanding is that the NMI pushes the current PC on the stack (of the instruction that just completed), instead of the next instruction.

So when the NMI completes (i.e. RTI is called) and you go to restore PC back to its original address before the NMI, do you advance PC by what instruction was originally there, or the instruction that is currently there? I say this since I suppose its possible that the ISR can modify the instructions that were at the location where the NMI occurred.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: NMI question in regards to cycles

Post by koitsu »

RTI does not increment the PC it pulls off the stack -- it differs from RTS in this regard. Quoting the WDC docs for RTI:
Unlike the RTS instruction, the program counter address pulled off the stack is the exact address to return to; the value on the stack is the value loaded into the program counter. It does not need to be incremented as a subroutine’s return address does.
AWJ
Posts: 433
Joined: Mon Nov 10, 2008 3:09 pm

Re: NMI question in regards to cycles

Post by AWJ »

Bowie90333212391 wrote:My understanding is that the NMI pushes the current PC on the stack (of the instruction that just completed), instead of the next instruction.
No, that's wrong. Interrupts push the PC of the next instruction, the one that would be executed if not for the interrupt. RTI doesn't adjust the address it pops in any way; it transfers it directly to the PC.

JSR pushes the PC of the next instruction minus 1 (or the address of the MSB of the JSR's operand, if you prefer). And RTS correspondingly adds 1 to the address it pops off the stack.

In neither case does the 6502 need to reread an already-executed instruction, or to somehow "remember" the length of a previously-executed instruction. All the information that RTI or RTS needs to resume execution is present on the stack.

Interrupts never happen in the middle of an instruction on the 6502. The CPU only checks the interrupt lines during the last cycle of each instruction, before it fetches the next instruction. Because of this, it can take several cycles to service an interrupt depending on what the CPU is doing at the time. This is known as "interrupt latency".
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: NMI question in regards to cycles

Post by Jarhmander »

CPUs that abandons the current multi-cycle instruction to service interrupts are not common. ARM can do this, at least the Cortex-M profile. In fact, there are three silicon options available: do not interrupt instructions, interrupt multi-cycle instructions but the instruction will be completely re-executed, interrupt multi-cycle instructions and save enough state on the stack to resume it. The 2nd variant is the most common.
((λ (x) (x x)) (λ (x) (x x)))
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: NMI question in regards to cycles

Post by tepples »

Jarhmander wrote:CPUs that abandons the current multi-cycle instruction to service interrupts are not common.
I thought most major CPUs since the 68000 and 65816 could do it. They have something called a "bus error", which lets a memory controller tell the processor to raise an exception because either nothing is mapped to a particular address or something is mapped that the current process should not be able to see. On the 68000 it's called /BERR; on the 65816 it's called /ABORT.
User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 569
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: NMI question in regards to cycles

Post by Jarhmander »

That's true, but observe that only specific interruptions (exceptions) have that property, and they relate to error conditions. On the ARM, at least the Cortex-M, all interrupts can stop an instruction.
((λ (x) (x x)) (λ (x) (x x)))
Post Reply