Horizontal scrolling problem

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Horizontal scrolling problem
by on (#93410)
Hi ,

I've implemented an emulator which begins to be operational. Nevetheless i have a scrolling problem that i don't understand. In Super Mario Bros the scrolling works great except for some lines, the last displaying score, time, ...
An example of the problem:

Image

Does anyone has an idea of what could happen ??

by on (#93411)
I see three problems:
  1. The sprites appear to be drawn one scanline above their true position. A scanline with attribute 0 equal to 128 will cover lines 129 through 136, not 128 through 135, because sprite data for a given scanline is fetched during the previous scanline.
  2. If pixels in a background tile are color $00, they'll be color $00 and not $04, $08, or $0C, no matter the attribute. For example, if the attribute is $01, the colors are $00, $05, $06, and $07, and if the attribute is $02, the colors are $00, $09, $0A, and $0B. That explains the black box around the coin in the status bar.
  3. Writes to the horizontal scroll register take effect at the end of the scanline, not the beginning. Writes to bits 0 to 2 take effect on the exact CPU cycle, but writes to bits 3 to 7 and the horizontal nametable select don't take effect until x=257. Eventually, you'll need to be able to render part of a scanline at once so that some games' mid-scanline effects work, but for now, you can emulate as if scroll changes take effect at the end of a scanline.

There also appears to be a slight problem with the scaling of the final image, causing the hill at the left side to appear uneven, but I'll let that slide for now.

by on (#93417)
Thanks for your answer. Nevertheless i don't really understand the point c(particularly the writes to bits 0 ot 2 take effect in the exact cpu cycle...., do you mean that only a part of the horizontal scroll offset shall be taken into account at different moments of the rendering ??).

The scaling is not good but it's not normal because the final is too large.

by on (#93418)
Yeah, scrolling is a little weird, but here's some info:

http://wiki.nesdev.com/w/index.php/The_skinny_on_NES_scrolling

by on (#93424)
nop wrote:
do you mean that only a part of the horizontal scroll offset shall be taken into account at different moments of the rendering ??

Yes. Are you familiar with the concept of "racing the beam"? The CPU and the PPU run at the same time, and the effect of writes to certain ports on the PPU shows up immediately in the PPU pixels rendered after the write. Other writes are buffered and don't take effect until the PPU checks the buffer.

How accurate you want your emulator to be is your decision. There are several grades of accuracy, each with its pros and cons. If you just want to get games working, go ahead and buffer horizontal scroll changes until the end of the scanline.

by on (#93503)
Your emulator is messing up on sprite 0 hit it appears...