Vertical nametable loading
Moderator: Moderators
Vertical nametable loading
I think I read somewhere in the hardware reference for the PPU that you can set it to accept nametable bytes vertically instead of horizontally. For example after sending in the byte to $2000 the next byte it will expect will be sent to $2020 followed by $2040, etc. Is this a good way of partially preloading nametables for scrolling? Sorry if this is a dumb or confusing question I don't think I quite have all of my terminology down yet.
Re: Vertical nametable loading
Yes. When you read from or write to the PPU data register ($2007), the VRAM address is automatically incremented. That increment is either by 1 (for writing nametables horizontally by row) or 32 (vertically by column), controlled by bit 2 of the PPU control register ($2000). Typically, you'll want to increment in the direction perpendicular to your scroll direction so you can write the next column or row you intend to scroll in without having to manually change the address after each write, which is very slow, particularly in comparison to the limited vblank window for writing to VRAM.
Re: Vertical nametable loading
Thank you. I kinda wish I had realized this before I wrote my level data decompression algorithm but I guess it's all good practice to someone learning 6502asm. One question though. At what point does the PPU increment to accessing the attribute data? Does it come after every 30 bytes? Or is it still done sequentially after the nametable is loaded? Like, do I have to manually jump to the attribute bytes for the column I just added? I hope you understand what I am trying to ask. Thank again.
Re: Vertical nametable loading
The increment behavior is the same regardless of the current VRAM address; it simply adds 1 or 32. This doesn't play nicely with attributes, which have 8 byte rows, and attributes in general are a real pain to deal with.
Re: Vertical nametable loading
So my guess is that I should write an algorithm to write four 30byte columns (skip 2 bytes after every 30) and then manually addresses and set the 8 bytes of attributes for that area. Correct?
Re: Vertical nametable loading
4 columns is ambitious; I think you can make it work, but it's costly to write all of that at once. Doing 2 columns at a time is more reasonable, though it makes the attributes handling more difficult. You'll be updating the address after each column, but not to 'skip 2 bytes' because the columns aren't contiguous in that way; each column's starting address is 1 apart. For attributes, you can batch 2 writes together with the 32 byte increment mode so you only have to set the address 4 times.
Re: Vertical nametable loading
Regarding attributes and 32 increment mode, there actually is a use for that.
Attribute table is 8 bytes wide (8 * 32 pixels), and 8 bytes tall (8 * 32 pixels). 32 bytes ahead of the last attribute byte means you advance 4 'rows' (128 pixels) down.
So if you're trying to write attributes for a whole column of tiles, you can write two attribute bytes. One for your target position, one for 128 pixels lower.
I find it makes things easier if you keep a copy of the whole attribute table in RAM. It's 128 bytes for the two nametables.
Attribute table is 8 bytes wide (8 * 32 pixels), and 8 bytes tall (8 * 32 pixels). 32 bytes ahead of the last attribute byte means you advance 4 'rows' (128 pixels) down.
So if you're trying to write attributes for a whole column of tiles, you can write two attribute bytes. One for your target position, one for 128 pixels lower.
I find it makes things easier if you keep a copy of the whole attribute table in RAM. It's 128 bytes for the two nametables.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Re: Vertical nametable loading
I meant do one column at a time, maybe two. But no need to update the attributes until after four rows are written because each attribute byte describes a 4 column by 4 row section.