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

PPU rendering question

PPU rendering question
by on (#105292)
When trying to understand how exactly the PPU works while reading things like http://wiki.nesdev.com/w/index.php/PPU_rendering, I've come across something which I don't quite understand

The rendering is described with the following:

Quote:
2 16-bit shift registers - These contain the bitmap data for two tiles. Every 8 cycles, the bitmap data for the next tile is loaded into the upper 8 bits of this shift register. Meanwhile, the pixel to render is fetched from one of the lower 8 bits.


And also:

Quote:
Every cycle, a bit is fetched from the 4 background shift registers in order to create a pixel on screen. Exactly which bit is fetched depends on the fine X scroll, set by $2005 (this is how fine X scrolling is possible). Afterwards, the shift registers are shifted once, to the data for the next pixel.


OK, at first glance I get the idea. A bit is selected from the bottom half of the shift registers depending on the fine scroll offset. The whole shift register is shifted afterwards to "move to the next pixel". But there's a catch which doesn't at face value make sense to me.

The bits in the pattern buffer as far as I have always understood represent pixels from "left to right" that is, bit 7 = pixel 0, bit 6 = pixel 1, etc.

So, let's suppose the shift register contains the following bits: (I'll use ':' to separate high/low for clarity).

Code:
ABCDEFGH:IJKLMNOP


When rendering, since we use the lower half (IJKLMNOP) to represent the current tile and the upper half (ABCDEFGH) for the next tile. The first pixel to be rendered if fine x scroll is 0 would be based on bit "I". OK, fair enough, but when we "shift right" we result in this:

Code:
.ABCDEFG:HIJKLMNO


Well this is no good, instead of rendering the correct pixel, we are getting some data from the next tile AND we've lost the bit for the last pixel of this tile!

So there's two solutions I can think of both of which would be equally effective as far as I can tell:

a) The bit patterns are reversed when loaded, so even though memory holds "ABCDEFGH" and "IJKLMNOP" for the two tiles, what gets loaded is:

Code:
HGFEDCBA:PONMLKJI


This would allow the rendering pipeline to select pixel 0 from the right most bit, then shift right and everything is all well and good.

b) the registers actually load into the low half and shift left. Similar effect, but simpler to write equivalent code. We'd end up with:

Code:
IJKLMNOP:ABCDEFGH


then when rendering, we select bit 'I' for the current tile, and shifting left gives us:

Code:
JKLMNOPA:BCDEFGH.


Which all works out well.

Are either of these the case? Or am I missing something obvious?

Thanks!
proxy
Re: PPU rendering question
by on (#105297)
Haha, sorry about how confusing that diagram is. :P Both your A and B options are correct; when I was drawing that diagram, I accidentally drew the shift registers backwards, but then I figured it works out when you horizontally flip the graphics data before it goes into the shift register (and in hardware, this is extremely trivial to do; you just connect the pins in the reverse order).
Re: PPU rendering question
by on (#105298)
I went ahead and fixed the diagram. While I was at it, I broke each shift register into two, corresponding to the PISO and SIPO that would be used in a 7400 or 4000 series implementation.
Re: PPU rendering question
by on (#105304)
Cool, that's what i figured, just wanted to make sure I wasn't missing anything obvious :-)

Thanks