Question on background tiles(and how to put them into the PPU)

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
xX_pokeman2003_Xx
Posts: 2
Joined: Sun Sep 13, 2020 9:51 pm

Question on background tiles(and how to put them into the PPU)

Post by xX_pokeman2003_Xx » Mon Sep 14, 2020 12:06 am

Hi all, first post! I feel really embarrassed making this, since it's basically 101 NES game making. The basic gist of the situation is that I have a displayable item(stolen from the pattern table example), but no matter how many times I've scanned over the PPU programmer's reference, I still don't quite understand what I'm supposed to do with it. My goal is to put it into the tilemap for backgrounds. After all, the eventual goal is to have text displayed on screen, and sharing 64 sprites with a bunch of other resources won't work. I've managed to display my sprite valiantly on the screen, but I'm still completely unable to figure out how to get it into the tilemap so that I can use it with the attribute and nametable. How would I achieve this effect?

User avatar
nesrocks
Posts: 468
Joined: Thu Aug 13, 2015 4:40 pm
Location: Rio de Janeiro - Brazil
Contact:

Re: Question on background tiles(and how to put them into the PPU)

Post by nesrocks » Mon Sep 14, 2020 5:17 am

Shorterest version: write twice to 2006 to write the NAM address (in the range of $2000-$2400 for NAM 0), then write as many bytes as you want to $2007 (these are the tiles you want to see on screen).

This will work, it will write to the nametable. After you've done that, you will notice there can be scrolling glitches at the moment you write the data, so there are two different fixes. One is simple. Have drawing bg and sprites disabled (controlled by $2001 register). Then when you're done writing to 2007 you enable drawing again. The screen will be black while doing this.

The other fix is a bit more complicated and allows you to update the nametable without turning off the screen, but I suggest you try method 1 first.
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!

User avatar
tokumaru
Posts: 11858
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Question on background tiles(and how to put them into the PPU)

Post by tokumaru » Mon Sep 14, 2020 9:52 am

The background is defined by the name and attribute tables. Think of each name table as a grid of 32x30 tile indices, where each index corresponds to a tile. The attribute tables are more complex, so you can worry about them later, but they define what palettes the tiles in the name tables will use.

The CPU doesn't have direct address to the video memory, so you can't just write data to the name table as if you were writing to RAM. In order to wire to the video memory (VRAM, where the name tables are), you have to make use of a couple of PPU communication ports, located at addresses $2006 and $2007. $2006 is the PPU address register, so if you want to access VRAM address $2000 (the top left corner of the first name table), you have to write $20 and then $00 to $2006, to let the PPU know which address you want to access. The reason you need to write to $2006 twice is that addresses are 16 bits wide, but the 6502 is an 8-bit CPU that can only transfer 8 bits at a time.

Then you use port $2007 for the actual transfer. Write to $2007 everything that you want to send to VRAM, and the PPU will take care of writing the data at the address you specified, automatically incrementing the address after each write so you can write large chunks of sequential data without having to set the target address all the time.

As nesrocks mentioned, you can only access VRAM when the PPU is not rendering pictures, otherwise the VRAM gets corrupted and you end up with a glitched screen. The safest way to guarantee that the PPU is not rendering is to completely disable sprite and background rendering via register $2001. Once you're finished writing all the data for your background, you can enable rendering again.

xX_pokeman2003_Xx
Posts: 2
Joined: Sun Sep 13, 2020 9:51 pm

Re: Question on background tiles(and how to put them into the PPU)

Post by xX_pokeman2003_Xx » Mon Sep 14, 2020 1:52 pm

While this is informative, I guess the conclusion is that I don't understand the nametable and what specifically would you do to it. Do you load tiles into a table and then tell the name table "this tile goes at address $2000", or do you literally define the tile in the name table? Where do I store the background tile if it's the former, in the pattern table?

User avatar
Controllerhead
Posts: 148
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Question on background tiles(and how to put them into the PPU)

Post by Controllerhead » Mon Sep 14, 2020 3:03 pm

xX_pokeman2003_Xx wrote:
Mon Sep 14, 2020 1:52 pm
While this is informative, I guess the conclusion is that I don't understand the nametable and what specifically would you do to it. Do you load tiles into a table and then tell the name table "this tile goes at address $2000", or do you literally define the tile in the name table? Where do I store the background tile if it's the former, in the pattern table?
The pattern table is filled with CHR tile information. Every byte in the nametable points to a tile in the pattern table. The location is hard wired. The attribute table points to a position in palette RAM for color information about that tile. The locations are also hard wired.

Here is a picture of Mesen with nametable and attribute info. Is this clear for you?

Image
Image

User avatar
dougeff
Posts: 2735
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: Question on background tiles(and how to put them into the PPU)

Post by dougeff » Mon Sep 14, 2020 3:59 pm

Tiles are 8x8 pixels. The screen is 256x240 pixels. That means 32 tiles wide and 30 tiles tall.

A formula to calculate a PPU address, in tiles position is...

$2000 + (tile Y * 32) + tile X

where tile X is 0 to 31, and tile Y is 0 to 29.

You take that PPU address, send it High byte, then Low byte to $2006 register, Then send tile numbers 0 to 255 to $2007 register.

Note that PPU addresses are entirely different from CPU addresses. The CPU can't access the PPU except by the registers at $2006 and $2007.

...note, $2000 above is for Nametable A, of an arrangement like...
A B
C D
B would be $2400, C would be $2800, D would be $2c00.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
tokumaru
Posts: 11858
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Question on background tiles(and how to put them into the PPU)

Post by tokumaru » Mon Sep 14, 2020 4:42 pm

Each name table is just a 32x30 grid of references to tiles, whose actual graphics are stored in the pattern table. Every frame, the PPU scans the name table, checking each one of the referenced tiles and drawing them.

You literally just need to send to the PPU (via register $2007) the indices of the tiles you want to display, in the form of 30 rows of 32 bytes (that's 960 bytes in total). Set the target VRAM address first (via register $2006), then write 960 bytes to register $2007, and you'll have filled an entire name table.

Post Reply