Writing bits 12-14 in VRAM address via $2006
Moderator: Moderators
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Writing bits 12-14 in VRAM address via $2006
I am attempting to play around with writing the VRAM address and tile offsets using $2006. From documentation, it looks like bits 12-14 in the VRAM address are the tile y offset. That means the first time we write to $2006, the upper nibble of the byte is essentially the tile y offset, correct? (with the 15th bit ignored) When I try this out and check out the scrolling with FCEUXD, I am able to increment the tile y offset from 0 to 3, but when I set it to 4, it appears to wrap to 0, as though the 14th bit is being ignored when I write.
This is because the first write to $2006 only uses bits 0-5 (high 2 bits are forced to zero). This makes fully specifying the fine Y scroll impossible with $2006 alone.
To do this (assuming you can't just use $2005 -- like if you want to change V scroll mid frame or something), you need to alternate $2006 and $2005 writes. Do the writes in the following order:
$2006 - write NT scroll (NT scroll in bits 2,3)
$2005 - fine Y scroll
$2005 - fine X scroll
$2006 - write low byte of PPU address (coarse X scroll + 3 bits of coarse Y scroll)
To do this (assuming you can't just use $2005 -- like if you want to change V scroll mid frame or something), you need to alternate $2006 and $2005 writes. Do the writes in the following order:
$2006 - write NT scroll (NT scroll in bits 2,3)
$2005 - fine Y scroll
$2005 - fine X scroll
$2006 - write low byte of PPU address (coarse X scroll + 3 bits of coarse Y scroll)
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Will writing in this order have the same effect?
;$2006 - write NT scroll (NT scroll in bits 2,3)
;$2006 - write low byte of PPU address (coarse X scroll + 3 bits of coarse Y scroll)
;$2005 - fine X scroll
;$2005 - fine Y scroll
We switch the writes to $2005 since $2006 and $2005 share the toggle for high/low byte.
;$2006 - write NT scroll (NT scroll in bits 2,3)
;$2006 - write low byte of PPU address (coarse X scroll + 3 bits of coarse Y scroll)
;$2005 - fine X scroll
;$2005 - fine Y scroll
We switch the writes to $2005 since $2006 and $2005 share the toggle for high/low byte.
The thing is that these writes only affect the temporary PPU address (loopy_t) and not the real PPU address (loopy_v). The only way the real PPU address can be changed is automatically by the PPU at frame start (provided rendering is enabled) -- or on the second $2006 write. $2005 writes never update the real address.
This is why the second $2006 write must be the last in the series. Doing it your way would work for setting the temp address, but the $2005 writes would have no effect on the real PPU address.
And if you're using $2005 this way, you might as well just ditch $2006 completely and use the NT scroll bits from $2000 instead.
This is why the second $2006 write must be the last in the series. Doing it your way would work for setting the temp address, but the $2005 writes would have no effect on the real PPU address.
And if you're using $2005 this way, you might as well just ditch $2006 completely and use the NT scroll bits from $2000 instead.
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
- GradualGames
- Posts: 1106
- Joined: Sun Nov 09, 2008 9:18 pm
- Location: Pennsylvania, USA
- Contact:
Not really, because if you're doing this in VBlank, there's no reason to use $2006 at all. You can use the low 2 bits of $2000 to set the NT scroll, and use $2005 to set the remaining scroll bits normally. $2000+$2005 do it all... the only thing they don't do is explicitly change loopy_v.
The only time you need to use $2006 to change the scroll is if you're changing the Y scroll mid-frame (like for a status bar or something -- or if you're turning rendering on late and miss the PPU's automatic v=t)
The only time you need to use $2006 to change the scroll is if you're changing the Y scroll mid-frame (like for a status bar or something -- or if you're turning rendering on late and miss the PPU's automatic v=t)
This is probably the best "summarised" explanation (for programmers) I've ever seen. For years I've wondered why games I'd disassembled wrote to $2005/2006 in the order they did, figuring it wasn't important...
Maybe I'll have to go back and fix my FF2e intro for Demiforce.
Thanks a ton, Disch. You have no idea how much I appreciate what you've posted. :-)
Maybe I'll have to go back and fix my FF2e intro for Demiforce.
Thanks a ton, Disch. You have no idea how much I appreciate what you've posted. :-)
I guess this serves as one more evidence that loopy's doc just isn't clear enough. A few years back I came here for explanations because I simply couldn't understand his document. I finally did though, with a little help.koitsu wrote:This is probably the best "summarised" explanation (for programmers) I've ever seen. For years I've wondered why games I'd disassembled wrote to $2005/2006 in the order they did, figuring it wasn't important...
If someone decides to present that information in a more friendly way (with a wiki entry maybe, instead of just a link to the original doc), they should also make clear that tricky $2005/$2006 writes are only necessary for messing with the scroll *after* the start of the frame. Many people seem to think that using $2006 for scrolling is required, while $2000 and $2005 were designed for manipulating the scroll under normal circunstances (during VBlank).
-
Celius
- Posts: 2159
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
I think that's kind of an understatement. It's not really as unclear as much as it's like a riddle or something. Basically the document gives you obscure clues or hints rather than answers.tokumaru wrote: I guess this serves as one more evidence that loopy's doc just isn't clear enough.
I still have to go through this thread to fully understand the relationship between $2005/$2006 for changing the scroll mid frame. But I can already tell just by skimming through it that it's a nicely condensed explanation of this.
I cleaned up a summary of $2000/$2005/$2006 behavior I wrote for myself.
Last edited by blargg on Sun Mar 01, 2009 4:15 am, edited 1 time in total.
Well I always had trouble understanding loopy's docs and also wrote some kind of summary, tough it's really on the practical side and not on the theorical side (it does covers all regs, but a long paragraph is about $2005, $2006 and $2000 updates).
You can get a html version and a txt version.
You can get a html version and a txt version.
Useless, lumbering half-wits don't scare us.