Extractos de Nesdev by Ealdor
Escrito el Viernes 17 de Abril del 2009 por Ealdor
En esta sección pondré todos los extractos del foro de Nesdev que puedan ser de utilidad.
[A] Disch - Posted: Sun Jan 11, 2009 2:28 pm
Seperating the infinite loop from the NMI is unimportant in simple programs, but to handle slowdown effectively, it can be useful to keep them each doing seperate jobs. The approach I'd use would be something like this:
In Infinite loop:
1) Update joypad data
2) Do game logic (collision detection, AI, etc)
3) Draw sprites and stuff to shadow OAM
4) Prepare an organized list of PPU writes in a buffer so that you can quickly dump stuff to $2007 next vblank.
5) Set a "can draw" flag
6) Set a "waiting for VBl" flag
7) Wait for "waiting for VBl" flag to clear
8) Repeat from step 1
In NMI:
1) Set up CPU cycle based IRQ if needed for raster effects (if mapper 069 or something -- probably not applicable most of the time).
2) Do Sprite DMA (only if "can draw" flag is set)
3) Scan the prepared drawing buffer and do all desired $2007 writes (step 4 in infinite loop) -- (only if "can draw" flag is set)
4) Clear the "can draw" flag to indicate drawing is done
5) Set scroll
6) Set up PPU based IRQ if needed for raster effects (if mapper 004 or something)
7) Just to music routine to keep music/sound effects playing
8) Clear "waiting for vbl" flag
9) RTI
This setup keeps the logic and drawing code seperated so that if NMI interrupts your game logic, you can still do necessary raster effects like splitting the screen, as well as keep music playing without disrupting game logic.
Also the "can draw" flag prevents your NMI handler from drawing half-completed stuff if the NMI happens in the middle of your preparation.
So this setup gracefully handles slowdown and stuff without causing weird graphical glitches.
EDIT: it dawns on me that you can use the "waiting for vblank" flag as the "can draw" flag -- so you only need one flag. *shrug*