Some basics..

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Some basics..
by on (#72220)
Hi,

I have posted here before, but I can't remember my old username, so hello again (a few years ago I made a copyNES from kevtris' schematic on his site, I was also considering using a NES to read controller data and output data to an XBOX for emulation, but never tried it.) So..

I have always wanted to, but recently decided maybe I would get more serious about learning to code for the NES. I have read tons of docs, and asm code, but once you start to actually code you realize you are not clear on some details.

I realize that this information is out there, I just want a an explicit clear answers/opinions to some questions I have.:

1. Should or can any PPU writes be done during the frame, besides of course ones that must be for desired effects - split screen scrolling, etc

2. When the PPU activates the NMI is it okay to immediately start writing to the PPU (Is the PPU already in vblank as soon as NMI code is hit or does the NMI activate a few clocks early)?

3. I see it is common practice to buffer most writes and push them to the PPU in NMI, but what about nametables? They take up a lot of space. would you buffer new offscreen tiles when scrolling? Is it common practice to buffer a nametable, or is the code for that done in the NMI, or is this where metatiles help?

4. When is it a good idea to turn off the PPU? I see the PPU has to be off if you are filling the whole nametable, is there anything else that takes more than vblank time?

5. If I am in my NMI and I know a sub routine is going to take more than vblank is it okay to shut off the PPU in NMI and do my thing, then turn it back on and continue.. any issues to worry about?

6. Proper way to shut off the PPU for long writes? Turn off rendering? Everything?

7. What is with the read of $2002 in NMI? do I really need to read (acknowledge) it? what if I don't? (more just curious here..)
Re: Some basics..
by on (#72222)
Movax12 wrote:
1. Should or can any PPU writes be done during the frame, besides of course ones that must be for desired effects - split screen scrolling, etc

You can write to PPU registers $2000, $2001 freely. You can't read/write $2006/$2007 (unless rendering is disabled).
Quote:
2. When the PPU activates the NMI is it okay to immediately start writing to the PPU (Is the PPU already in vblank as soon as NMI code is hit or does the NMI activate a few clocks early)?

Yes it's ok.
Quote:
3. I see it is common practice to buffer most writes and push them to the PPU in NMI, but what about nametables? They take up a lot of space. would you buffer new offscreen tiles when scrolling? Is it common practice to buffer a nametable, or is the code for that done in the NMI, or is this where metatiles help?

The reason writes are buffered is because there's not very much VBLANK time per frame (~2K cycles). This means with even a completely unrolled loop you can only write about 250 bytes per frame. Not enough to update an entire nametable.

Games don't update the entire nametable every frame, they only update what's needed (for a sidescrolling game around 30 tiles (bytes) + attributes).
Quote:
4. When is it a good idea to turn off the PPU? I see the PPU has to be off if you are filling the whole nametable, is there anything else that takes more than vblank time?

You should wait for VBLANK before turning rendering on/off to avoid glitches. Also make sure palette writes are in VBLANK if you don't want any glitches on screen.

Quote:
5. If I am in my NMI and I know a sub routine is going to take more than vblank is it okay to shut off the PPU in NMI and do my thing, then turn it back on and continue.. any issues to worry about?

This depends on the situation but usually you don't want to do this. Black (/bg colored) frames don't look too good in between rendered frames. :)
Quote:
6. Proper way to shut off the PPU for long writes? Turn off rendering? Everything?

Turn off BG and sprite rendering by writing to $2001.

Quote:
7. What is with the read of $2002 in NMI? do I really need to read (acknowledge) it? what if I don't? (more just curious here..)

It's good practice but not strictly necessary. Not acknowledging it can lead to some nasty bugs in some cases.. for example if you toggle the NMI flag (in $2000) in your NMI code and didn't ack, it will cause a bogus new NMI to be generated.
Re: Some basics..
by on (#72223)
Movax12 wrote:
Hi,

I have posted here before, but I can't remember my old username, so hello again (a few years ago I made a copyNES from kevtris' schematic on his site, I was also considering using a NES to read controller data and output data to an XBOX for emulation, but never tried it.) So..

I have always wanted to, but recently decided maybe I would get more serious about learning to code for the NES. I have read tons of docs, and asm code, but once you start to actually code you realize you are not clear on some details.

I realize that this information is out there, I just want a an explicit clear answers/opinions to some questions I have.:

1. Should or can any PPU writes be done during the frame, besides of course ones that must be for desired effects - split screen scrolling, etc


The only PPU writes you do while the PPU is rendering are ones which change the screen scrolling, or turning off the screen. You don't do any data writes while the PPU is rendering.

Turning off the screen only seems to be 'safe' to do when you are in later pixels, but not quite at HBLANK time, around 200-255 seems safe. Otherwise you sometimes get sprite glitches in the next frame. This is new stuff that was discovered recently, and is still not understood well. Most games back in the day that turned off the screen during rendering time seemed to do it fine.

