don't understand Nametables.

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

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

don't understand Nametables.

Post by DementedPurple »

So I've been reading Nerdy Nights and they have an example where they teach you how to use nametables. here is the code:

Code: Select all

LoadBackground:
  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address
  LDX #$00              ; start out at 0
LoadBackgroundLoop:
  LDA background, x     ; load data from address (background + the value in x)
  STA $2007             ; write to PPU
  INX                   ; X = X + 1
  CPX #$80              ; Compare X to hex $80, decimal 128 - copying 128 bytes
  BNE LoadBackgroundLoop  ; Branch to LoadBackgroundLoop if compare was Not Equal to zero
What I don't understand about it is that all it says is LDA background,X. What address is background? Is it a variable because of sprite DMA? That would make sense if each individual X and Y position had its own memory address. And also, what is a High/Low latch?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: don't understand Nametables.

Post by tokumaru »

DementedPurple wrote:What I don't understand about it is that all it says is LDA background,X. What address is background?
It's a table in ROM where the data is copied from. You have to create this table yourself, it's just a sequence of tile indices:

Code: Select all

background:
	.db $00, $02, $01, $10, $12, ...
The LDA $XXXX, X addressing mode can only access tables up to 256 bytes large though, so if you need to write more than that to a name table (a complete name table is 960 bytes) you will need to use pointers (LDA ($XX), Y, where the ZP position $XX contains the address of the table, and should be adjusted a few times during the transfer so that more than 256 bytes can be accessed).
Is it a variable because of sprite DMA?
What? No sprites have nothing to do with the name tables.
That would make sense if each individual X and Y position had its own memory address.
Each tile DOES have its own address, but even though the screen is 2D, memory is 1D. To find the address of a tile at position (X, Y) you need to use a little formula: address = Y * 32 + X. You can also think of the address in binary as having the following format: 0010NNYY YYYXXXXXX.
And also, what is a High/Low latch?
To set the VRAM address, you write both the low and high bytes of the address to register $2006. This latch exists so the PPU knows whether you're writing the low or the high byte, otherwise it wouldn't be able to tell them apart. Reading $2002 resets the latch, letting the PPU know that the next $2006 write will contain the high byte of the VRAM address.
User avatar
dustmop
Posts: 136
Joined: Wed Oct 16, 2013 7:55 am

Re: don't understand Nametables.

Post by dustmop »

Two separate things going on here:

1) Data table with indexed addressing.

In this sample code, `background` is the name of a table in memory. It's not a `variable`, because it's an address of ROM, which is not modifiable. Instead, this location in memory has a bunch of read-only data, and an amount of bytes equal to $80 is being read from that location and loaded into the PPU.

Let's say, for example, that `background` is pointing at the address $9123. Then the instruction:
LDA background,x
Will get the address at $9123+x and put it into the accumulator. The first time through the loop, X = 0, due to the LDX instead before the loop.

So:
LDA background,x
when X=0, loads A with the value in ROM at $9123

The next time through the loop, when X = 1,
LDA background,x
loads A with the value in ROM at $9124

and so on until X = $80.

This has nothing at all to do with sprite DMA, that's completely unrelated.

2) The high / low latch

The NES is an 8-bit machine, but its uses address spaces that are 16-bits, from $0000 to $ffff. In particular, the PPU has a 16-bit address space. This means that to create a pointer to the PPU's memory, addresses have to be created one byte at a time. When a byte is written to CPU's address $2006, this sets half of the PPU memory pointer. Which half it sets is based upon an internal flop called a "latch". When PPU_STATUS ($2002) is read, it resets the latch to "high", meaning the next write to $2006 will be the high byte of the ppu address, and this write will also flop the latch. The following write to $2006 will then be the low byte of the ppu address.

Stepping through this code a single instruction at a time:

Code: Select all

  LDA $2002  -  latch=0, ppu_pointer=????
  LDA  #$20  -  latch=0, ppu_pointer=????
  STA $2006  -  latch=1, ppu_pointer=20??
  LDA  #$00  -  latch=1, ppu_pointer=20??
  STA $2006  -  latch=0, ppu_pointer=2000
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: don't understand Nametables.

Post by DementedPurple »

Then how would we know what part of the ROM the name tables are pointing to?
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: don't understand Nametables.

Post by dougeff »

Then how would we know what part of the ROM the name tables are pointing to?
The nametables don't point to the ROM, or anything else.

The PPU has it's own RAM chip. The nametables are on that separate RAM chip. You have to transfer the data to it. (accessed with 2007 register).
nesdoug.com -- blog/tutorial on programming for the NES
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: don't understand Nametables.

Post by DementedPurple »

Do I tell it where the Nametable ram is with the PPU control registers?
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: don't understand Nametables.

