Changes in fine horizontal scroll during scanline rendering

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
Josh G.

Changes in fine horizontal scroll during scanline rendering

Post by Josh G. » Wed Nov 23, 2005 9:45 pm

Quietust posted here previously that changes in the fine horizontal scroll value via $2005 (low 3 bits) take effect immediately, even in the middle of a scanline. The coarse scroll value (high 5 bits) would obviously not be implemented until the next scanline when the tile index would be reloaded. I'm having trouble understanding how changing the fine X scroll value in mid-scanline would work. Would the PPU render the same pixels from a tile twice if it were decremented? I thought the shift register only worked 1 way. I initially assumed that the fine X scroll just told the PPU how many bits to throw away from the left edge of the first tile rendered, but apparently that's not the case. Can anyone shed some light on how this would actually work? It was stated that some games (e.g. SMB3 during the matching subgame) rely upon this behavior. Does Nintendulator currently emulate this?

User avatar
Quietust
Posts: 1500
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Changes in fine horizontal scroll during scanline render

Post by Quietust » Wed Nov 23, 2005 11:15 pm

Josh G. wrote:Would the PPU render the same pixels from a tile twice if it were decremented?
Yes.
Josh G. wrote:I thought the shift register only worked 1 way. I initially assumed that the fine X scroll just told the PPU how many bits to throw away from the left edge of the first tile rendered, but apparently that's not the case.
When the PPU renders, it uses a series of 16-bit shift registers with 8-bit parallel inputs at the beginning and 8-bit parallel outputs at the end. The fine X scroll simply selects which of the 8 output bit sets to feed to the sprite unit. This also explains why the PPU must fetch TWO tiles in advance at the end of each scanline before it can start rendering - it takes that much data to "prime" the shift register so it can output valid data.

And now, a diagram to attempt to illustrate what's going on:

Code: Select all

                  Input bits, coming from the logic that fetches tiles
                  * * * * * * * *
                  | | | | | | | |
===============   =============== parallel load happens every 8 pixels
== Shift Reg ==<--== Shift Reg == serial shift happens every 1 pixel
===============   =============== there are 4 of these (tile and attrib bits)
| | | | | | | |    ***
* * * * * * * *    \|/ fine horizontal scroll, selects one of those 8 bits
|_|_|_|_|_|_|_|_____|____
                         |
                         |
                         Output to sprite comparitor
I do not know for a fact that this is the way that the PPU works, but, given all current evidence, it is extremely likely that it does work this way.
Josh G. wrote:It was stated that some games (e.g. SMB3 during the matching subgame) rely upon this behavior.
It does not rely on this behavior, but correct behavior will produce a characteristic graphical glitch at the edge of each scrolling area (which is visible on a real NES).
Josh G. wrote:Does Nintendulator currently emulate this?
It does.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

Josh G.

Post by Josh G. » Thu Nov 24, 2005 8:20 pm

Thanks! I had to mull over your diagram for about 15 minutes before it all clicked, but I think I get it now.

So... what (if any) aspects of the NES hardware *aren't* currently supported by Nintendulator? Have you reached absolute perfection (in terms of basic CPU/PPU/APU emulation, not weird mappers) yet? It seems like you're getting pretty close.

User avatar
Quietust
Posts: 1500
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust » Thu Nov 24, 2005 10:16 pm

I still haven't implemented low-level sprite evaluation (I've got some partial code, but it needs some significant changes before it'll work properly) and my audio core is nowhere near perfect - once I get a CopyNES, though, I'll be able to check things more easily.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

User avatar
Anes
Posts: 604
Joined: Tue Dec 21, 2004 8:35 pm
Location: Argentina
Contact:

Post by Anes » Sat Nov 26, 2005 9:23 pm

Quietust i have just implemented the pixel processing in that way, but i still dont figure out how the 2 upper bits of the pixel (AT) are fetched.
Any help?
ANes

User avatar
Quietust
Posts: 1500
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust » Sun Nov 27, 2005 1:15 pm

The upper 2 bits of each pixel come from the Attribute Table - if your emulator has working video then you should already know where to get it from.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

User avatar
Anes
Posts: 604
Joined: Tue Dec 21, 2004 8:35 pm
Location: Argentina
Contact:

Post by Anes » Sun Nov 27, 2005 10:36 pm

its working but i use precalculated AT BYTE location and SHR amount.
That's why i was asking.
ANes

User avatar
Quietust
Posts: 1500
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust » Mon Nov 28, 2005 12:55 am

Anes wrote:its working but i use precalculated AT BYTE location and SHR amount.
Define "precalculated". The real PPU 'calculates' the attribute byte address/shift based on the nametable address it fetched from immediately prior.
(when I say 'calculates' I mean 'takes certain groups of bits from the VRAM address and rearranges them')
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

Post Reply