This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

PPU address, temp address, updates etc..

PPU address, temp address, updates etc..
by on (#27277)
I put this in a separate thread rather than hijack the other onewith my questions.

Disch wrote:
albailey wrote:
I wish I knew where the PPU addr pointed to after a write to $2000 (I assume its the start of that particular nametable)

$2000 does not [directly] change the address at all -- it would still point tot he same place it did before the write.

$2000 does, however, change the nametable bits in the temporary address (which gets copied to the actual PPU address at frame start).

$2000 sets only bits 10 and 11... other bits in the temp address remain unchanged. Therefore if the temp address is $2416 and you write 0 to $2000, the new temp address will be $2016

OK, so the writes to $2005 mentioned by Tokumaru are required.

Based on loopy's scrolling/skinny document:

$2000 updated bits 10 & 11
first write to $2005 clears bits 0,1,2,3,4
second write to $2005 clears bits 5,6,7,8,9 and also updates 12,13,14 (what happens o those?)
and at frame start the temp address becomes the PPU address.

Edit- I guess my question is, what value ends up in bits 12-14 when you write #$00 to $2005 (twice)


by on (#27278)
Old but relevent thread:

bits 12-14 contain the fine Y scroll after dual $2005 writes (low 3 bits of the second value writte). In the case of dual writes of 0, those bits would be 0.

by on (#27280)
Hi, Al. Here's the idea behind it all:

There's a register that points to vram, and this is used for 2 purposes. We, programmers, use it to point to bytes in vram when we want to read/write data from/to vram, while the NES uses it during rendering to fetch data from vram in order to render the screen.

Since the register is used for these 2 purposes, obviously the 2 can't happen at the same time, and this is why we can only write/read to/from the PPU when the PPU is not rendering. Anyway, so that scrolling the screen is possible, we are able to modify this register before rendering starts so that rendering can start at any point in tha name tables.

Nintendo provided programmers with a set of registers to set up what this starting point should be. They included a temporary vram address register, that's written to through the lower 2 bits of $2000 and writes to $2005. With those, you can fully point to any pixel in tha neme tables: The lower bits of $2000 indicate inside which name table is the first pixel to render, while the 8-bit values written to $2005 indicate the exact pixel coordinates within the specified name table.

So, it's clear that Nintendo provided 2 ways of accessing the vram address register: one is through $2006, that should be used when one wants to read or write bytes to vram, and the other is though $2000 and $2005, that should be used to point to a specific pixel that should be the first one rendered.

The catch is, writing to $2000 and to $2005 only changes the temporary vram address, so you can only use that method to indicate the pixel where rendering should start from if you do it before VBlank ends, at which time the temporary register is copied into the actual one.

However, that doesn't mean it's impossible to point to any pixel in case one needs to enable rendering after the frame has already started. As loopy documented, with a specific combination of $2000, $2005 and $2006 writes you can still point to any pixel within the name tables.

The problem is that many people fix scrolling problems (usually in demos that only use the first name table) by writing two 0's to $2006. But $2006 was not created for setting the scroll, it was created to make manipulating vram bytes possible. It can be used, when necessary, in conjuction with other addresses ($2000 and $2005) to set up scrolling. The writes to $2006 alone do not reliably set the scroll. For one thing, just notice that writes to $2006 do nothing to what's known as the "fine X scroll".

I guess I can sum up this with the following:
  1. Nintendo created $2000 and $2005 to properly set up the scroll while still in Vblank.
  2. They created $2006 so that programmers could manipulate bytes in vram.
  3. If you need to set up the scroll while not in Vblank, you can use $2006, but not just it. You need the full set of $2000/$2005/$2006 writes to properly point the PPU to an exact pixel.

by on (#27283)
Use only $2006 will work as long as the fine H scroll has been set up at least one time. $2006 can not change the fine H scroll, and reset the fine V scroll, but the main scrolling is fully acessible. It's just not the standard way to acess it, but it can be used as well as $2005 if the programmer knowns what he does.
Now that I think about it games that scrolls only full tiles might as well set up $2005 once at start to $00, $00 and then write the tile adress to $2006 instead of doing it the standard way near the end of the frame, this *could* be more pratical for math reasons behind the programm (however I'm not sure it is).

by on (#27314)
That clears things up a lot for me. And it really helps me better understand loopy's document. When I read (and re-read) it before, I had no clue what that temp address was all about.

I'll admit, I've been using direct writes to $2006 to reset PPU because I thought it was the preferred way, so now I know better.

Thanks guys.