Post by dougeff »

Now that is a good question.

The 2000 register selects a nametable (there are 4 nametables).
---- --00 = nametable 0
---- --01 = nametable 1

The scroll register (2005) tells the PPU where in the nametable to start rendering (ie, it shifts the nametable's position on the screen).

The 2006 shares bits with the 2005 register, so writing to 2006 (without then setting 2005 registers) will also shift the position of the screen. This is probably confusing...but it is common to rewrite the scroll registers every frame, even if they haven't changed, to make sure writes to the PPU don't screw up the scroll bits and misalign the screen.
nesdoug.com -- blog/tutorial on programming for the NES
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: don't understand Nametables.

Post by DementedPurple »

So how would I actually plot sprites?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: don't understand Nametables.

Post by tokumaru »

Sprites have nothing to do with name tables. Name tables are used to draw backgrounds.

To draw sprites you have to fill a page of RAM worth of sprite attributes and then, during vblank, transfer that to the PPU using a sprite DMA.

To draw backgrounds you have to make sure that rendering is off (either by forcing it off or waiting for vblank) and copy the name table data to VRAM using registers $2006 (address) and $2007 (data). If your game uses a static background, normally you just have to copy 1024 bytes (960 tile indices + 64 attribute bytes) from ROM to VRAM with rendering disabled. But if you have scrolling levels, dynamic backgrounds, etc., then you need a more complex system to buffer the incremental changes to RAM and copy those to VRAM during vblank, respecting the limits of how much data can be transferred during the short vblank time.
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: don't understand Nametables.

Post by DementedPurple »

So you pretty much would just write tile numbers to the PPU?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: don't understand Nametables.

Post by tepples »

To update nametables, you write bits 13-8 of the destination address to $2006, bits 7-0 of the destination address to $2006, and one or more tile numbers to $2007. Every time you write to $2007, the destination address increases by 1, causing tile numbers to be written from left to right. There's a setting in $2000 to make it increase by 32 instead, causing tile numbers to be written from top to bottom.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: don't understand Nametables.

Post by tokumaru »

For backgrounds, yes. You also have attributes to worry about, they select which palette is used for each 16x16-pixel area of the screen, but you don't need to worry about creating this data manually if you use a program like NES Screen Tool. You can design your screens in it and export the data to be included in your ROM.
DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: don't understand Nametables.

Post by DementedPurple »

Could you maybe explain it in simpler terms?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: don't understand Nametables.

Post by tepples »

The following is long because "simpler terms" to express the same idea are often longer.

Coordinate pair (12, 10) means x=12 y=10, or 12 cells from the left and 10 cells from the top.

The video memory address of a nametable cell is the nametable's base address plus 32 times the Y coordinate plus the X coordinate.
For example, the video memory address of (12, 10) on the first nametable, whose base address is $2000, is
$2000 + 32 * Y + X
= $2000 + 32 * 10 + 12
= $2000 + 332
= $2000 + $14C
= $214C

To seek to $214C in video memory, write $21 to $2006 and then write $4C to $2006. Then write tile numbers to $2007. The first tile number you write to $2007 will then go to $214C, which corresponds to cell (12, 10).

If you continue to write tile numbers to $2007, where they go depends on the video memory increment, which can be +1 or +32. This depends on bit 2 of the last value written to $2000.

If bit 2 of $2000 is clear (0), the video memory increment is set to +1. This means successive tile numbers written to $2000 will appear to the right. To set the video memory increment to +1, write $80 to $2000. This means vblank NMI enabled (because bit 7 is set to 1) and video memory increment +1 (because bit 2 is clear to 0).

If the video memory increment is set to +1, and you seek to $214C and write three tile numbers, these tile numbers will be written to $214C, $214D, and $214E, which correspond to cell (12, 10) and the two cells to its right.

If bit 2 of $2000 is set (1), the video memory increment is set to +32. This means successive tile numbers written to $2000 will appear downward. To set the video memory increment to +32, write $84 to $2000. This means vblank NMI enabled (because bit 7 is set to 1) and video memory increment +32 (because bit 2 is set to 1).

If the video memory increment is set to +32, and you seek to $214C and write three tile numbers, these tile numbers will be written to $214C, $216C, and $218C, which correspond to cell (12, 10) and the two cells below it.
User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: don't understand Nametables.

Post by dougeff »

PPU addresses $2000-23ff represent nametable #0.

The last 64 bytes ($23c0-23ff) is called attribute table, and it's complicated, but it tells which parts of the screen (bg) should use which bg palette.

Just fill it with zero for now, and the whole screen will use the first palette (bg palette #0 = $3f00-3f03).
nesdoug.com -- blog/tutorial on programming for the NES
Post Reply