It is currently Tue Oct 16, 2018 8:36 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Thu Sep 12, 2013 5:48 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3629
Location: Mountain View, CA
The combination of tepples, blargg, and rainwarrior's posts above have answered my questions about the mirroring part, specifically rainwarrior's quote here:
rainwarrior wrote:
... The mirroring is simply a side effect of ignoring those bits.

Makes sense now. I had thought it was the other way around, i.e. the mirroring happened intentionally (as in someone had to go the extra mile to make it happen). Yay for people who can explain hardware.


Top
 Profile  
 
PostPosted: Thu Sep 12, 2013 5:51 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6880
Location: Canada
$2005 and $2006 operate on a shared register.

To set the scroll write to $2005 twice before the end of vblank, and the scroll will take effect at the top of the screen when rendering begins, but ONLY if you don't do anything else to mess with the PPU address. Writing $2006 will override whatever you did to $2005. You should get rid of those writes to $2006. (Writing all 0s to it will have the same effect as writing 0s to $2005 so in this case it doesn't matter here, but when you start actually scrolling it will matter.)

See this if you want to know all the gritty details: http://wiki.nesdev.com/w/index.php/The_skinny_on_NES_scrolling

(Not really necessary reading, but if you ever want to know what's really going on with $2005/2006 this is it.)


Top
 Profile  
 
PostPosted: Thu Sep 12, 2013 5:56 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3629
Location: Mountain View, CA
StephenM wrote:
Thanks! Seems like scrolling can get quite complicated! I will eventually have to master scrolling in both horizontal and vertical directions.

Despite what the others here may say, I too think it's extremely complicated. It all has to do with how it all works under the hood/behind the scenes (meaning how $2000, $2005, and $2006 affect the PPU internally, and even more specifically how they affect the PPU depending on what it's doing at that moment in time).

In my time (during which I haven't written much actual code, and only semi-recently have had the ability to test things on actual hardware vs. emulators), I've had to do two things in two different programs (and at different times/places within the programs): one required me to write $00/$00 to $2005 (which is the most common situation for simple things -- aforementioned threads go over it), and another case where I had to write $3F/$00 to $2006 (and I now understand how/why that was needed) and I think writing $00/$00 $2005 (but I could be remembering wrong; but I do remember the order mattered, as has already been mentioned/discussed/documented).

The tricky part is understanding/acknowledging that those registers can, in some way or another, affect scrolling depending on what the PPU is doing at that moment in time or what has been previously written. As you can see there's a very intricate relationship between those 3 registers and the PPU internals.

I find the SNES/SFC a significantly easier console to work on in this regard (from a programmer's perspective that is).


Top
 Profile  
 
PostPosted: Thu Sep 12, 2013 6:12 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20660
Location: NE Indiana, USA (NTSC)
koitsu wrote:
I find the SNES/SFC a significantly easier console to work on in this regard (from a programmer's perspective that is).

Including learning a second CPU's assembly language to get any sound output?


Top
 Profile  
 
PostPosted: Thu Sep 12, 2013 6:47 pm 
Offline
User avatar

Joined: Fri Aug 30, 2013 10:18 pm
Posts: 13
3gengames wrote:
Wrong, you have to not care about $2006, and write to $2005 two times, and then to $2000 to set the scroll. Only use $2006 to set scroll during rendering.

Ok I see, so $2005 during Vblank and $2006 during rendering. When you say "and then to $2000 to set the scroll" are you talking about setting which name table I'm using? How does PPU control #1 set scroll?

rainwarrior wrote:
Writing $2006 will override whatever you did to $2005. Writing all 0s to it will have the same effect as writing 0s to $2005 so in this case it doesn't matter here.

Gotcha! It's a little dangerous for me to have so many $00's floating around. I always try to avoid being right for the wrong reasons.


Top
 Profile  
 
PostPosted: Thu Sep 12, 2013 7:12 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2263
Think of the X and Y scroll as 16 bits. The bottom 5 or so bits of X are stored elsewhere, so the $2006 write trash all the top X Bits, and all Y and nametable select bits, that's why you have to set both $2005 and $2000 nametable bits. The nametable selection bits are just the top of the X and Y scroll. Scroll is just the lower part, basically.

And the 1st set scroll will be controlled by the same latch as the PPU $2006 latch, so you can reset with reading $2002 if you want, but it should be in line with your vblank code.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 7:04 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10893
Location: Rio de Janeiro - Brazil
3gengames wrote:
Think of the X and Y scroll as 16 bits.

More like 9 bits each. The 9th bit of the X scroll selects between left and right name tables, while the 9th bit of the Y scroll selects between the top and bottom name tables. These bits had to be put in another register ($2000), since $2005 only takes 8-bit values.

Quote:
The bottom 5 or so bits of X are stored elsewhere

It's 3 bits actually, the fine scroll that ranges from 0 to 7.

Quote:
the $2006 write trash all the top X Bits, and all Y and nametable select bits, that's why you have to set both $2005 and $2000 nametable bits. The nametable selection bits are just the top of the X and Y scroll. Scroll is just the lower part, basically.

This is pretty much correct.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 10:30 am 
Offline

Joined: Tue Apr 05, 2005 7:30 pm
Posts: 179
A useful thing to do when you get around to scrolling worlds is to store horizontal and vertical scroll into 16-bit variables, use the low bytes to set the X/Y scrolls, and use the LSB of the two high bytes to set the name table address, thus potentially having two 16-bit X and Y coordinates. Of course, you'd have to handle the wraparound in the Y scroll from 239 to 0, or vice versa, yourself.

_________________
Be whatever the situation demands.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 1:17 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10893
Location: Rio de Janeiro - Brazil
Just writing to agree with doppelganger.

Sometimes I wonder if we should drop the "name table selection bits" name altogether and just call them the high bits of the scroll, because newbies often have a lot of trouble seeing how the two things connect in order to scroll over bigger worlds. But then I figure this wouldn't be of much help because there's still a clear separation between the name tables because of the way they are mapped, and the configurable mirroring doesn't make it any easier either.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 1:24 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20660
Location: NE Indiana, USA (NTSC)
tokumaru wrote:
Sometimes I wonder if we should drop the "name table selection bits" name altogether and just call them the high bits of the scroll

The wiki currently calls them both: "Equivalently, bits 0 and 1 are the most significant bit of the scrolling coordinates."


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 2:11 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
It doesn't even make sense to call them nametable selection bits, because except for X=0 Y=0, you're displaying more than one nametable. From a programming standpoint, they are truely the top bits of the 9-bit scroll positions. "The NES displays a 256x240 portion of the 512x480 offscreen stored in VRAM and has 9-bit X and Y scrolling positions to set what portion is displayed."


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 7:56 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2263
But the memory map supports the idea of it being 4 separate entities.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 8:30 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
The image is composed of four blocks, which are each composed of 960 smaller blocks, which are each composed of 64 even smaller blocks (pixels). So taking all these into account, scrolling consists of three distinct parts for each axis: nametable select (1 bit), tile select (5 bits), and pixel select (3 bits). From a programming perspective, this view seems of less utility than treating it as a 9-bit pixel position on a 512x480-pixel image.


Top
 Profile  
 
PostPosted: Fri Sep 13, 2013 8:32 pm 
Offline
Formerly 65024U

Joined: Sat Mar 27, 2010 12:57 pm
Posts: 2263
Yeah, but when you get in to attributes, viewing it as a single 512x480 entity will completely throw everything you know off because you'll have to change it for 4 different screens.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: JRoatch and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group