Background rendering

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Background rendering

Post by Muhammad_R4 »

Hello :)

I have now a question about background rendering

I know that the background rendering starts 2 tiles ahead before the real output of the tile

according to the this http://wiki.nesdev.com/w/images/d/d1/Ntsc_timing.png

we fetch the first two tiles of scanline (S) in clks from 321 -> 336 of scanline (S-1)

according to this project , the address of the name table byte is as follows ( assuming we are dealing with name table at 0x2C00 )

& = concatenation
"1011" & y_scroll[7:3] & x_scroll[7:3]

where x_scroll and y_scroll are counters for horizontal and vertical pixels

the problem I see with this is that the first 2 tiles are not fetched right

as example , if we are on scanline y=0x02 thefore the address if name table byte( at clk = 321) will be equal
0x2C08(the ninth tile) not 0x2C00( the first tile )
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Background rendering

Post by Dwedit »

"1011" isn't necessarily right, the first 10 is fine since it indicates that it wants the nametables rather than the pattern tables, but the "11" afterwards is actually two nametable selection bits, which are part of V. It could be 00, 01, 10, 11, etc.
Aside from that, check that the coarse X is incremented correctly.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

check that the coarse X is incremented correctly.
So how it is incremented correctly ?
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Background rendering

Post by Dwedit »

Some quick stuff:
VRAM address format: yyyNNYYYYYXXXXX (yyy = fine y, NN = nametable, YYYYY = coarse Y, XXXXX = coarse x)

For nametable tile fetches, we use this:
010NNYYYYYXXXXX
010 = Nametable memory rather than pattern tables, NN = nametable selection, YYYYY = coarse Y, XXXXX = coarse X

If we are scrolled to 0,0 on upper-left name table, we use NN = 0, YYYYY = 0, XXXXX = 0, we get this address:
010000000000000
Then for the next tile horizontally, treat NXXXXX as a single 6-bit value (using the lower bit of NN), increment that.

Attribute byte fetch:
010NN1111YYYXXX, using upper 3 bits of XXXXX and YYYYY. The second-lowest bit of YYYYY and XXXXX are used to select which 2-bits to use from the attribute byte value.
The same attribute fetch is made twice.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

it seems I have a problem with counters arrangement

till now , I think that counters are chained as follows

MSB-------------------LSB

YYYYY yyy XXXXX xxx

YYYYY -> 5 bits indicating tile no. (vertically)
yyy -> fine ver
xxx -> fine hor
XXXXX-> 5 bits indicating tile no. (horizontally)

that's also how I think rendering goes , line by line

is this wrong ?
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Background rendering

Post by Dwedit »

