This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Best time in the scanline to modify the scroll mid-frame

Best time in the scanline to modify the scroll mid-frame
by on (#63285)
Neil's thread about mid-screen palette changes got me thinking about mid-screen scroll changes (also discussed in that thread), and I was wondering if you guys had anything to say about this.

I already know how to write to $2006, $2005, $2005, $2006 (in that order) in order to set the scroll to any part of the name tables I want, but I'm not sure what would be the best time to do that during rendering (so far I have only done this after extending VBlank, before turning rendering back on).

Of course I want the whole thing to take effect during HBlank, so that the next scanline is displayed correctly, but there are a few things to consider:

1. The vertical scroll is incremented by the PPU at cycle 251;
2. The horizontal scroll is reset by the PPU at cycle 257;
3. At the end of HBlank (what cycle?) the PPU starts fetching tiles for the next scanline;

I am thinking about making the writes approximately at the following times:

$2006: close to the end of the scanline, with pixels still rendering;
$2005: close to the end of the scanline, with pixels still rendering;
$2005: during HBlank, because the fine X scroll changes right away;
$2006: during HBlank, before the PPU starts fetching tiles;

I'll of course have some wiggling room, so the first two writes might happen closer to or during HBlank, but the third one definitely happens after HBlank starts.

Am I right to guess that there is nothing wrong in messing with T (temporary VRAM address) as the PPU finishes rendering pixels and enters HBlank? Or is this not as simple as I'm assuming, and disabling rendering is a necessity?

by on (#63286)
Go ahead and mess with T, it's basically the 'Horizontal reset' thingy for each scanline, and the 'Vertical Reset' thingy for the top.

The PPU doesn't mess with T in the middle of the frame anyway, it just reads some bits from it every scanline to reset the horizontal scroll.

by on (#63287)
Chapter "Low level scanline timing" : http://jonathan.microclub.ch/NES_raster/

by on (#63316)
Bregalad wrote:
Chapter "Low level scanline timing" : http://jonathan.microclub.ch/NES_raster/

I did in fact read that chapter in your document before posting, but some things weren't very clear.

For example, you say that "on cycle 256, the PPU increments it's internal row counter, and the coarse horizontal scrolling gets reloaded", which apparently isn't true (not that it matters so much in this case, but it might in other circumstances). Anyway, your suggestion of modifying the scroll "either always before cycle 256 or always after" was kinda vague. Also you don't provide exact timing information, you just say that NOPs should be added/removed until the effect is glitch-free, and I wanted something more specific.

It did help a little though, so thanks, but I still had to ask the more specific questions here.

Dwedit wrote:
Go ahead and mess with T

Thanks Dwedit. I imagine that this should work fine, but when it comes to these low level details I'd rather ask, since some of you (specially emulator authors) know the tiniest details I couldn't possibly know about.

by on (#63332)
Well then I can't answer you because pretty much all I know was put into the document.

I don't think I said anything wrong about that cycle 256 thing, but maybe different source numbered the cycles differently ?

Anyway, on your second $2006 write, it should land either always before cycle 256 or always after - by always I mean in all cases of jitter. If you fall between the two (so that, depending on jitter condition, you will write after or before 256) you will get shaking graphics, because in some cases the V scroll will be incremented before your write, and sometimes after.

by on (#63343)
Bregalad wrote:
Well then I can't answer you because pretty much all I know was put into the document.

I appreciate the effort you put into making a document about a subject that is not widely known, but it's a very broad subject and some types of raster effects need very specific timing, and there is no way you could talk about every possible case, so it's understandable that it's a bit vague sometimes.

Quote:
I don't think I said anything wrong about that cycle 256 thing, but maybe different source numbered the cycles differently ?

Like I said in the first post, the vertical and horizontal components of the scroll are updated at different times (cycles 251 and 257 respectively, definitely around 256, but not exactly). I don't remember who said that, but IIRC the information came from Nintendulator's source code.

Quote:
If you fall between the two (so that, depending on jitter condition, you will write after or before 256) you will get shaking graphics, because in some cases the V scroll will be incremented before your write, and sometimes after.

Sure, the manual scroll change must happen always before or always after the automatic change, of course. But a apparently the automatic change doesn't happen at once, it happens in a window between cycles 251 and 257, so we must watch out for that.

Since I plan on making the last two writes ($2005, $2006) during HBlank, that's well past cycle 257, so I should be safe. And as a plus I get to use the actual scroll values I want, instead of having to awkwardly compensate the values for updating the scroll before the automatic increment.

by on (#63356)
I just tried modifying the scroll as described in my post and it works great in all emulatos I tried, no glitches. I haven't tried on a real NES though, I think I'll clean up the code a bit and fix other things I broke before doing that.