NMI question in regards to cycles

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NMI question in regards to cycles
by on (#177406)
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)?
Re: NMI question in regards to cycles
by on (#177408)
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.
Re: NMI question in regards to cycles
by on (#177414)
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.
Re: NMI question in regards to cycles
by on (#177433)
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.
Re: NMI question in regards to cycles
by on (#177435)
RTI does not increment the PC it pulls off the stack -- it differs from RTS in this regard. Quoting the WDC docs for RTI:

Quote:
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.
Re: NMI question in regards to cycles
by on (#177498)
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".
Re: NMI question in regards to cycles
by on (#177516)
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.
Re: NMI question in regards to cycles
by on (#177517)
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.
Re: NMI question in regards to cycles
by on (#177580)
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.