Clarification on 2C02 technical reference

Clarification on 2C02 technical reference
by on (#48176)
In the document '2C02 technical reference.TXT' (and various others that state the same information) there seems to be a bit of confusion.

First, it states that PPU cycles 1 - 256 are for fetching background data, in the order:

NameTable
Attribute
Pattern Lo
Pattern Hi

which consumes 8 PPU cycles. It then states "this is repeated 32 times". The first set of fetches is for the third tile. It then states that later PPU cycles are used to fetch the first two tiles of the NEXT scanline.

Doesn't this mean that the first two tiles of the NEXT scanline are fetched twice? Once as the 31st and 32nd fetches in cycles 1-256, and then again after the sprite fetches.

Image
I managed to get full_nes_palette.nes and full_nes_palette2.nes working, which seems to require pretty close to accurate PPU timing. But in the process I have broken a few other test ROMs in my emulator that used to work when I had crappy scanline-based emulation. Now that my CPU marches along with the pixels I have an invested interest in making it as accurate as possible.

So I started looking closer at the documentation and got confused...again.

by on (#48178)
0 - 255 = 8 cycles * 32 tiles

256 - 320 = 8 cycles * 8 tiles, max of 8 sprites / line

321 - 336 = 8 cycles * 2 tiles ( pre fetch for the next line)

337 - 341 = idle / garbage

The first 2 tiles in the buffer/latch is fetched right after the sprites on the previous line. The is a ~2 tile delay from when its shown. Depending on the scrolling, the first or last tile ( 2 + 32 = 34) will not be shown.

matt

by on (#48181)
mattmatteh is correct. To elaborate further:

consider that it takes 8 cycles to fetch all the information required to render a tile.

Then consider that the 2nd tile of the scanline can be rendered as soon as the 2nd cycle of the scanline (if fineX=7). The PPU obviously can't fetch the first two tiles on the same scanline they're rendered, because they would both need to be rendered before either one of them could've been fetched. Therefore it reads them on the previous scanline.

What ends up happening is that the PPU has fetched 2 tiles ahead of time, so it always has enough fetched:

Code:
320:  fetch 1st tile for NEXT scanline
328:  fetch 2nd tile for NEXT scanline
  0:  fetch 3rd tile for this scanline (render 1st tile)
  8:  fetch 4th tile for this scanline (render 2nd tile)
 16:  fetch 5th tile for this scanline (render 3rd tile)
... etc


At least 1 pixel from the first tile is always rendered.
At most 7 pixels from the 33rd (second last) tile is rendered
the 34th tile is never rendered (but it is still fetched -- this is important for MMC2/MMC4)