Slightly confused about filling nametables..

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Slightly confused about filling nametables..
by on (#223777)
Hey fellow nesdevers.

I'm a little confused about the filling of the nametables.
I was following Roth's nerdy nights tutorial where he shows how to load a background like this:
Edit: It's Bunnyboy's nerdy nights tutorial.

Code:
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
                        ; if compare was equal to 128, keep going down
.nametable:
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;row 1
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;all sky ($24 = sky)
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;row 2
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24  ;;all sky
  .db $24,$24,$24,$24,$45,$45,$24,$24,$45,$45,$45,$45,$45,$45,$24,$24  ;;row 3
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$53,$54,$24,$24  ;;some brick tops
  .db $24,$24,$24,$24,$47,$47,$24,$24,$47,$47,$47,$47,$47,$47,$24,$24  ;;row 4
  .db $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$55,$56,$24,$24  ;;brick bottoms


And I was thinking "That's allot of Duplicate $24's. Why don't I write those in a loop to $2007.
I Tried it and It worked. :)

But then I thought the following: "What if I hardly want anything on the background layer and it would mostly be filled with $00's?"
So I tried the following:

Code:
  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$21
  STA $2006             ; write the high byte of $21AF address (The location of where I want the background image to be)
  LDA #$AF
  STA $2006
  STA $2007

  /* Then use the same background loading loop as in the first example to fill till I got the desired about of tiles I want. */



This works but it "Moves" the entire nametable up until when I load the first tile.
I have to do this:

Code:
  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$20
  STA $2006
  LDA #$00
  STA $2006
  STA $2007



After the loop has ended to make it appear in the right spot.
I should be happy that it works and I am but I'm just curious to why this is?
Re: Slightly confused about filling nametables..
by on (#223780)
I'm pretty sure bunnyboy wrote the Nerdy Nights, and Roth only listed them all into 1 convenient post.

The PPU address shares bits with the scroll register (internally).

Writing to 2006 affects the scroll.

You should set the scroll after writing to the PPU.

You can do this with 1 write to 2000, and 2 writes to 2005.

Or, you can do this with 2 writes to 2006, and 2 writes to 2005.

Just writing to 2006 can't properly set the fine x,fine y bits.
Re: Slightly confused about filling nametables..
by on (#223781)
It's probably the scroll. The PPU has an address register that it uses to access VRAM, and this register is used for ALL VRAM accesses, be it when you're filling name tables or when the PPU itself is reading them to render images. When you write to VRAM and leave the PPU address at whatever position it was when you finished writing, the PPU will try to use that as the scroll origin.

No matter what kind of VRAM manipulation you do, you ALWAYS have to reset the scroll to the position where you want rendering to start from. The correct way to set the scroll is during vblank, via $2000 (name table selection) and $2005 (X and Y scroll).
Re: Slightly confused about filling nametables..
by on (#223784)
dougeff wrote:
I'm pretty sure bunnyboy wrote the Nerdy Nights, and Roth only listed them all into 1 convenient post.

The PPU address shares bits with the scroll register (internally).

Writing to 2006 affects the scroll.

You should set the scroll after writing to the PPU.

You can do this with 1 write to 2000, and 2 writes to 2005.

Or, you can do this with 2 writes to 2006, and 2 writes to 2005.

Just writing to 2006 can't properly set the fine x,fine y bits.


You're right it was bunnyboy. :oops:
Re: Slightly confused about filling nametables..
by on (#223798)
I had no idea it affected the scroll.

Thanks for the help guys! :) :beer:



Just to give fellow noobs that might be reading this a quick answer, this is how to set the scroll to 0,0 :
Code:
  LDA #$00
  STA $2005
  STA $2005
Re: Slightly confused about filling nametables..
by on (#223803)
The long explanation for why this happens/why this is, is here: https://wiki.nesdev.com/w/index.php/PPU_scrolling -- and https://wiki.nesdev.com/w/index.php/Errata also has some summarised bits.

Nobody except the experienced really "expects" it to affect the scroll, but it does given how the console is designed. $2005, $2006, $2002, and $2000 are all "intertwined" in a way that isn't immediately obvious. I still consider it one of the biggest "catches" or "gotchas" of the console, from a developer standpoint. In short: you're not alone. :-)
Re: Slightly confused about filling nametables..
by on (#223825)
Remember to use your favourite emulator™s debug features to test your code. :)

For example FCEUX's nametable viewer would immediately make obvious what your nametable looks like, and what the scroll value is doing.
But kudos for going outside of the tutorial and trying some stuff on your own. I find that it is the best way to learn from tutorials, and avoid somehow missing the essential parts of what you are trying to learn. Every tutorial should have a "now you try:" section for every chapter :P