A game will write to $2006 twice, and get this:
first write: _0yyNNYY
2nd write: YYYXXXXX
(due to a quirk about how register $2006 works, the top bit of fine y can't be written that way, but it can still be changed with a combination of $2005/$2006 writes)

If you use the ordering from what $2006 writes look like, you get this:
_yyyNNYYYYYXXXXX
When rendering is disabled, that 15-bit value is used as the PPU address for reads and writes.
The actual arrangement of the bits inside could be anything. I haven't looked at the silicon and don't intend to. But numbers like YYYYYyyy and XXXXXxxx aren't used anywhere during rendering.
Since yyyNNYYYYYXXXXX corresponds to the 15-bit value used as the PPU address, people often assume that the counter inside looks like that.
And fine x (xxx) is nowhere to be seen in the VRAM address value, it's treated as being separate. First write to $2005 will set those bits.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

If we are scrolled to 0,0 on upper-left name table, we use NN = 0, YYYYY = 0, XXXXX = 0, we get this address:
010000000000000
I have a problem with this example

although this is the address of the first tile in the name table , it should be fetched at clks 321 , 322

at those clks , if we tried to extract the fine x , coarse x and formed the address from it using the format , we will find that

321 = 0b 101000000------> xcoarse = 01000 ( assuming ycoarse = 00000
if we formed the address : 010 0000 0000 1000 = 0x2008 which points to the ninth tile not the first which I want to fetch

I have a way to bypass this ( subtracting 8 during fetch in scanline S-1 clks 321 -> 336 and adding 2 when fetching the rest in scanline S ) but I think this is not what really happens

tell me if you didn't get me problem to explain it more
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Background rendering

Post by Dwedit »

While there might be some internal counters somewhere for the scanline number and which dot it's rendering, those are separate from the VRAM address used when fetching stuff.

We have two counters, people call them "Loopy T" and "Loopy V", named after a user called Loopy who figured out how they worked.
V corresponds to the address that the PPU uses to fetch tiles, and T is used to make V snap back to the left at the end of a scanline, or snap back to the top at the beginning of the screen.

They are organized in the usual yyyNNYYYYYXXXXX pattern.

At dots 280-304 of the prerender line, vertical parts of T are copied into V. This is yyy, high bit of NN, and YYYYY. This snaps it back to the top of the screen.

At dot 256 of each scanline, vertical part of V is incremented.
Vertical increment:
Treat Y scroll bits of V as an 8-bit value made up of YYYYYyyy. Increment it. If the value changed from 239 to 240, set YYYYYyyy = 0, then toggle the high bit of NN. This makes it advance to the next name table after incrementing from 239 to 240, and resets vertical scroll to 0.
There is also 'negative scrolling' here, if the value of Y was 240 or higher before it was incremented, it does not change any bits of NN, and does not reset to 0. The value of Y can increase from 255 to 0, and it won't flip the high bit of NN. This doesn't usually happen, unless the game intentionally wrote an out-of-range value 240 or higher to Y-scroll. Y-scroll values out of range make it draw attribute tables as tiles, and produce artifacts at the top of the screen.

At dot 257 of each scanline (including prerender line), horizontal parts of T are copied into V. This is XXXXX and low bit of NN. This makes it snap back to the left so it can draw the next scanline.

At dot 321, it starts fetching the first tile of the next scanline.
Horizontal increment:
This happens 34 times per scanline.
7 dots after the first fetch, horizontal parts of V are incremented, like incrementing a 6-bit number made up of NXXXXX. There is nothing weird here, unlike Y scrolling.

this is a good diagram: http://wiki.nesdev.com/w/images/d/d1/Ntsc_timing.png
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

sorry but I didn't get it but I think you want to refer that the vertical counters are different from scanline counters?

and pixel counters (from 0 to 340) differs from the horizontal counter ?
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Background rendering

Post by tepples »

Correct.

While rendering is off, there are three counters:
  • VRAM address, bits 14-0
  • Horizontal pixel position, from 0 to 340
  • Vertical pixel position, from 0 to 261 (or 311 on PAL)
But while rendering is on, the VRAM address's carry paths are reconfigured to behave as four independent counters:
  • Horizontal portion of VRAM address, consisting of bits 10 and 4-0 of the VRAM address
  • Vertical portion of VRAM address, consisting of bits 11, 9-5, and 14-12 of the VRAM address
  • Horizontal pixel position, from 0 to 340
  • Vertical pixel position, from 0 to 261 (or 311 on PAL)
The names v and t come from "The skinny on NES scrolling", on which the wiki article about PPU scrolling registers was based. When I have needed longer names for them, lately I've been using "VRAM address" for v and "top left" for t.
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

I may understand regsiter V but what is the importance of register T ?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Background rendering

Post by rainwarrior »

T is the "scroll" setting.

T is used to automatically reload V at the top of the screen to start drawing the new frame with the desired scroll.

It also partially reloads V at the end of every line, just the horizontal bits, again to keep the desired scroll position.
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

rainwarrior wrote:T is the "scroll" setting.

T is used to automatically reload V at the top of the screen to start drawing the new frame with the desired scroll.

It also partially reloads V at the end of every line, just the horizontal bits, again to keep the desired scroll position.
sorry I didn't get it

what will I lose without it ?

shouldn't the registers when rolled over return to the top left ?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Background rendering

Post by tokumaru »

Muhammad_R4 wrote:shouldn't the registers when rolled over return to the top left ?
The horizontal and vertical parts are reset separately. Every scanline, the horizontal part is reset (copied from T to V) back to the left, but the vertical part simply increments to the next scanline.
Muhammad_R4
Posts: 66
Joined: Sat Jun 25, 2016 5:33 am

Re: Background rendering

Post by Muhammad_R4 »

then how T is edited during the entire frame ?

I only read that V is reloaded from T , but the data in T how it is calculated ?
Post Reply