NMI thread: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(copy data from what part of RAM?)
(tokumaru suggested to deemphasize the fact that it's threading because threading is scary)
Line 9: Line 9:
And if your scanline counter is based on sprite 0 hit and not an IRQ, it will cause visual glitches as the status bar flickers.
And if your scanline counter is based on sprite 0 hit and not an IRQ, it will cause visual glitches as the status bar flickers.


To make the status bar rock-solid in the face of excessive game logic, you can break your program into two [[wikipedia:Thread (computer science)|threads]] and move VRAM uploads into the NMI handler.
To make a top status bar rock-solid in the face of excessive game logic, you can move VRAM uploads and sprite 0 handling into the NMI handler.
Because the NMI handler itself is never interrupted, the locking can be much simpler than it is in multithreaded programming on a PC.
The main program prepares VRAM updates in main RAM, and once the VRAM update request is ready, it turns on a flag VRAM_update_ready to let the NMI handler know.
In this program structure, the main thread prepares VRAM updates in main RAM and maintains a flag VRAM_update_ready to let the NMI thread know whether the VRAM update request is consistent.
This is similar to [[wikipedia:Thread (computer science)|multithreaded programming]], but because the NMI handler itself is never interrupted, the locking can be much simpler than it is in multithreaded programming on a PC.


The NMI thread has these steps:
The NMI thread has these steps:

Revision as of 21:32, 29 March 2010

The NMI article describes the simplest possible working method to wait for vertical blank. This works for simple games without a status bar or for games whose upper limit on CPU use is easy to predict. It may also work for games whose mapper has a scanline counter that triggers an IRQ.

But once your game world becomes more complex, the simple method may cause problems. For example, consider a video game that has a status bar and several critters running around. It may occasionally take longer than one screen to process AI, physics, and display updates once enough critters with complex movement patterns are spawned, such as multiple Hammer Brothers in Super Mario Bros. or all the ducks turtles in the middle of World 3-7 of Super Mario Bros. 3. This will cause your game to slow down when an NMI occurs while your game is doing something else. And if your scanline counter is based on sprite 0 hit and not an IRQ, it will cause visual glitches as the status bar flickers.

To make a top status bar rock-solid in the face of excessive game logic, you can move VRAM uploads and sprite 0 handling into the NMI handler. The main program prepares VRAM updates in main RAM, and once the VRAM update request is ready, it turns on a flag VRAM_update_ready to let the NMI handler know. This is similar to multithreaded programming, but because the NMI handler itself is never interrupted, the locking can be much simpler than it is in multithreaded programming on a PC.

The NMI thread has these steps:

  1. Let the main program know that NMI has occurred, as in the simple method.
  2. Push all registers.
  3. If VRAM_update_ready is false, go to step 5.
  4. Copy data from the VRAM update request areas in RAM into VRAM and OAM.
  5. Set VRAM_update_ready to false.
  6. Set the scroll position using PPUCTRL and PPUSCROLL.
  7. (Optional) Run the music code.
  8. (Optional) Wait for sprite 0 hit and change the VRAM address.
  9. Pull all registers and return.