2 vblank/nmi questions

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
ittyBittyByte
Posts: 24
Joined: Sun Dec 18, 2016 1:11 pm

2 vblank/nmi questions

Post by ittyBittyByte »

So the NMI is just a piece of code that automatically triggers at vblank right? If thats the case I have 2 questions:

1: Does that mean normal asm code runs asynchronously as the last or current frame is being drawn? Otherwise, wouldn't it only be able to be running during vblank as that's when it's not drawing?

2: If so, how does it stay in sync? What if the code is not completed when it comes time to start drawing the next frame? If the code is half done wouldn't it mean that only about half of the sprites would appear or am I wrong?
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 2 vblank/nmi questions

Post by rainwarrior »

It's not asynchronous execution. There's only one CPU. It's an interrupt.

Execution stops, the program counter and status flags are pushed to the stack, and it jumps to the NMI code. When the RTI (return from interrupt) instruction is hit, it recovers that information from the stack and resumes.

Yes, NMI signals at the beginning of vblank, and the point is to run code during vblank that needs to mess with the PPU while it's not engaged in drawing the screen. (Trying to do so while it's rendering has unpleasant results.)
ittyBittyByte
Posts: 24
Joined: Sun Dec 18, 2016 1:11 pm

Re: 2 vblank/nmi questions

Post by ittyBittyByte »

What I meant is does the CPU run while the PPU draws the frame or what? Because the way I know lots of newer games work is by first taking input then doing game logic then rendering and then repeating that as fast as possible, the idea of cpu beginning execution when something on the gpu/ppu happens is foreign to me, so it is hard for me to understand the order things are done in.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 2 vblank/nmi questions

Post by rainwarrior »

Yes. The PPU is idle during vblank (or if turned off), and otherwise it's occupied drawing the frame.

The PPU generates the NMI signal at the start of vblank (if the signal is turned on), and the CPU will be interrupted at that time and start executing its NMI handler code.

The PPU does not run the NMI code, it doesn't have software of its own, it just generates the video signal.
ittyBittyByte
Posts: 24
Joined: Sun Dec 18, 2016 1:11 pm

Re: 2 vblank/nmi questions

Post by ittyBittyByte »

So if the cpu runs normal code while the ppu renders then how does it stay in sync? For example if only half of all "objects" or sprites are updated to their new positions in the cpu and then it comes time for the PPU to collect sprites to draw them then will half of the sprites be at their new position and half at the old position in the frame, or something else will happen? Or is that just not possible?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 2 vblank/nmi questions

Post by tokumaru »

It normally goes like this:

1 - Main code processes game logic, computes new sprite positions, etc., then waits for the NMI;
2 - Vblank starts, the NMI fires and interrupts whatever the CPU is doing, then blasts all buffered video updates to the PPU;
3 - NMI handler gives control back to the main code, which detects that an NMI happened and proceeds to process the next frame.

Now, it's entirely possible that an NMI fires while step #1 hasn't finished yet, meaning that it can't reliably perform any graphical updates. This is normally detected by the NMI handler through the use of a flag, that the main code sets when it finishes processing each frame. If the flag isn't set, the NMI handler restricts itself to performing high priority tasks that aren't supposed to lag, such as updating the audio and setting up raster effects.

When the NMI handler is finished, control is transferred back to the main code, which then finishes the frame it couldn't finish before. It will set the flag indicating that the game logic has been fully processed and only when the next NMI fires will the video updates finally happen. This is why games lag when the CPU is under heavy load.

EDIT: Another important point that might not be clear: the CPU and the PPU run in parallel. The PPU is programmed (a program "embedded in the chip" that you can't change) to draw an image, pixel by pixel, using information from various parts of its memory (pattern, name and attribute tables, OAM and palette RAM), then "rest" for the duration of vblank, and repeat this process over and over. If the contents of the PPU memory don't change, neither does the picture it generates. So, to answer your question, synchronization of maintained by not changing the PPU memory at all if the CPU couldn't finish computing all the changes in time, effectively causing the PPU to draw the exact same picture again, which results in slowdown.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: 2 vblank/nmi questions

Post by rainwarrior »

ittyBittyByte wrote:So if the cpu runs normal code while the ppu renders then how does it stay in sync?
The PPU sends the NMI signal to the CPU every vblank. That's what's used to synchronize the PPU and the CPU. On the CPU, that signal gets to the software in the form of an interrupt, and it's the software's job to do things with appropriate timing in response.

Edit: sorry if I'm repeating myself. Maybe tokumaru's answer was what you're really looking for.
ittyBittyByte
Posts: 24
Joined: Sun Dec 18, 2016 1:11 pm

Re: 2 vblank/nmi questions

Post by ittyBittyByte »

What happens if NMI code doesn't finish in time when the PPU actually starts to draw the next frame?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: 2 vblank/nmi questions

Post by tokumaru »

If you're still using $2006/7, the picture will get corrupted. The PPU will try to read stuff from VRAM/VROM while you're still manipulating the address register so it will end up fetching the wrong data and drawing garbage on the screen. If you're not using any of the PPU registers anymore, and the scroll has already been set, the NMI can safely perform other tasks (like audio or input, if you wish) as long as it finishes before the next NMI fires.
Post Reply