Sorry, but I tried. And I tried. And then I tried some more. But I couldn't understand it.
I know you have to manipulate the address in $2006 to what you want during rendering, and I know that there are writes that clear and set the specific bits. But I just can't understand the actual logic behind it. I've seen so many different ways people say they use (probably because there isn't ONE way of doing it), wich made me even more confused.
Loopy's document is unreadable for a human, IMO. If it is not much trouble, can anyone that understands how the $2005/$2006 mid-frame writes work explain it to me? What needs to be set, what needs to be clear, the correct order of the writes, in order to set the scrolling values to whatever you want mid-frame...?
Thanks for the help. I understand there is no ONE correct way, I guess it changes depending on what you actually want to do. But if anyone can give a light on this, I'd really appreciate it.
Maybe someone can explain me HOW to read Loopy's document, since you guys seem to menage it somehow. I just don't understand what it all means. The actual manipulation of the addresses can't be more difficult than reading the doc, it just can't.
Treat the 1s and 0s in loopy's scrolling document as bit masks - that is, transfer the "1" bits on the left to the "1" bits on the right, in the same order (and leave the "0" bits alone).
Quietust wrote:
Treat the 1s and 0s in loopy's scrolling document as bit masks - that is, transfer the "1" bits on the left to the "1" bits on the right, in the same order (and leave the "0" bits alone).
Wow... that really changes everything! Why didn't I ever think of that? I'll go read the damn thing again right now! So it basically describes how each write sets/clears bits in the destination...? Or something like this, I can't quite put it into words, but I think I get it now. I'll just read it again and play with it later.
Wich emulators handle this correctly, so I can test it and actually learn something that works on the real hardware?
Nintendulator is like Ivory soap: 99.44 percent accurate.
OK, Nintendulator it is...!
But I still don't get some of the info over there... it shows what bits get tranfered to where, as Quietust said, but didn't bits get cleared too? I read some writes copied bits but also cleared some... So you had to to make a combination of writes to get it all done?
The '1' bits get copied over, and the '0' bits are ignored. The ONLY bits that get cleared are the upper 2 bits during the first write to $2006 (the lower of which is the high order bit for fine vertical scroll).
Wow, this is great! Thanks, loopy! The letters work much nicer than the 1's and 0's, since we can see EXACTLY what goes where.
Well i think I'm really close to understanding this whole thing, now. Exept one thing: "x=d:xxxxxABC" on the 1st write to $2005. I know what "d", "t", and "v" stand for, but what is the "x"?
And, what do all bits mean again? I know the first 5 indexes tiles in the X direction, the next 5 indexes tiles in the Y direction, and the next 2 indexes the nametables. So, that was 12 bits, with wich I think you can only point to whole tiles (no fine scroll). The next 4 bits aren't enough to control fine X AND Y.
You know what? As I think of it, I'm starting to think that the "x" I asked about before is the fine x, right? And the top 4 bits are the fine y (exept for the last one, i know)?
OK, I think I got it know, I would only like a confirmation from you guys on the stuff I just asked. And one more thing: If the 14th bit gets cleared on the 1st write to $2006, how do you set it again? Or don't you? You said that 2005 and 2006 share the toggle that selects between 1st and 2nd
writes. So, could I do something like this:
.write to $2000
.1st write to $2006
.2nd write to $2005
.1st write to $2005
.2nd write to $2006
This way the bit clearing will not bother me, am I right? Can it be done in this order, can I transfer all bits successifully in this way?
Thanks for the help guys!
PS: This document is written much more from the perspective of the emulator programmer than the NES programmer... I think that's why it took me so long to understand it... Not that I don't know how an emulator works, but... I just wasn't in the emulator programmer's shoes. Man, this is so great. I finally understood it. The 1st write to 2005 confused me a little, with the top 5 bits going to one place and the lower 3 to another... didn't get the notation very well at first.
Just noticed one more thing: The writes to $2006 are fairly pointless, exept for the fact that the second write to $2006 makes the whole thing active, right? If the first write to $2006 can be done as I asked before (before all other writes), it doesn't matter what you write. But do we actually have to go through the trouble of packing the bits in the correct way for the second write to $2006? Well, it is not such a big deal, but... many little shifts involved just for a little write, it bugs me a little bit. I guess this is the price we pay for the effect.
The "complete" way to upload PPU registers is the following :
Code:
lda NameTbl
asl A
asl A
sta $2006
lda VScroll
sta $2005
lda HScroll
sta $2005
lda VScroll
asl A
asl A
and #$e0
sta Temp
lda HScroll
lsr A
lsr A
lsr A
ora Temp
sta $2006
Of couse, in function of the practiced application, this can be simplified a lot. For exemple, if you modify only the main scrooling, but not fine scrooling, this can be simplified, by writing only to $2006 and not to $2005. If you want to just change main vertical scrooling and to keep fine horizontal scrooling, write twice to $2006 then once to $2005.
If you only want to change the fine horizontal scrooling, just write once to $2005.
Etc...
Just as I thought. That means I FINALLY got it... Man, I've been trying to figure this thing out for, like, one year or so...
The annoying part is the bit packing for the second write to 2006, as I said before. But as you said, the final code can be simpler depending on what you want to happen, not always we need that much precision.
I don't actually have a use for this stuff right now, but it is just good to know that I can use it if I need. I hate knowing the NES has a feature I can't master. I love to get the best out of the system! =)
By the way, are there any commercial games that do it like this? I tried to think of one, but none of the ones I came up with did anything similar, when I checked using a debugger. I thought Battletoads had to do something similar, in the beginning of the first level, but it didn't, they did it some other way.
Battletoads does write twite to $2006 to get the vertical scrooling, then twice to $2005 to get horizontal scrooling (the second write is dummy and don't actually need to be there). All licenced games seems to do like this, and the only restriction is that they need timed code to setup fine vertical scrooling.
Bregalad wrote:
Battletoads does write twite to $2006 to get the vertical scrooling, then twice to $2005 to get horizontal scrooling (the second write is dummy and don't actually need to be there). All licenced games seems to do like this
Yeah, many games I checked did it like this... I can't seem to understand how this works, though, since the second write to $2005 has no effect.
Quote:
and the only restriction is that they need timed code to setup fine vertical scrooling.
What do you mean? How can timed code help them in getting fine vertical scroll?
Anonymous wrote:
Bregalad wrote:
Battletoads does write twite to $2006 to get the vertical scrooling, then twice to $2005 to get horizontal scrooling (the second write is dummy and don't actually need to be there). All licenced games seems to do like this
Yeah, many games I checked did it like this... I can't seem to understand how this works, though, since the second write to $2005 has no effect.
Quote:
and the only restriction is that they need timed code to setup fine vertical scrooling.
What do you mean? How can timed code help them in getting fine vertical scroll?
In order to do smooth scrolling without that trick, you have to black out the background (ideally by switching CHR banks or equivalent), wait N scanlines, set vertical scroll to the coarse offset you want (with two $2006 writes), wait 8-N scanlines, then start rendering the playfield. All vertical scrolling games with a top-mounted status bar use this technique, the most noticeable ones being Battletoads and Castlevania 3.
Anonymous wrote:
Bregalad wrote:
Battletoads does write twite to $2006 to get the vertical scrooling, then twice to $2005 to get horizontal scrooling (the second write is dummy and don't actually need to be there). All licenced games seems to do like this
Yeah, many games I checked did it like this... I can't seem to understand how this works, though, since the second write to $2005 has no effect.
The second write to $2005 is to reset the even/odd latch, right? Otherwise you'd have to read $2002.