--------- the current information on background scrolling is sufficient for most games; however, there are a few that require a more complete understanding. here are the related registers: (v) vram address, a.k.a. 2006 which we all know and love. (16 bits) (t) another temp vram address (16 bits) (you can really call them 15 bits, the last isn't used) (x) tile X offset (3 bits) the ppu uses the vram address for both reading/writing to vram thru 2007, and for fetching nametable data to draw the background. as it's drawing the background, it updates the address to point to the nametable data currently being drawn. bits 0-11 hold the nametable address (-$2000). bits 12-14 are the tile Y offset. --------- stuff that affects register contents: ('d' is the byte being written to a particular address) 2000 write: t:xxxxABxxxxxxxxxx=d:xxxxxxAB 2005 first write: t:xxxxxxxxxxxABCDE=d:ABCDExxx x=d:xxxxxABC 2005 second write: t:xxxxxxABCDExxxxx=d:ABCDExxx t:xABCxxxxxxxxxxxx=d:xxxxxABC 2006 first write: t:xxABCDEFxxxxxxxx=d:xxABCDEF t:ABxxxxxxxxxxxxxx=0 (bits 14,15 cleared) 2006 second write: t:xxxxxxxxABCDEFGH=d:ABCDEFGH v=t scanline start (if background or sprites are enabled): v:xxxxxAxxxxxBCDEF=t:xxxxxAxxxxxBCDEF frame start (line 0) (if background or sprites are enabled): v=t note! 2005 and 2006 share the toggle that selects between first/second writes. reading 2002 will clear it. note! all of this info agrees with the tests i've run on a real nes. BUT if there's something you don't agree with, please let me know so i can verify it. ------------ (more notes on ppu logic) you can think of bits 0,1,2,3,4 of the vram address as the "x scroll"(*8) that the ppu increments as it draws. as it wraps from 31 to 0, bit 10 is switched. you should see how this causes horizontal wrapping between name tables (0,1) and (2,3). you can think of bits 5,6,7,8,9 as the "y scroll"(*8). this functions slightly different from the X. it wraps to 0 and bit 11 is switched when it's incremented from _29_ instead of 31. there are some odd side effects from this.. if you manually set the value above 29 (from either 2005 or 2006), the wrapping from 29 obviously won't happen, and attrib data will be used as name table data. the "y scroll" still wraps to 0 from 31, but without switching bit 11. this explains why writing 240+ to 'Y' in 2005 appeared as a negative scroll value.