Movax12 wrote:
2. When the PPU activates the NMI is it okay to immediately start writing to the PPU (Is the PPU already in vblank as soon as NMI code is hit or does the NMI activate a few clocks early)?


The NMI actually comes a scanline late, there's an entire blank scanline where you are able to freely do drawing before the Vblank period starts. But the only way to take advantage of that is a well-timed interrupt near the bottom of the screen.

Movax12 wrote:
3. I see it is common practice to buffer most writes and push them to the PPU in NMI, but what about nametables? They take up a lot of space. would you buffer new offscreen tiles when scrolling? Is it common practice to buffer a nametable, or is the code for that done in the NMI, or is this where metatiles help?


Often games only use a small buffer for nametable updates. A row or column of tiles is about 32 bytes large, so a game may allocate 64 bytes for tile data, 16 bytes for tile attribute data, and any pointers and length information needed to draw it.
Mostly games draw a new row or column of background data as it scrolls. Some games draw two columns instead of just one, some even draw more.

Metatiles are still too slow for NMI processing time, you need to convert the metatiles into physical tiles during your main loop, then blast out the data during vblank time.

In my Chu Chu Rocket game, I'm using 216 bytes for nametable updates, and I'm blasting out an entire half-nametable every frame. This extends about 4 scanlines into the screen, then I do the scrolling and turn on the screen after it's done with all the drawing.

Movax12 wrote:
4. When is it a good idea to turn off the PPU? I see the PPU has to be off if you are filling the whole nametable, is there anything else that takes more than vblank time?


When you have CHR RAM, and you want to load an entire character set, that's also a good time to have the screen off for a few frames.
Or you might be using a system that runs the game's scrolling code to fill in the initial nametables, so you can call the code that produces the tiles and the code that consumes the tiles. I do that in one game, and it takes about 5 frames to draw the screen.

Movax12 wrote:
5. If I am in my NMI and I know a sub routine is going to take more than vblank is it okay to shut off the PPU in NMI and do my thing, then turn it back on and continue.. any issues to worry about?


If you do that, you turn the screen back on, and it will treat whenever you turned it on as the top of the screen, so you'll see the entire screen drawn too low for that frame.
If you know you will *consistently* draw more than NMI time every frame, you can have some of the top scanlines always blank, and make the effective top of the screen lower.

Movax12 wrote:
6. Proper way to shut off the PPU for long writes? Turn off rendering? Everything?


Usually you want to turn off the PPU during Vblank time for best results, then you don't have to worry about the sprite glitching bug.

If you're turning it off during rendering, and want to leave it off for a few frames, then you can get away with turning the screen off late.
If you're turning off the screen during rendering in order to make some PPU writes, try to do it late in a scanline, but not quite at HBLANK time. The DMC channel can sometime halt the CPU to fetch a byte, and that eats 5 CPU cycles, or 15 ppu pixels.

Movax12 wrote:
7. What is with the read of $2002 in NMI? do I really need to read (acknowledge) it? what if I don't? (more just curious here..)


Reading 2002 (PPUSTAT) will clear the VBL flag, and reset the low-byte high-byte latch that's used when you do your two writes to 2005 (PPUSCROLL) or 2006 (PPUADDR). It's a way of guaranteeing that the correct address is used when you set the PPU address. But if you need the help of reading 2002 to ensure the larch is in the right place, you probably have messy code.

If you don't do the 2002 read at the beginning of NMI, then you could get a second NMI interrupt if you disable then re-enable NMI, because the VBL flag is still set.

Sometimes a game will read 2002 a lot during vblank, this is because the Sprite 0 Hit flag does not clear until vblank ends. So games wait for the flag to become clear, then they know when rendering time has started, and they can start waiting for a new sprite 0 hit.

If you know you have a long NMI handler that always spills past VBLANK time, you can even read the VBL flag as a crude way of detecting a PAL region console.

by on (#72225)
I think between the two replies you've answered all my questions at least for the moment, thank you. If anyone would like to add anything though, feel free, more info is never bad.

From what I've just read, I would think then it is generally a good idea to wait for vblank to turn PPU drawing on or off, unless you know have the timing perfect?

thefox, I do realize that turning off the PPU for a few frames will result in the image disappearing for a few frames, I was thinking for setting up a new nametable (title screen to game for example).

by on (#72226)
Movax12 wrote:
From what I've just read, I would think then it is generally a good idea to wait for vblank to turn PPU drawing on or off, unless you know have the timing perfect?

You are correct. The side effects of not waiting for VBlank are not very bad though, the image just "jumps" for 1 frame, and in fact, many early commercial games do that once in a while, but it's certainly more professional to avoid this if you can.

Quote:
I do realize that turning off the PPU for a few frames will result in the image disappearing for a few frames, I was thinking for setting up a new nametable (title screen to game for example).

Yes, you typically turn rendering off for large screen updates between sections of the game. When rendering is off you don't even have to worry about buffering data, since the PPu is completely free for writing/reading.