A while back, I posted about DPCM interfering with vertical scrolling in Zelda, where if DPCM is playing, writes to PPU_ADDRESS during rendering sometimes cause the screen to jump to unexpected locations (frequently $2000 or $2100). As tepples suggested back then, this is indeed related to timing. I've created a repro for it that tries to mimic Zelda's scrolling, but uses variable timing instead of DPCM. I've had success reproducing the glitching on console with an Everdrive, but as expected, it doesn't occur in any emulator I've tried.

I've attached a copy of the repro, containing a version without glitching (normal) and a version with variable delay that reproduces the problem (delay), as well as some messy source code. Does anyone have any idea what's going on here that emulators don't seem to replicate?

During the process of fetching DMC bytes in playback, the DMA process will wait 3 cycles before the actual read. The 6502 is designed to always read or write on every cycle, so every one of these idle cycles are a read of the current address bus register. So not only does the reads affect timing, but all stale addresses will be reread if the DMC cuts in in the middle of an instruction.

Fortunately, PPU registers mostly ignore single cycle rereads, but there are documented circumstances where timing is sensitive, including the SMB glitch line. Emulators that cover the pre-PAL DMA bug may only be programmed to handle 4016h/4017h/4014h (and some PPU registers), but even my emulator — which handles all stale address bus values — only jitters vertically like the others.

ap9: While both Zelda and the split_scroll_delayed test should be scrolling by a tile every 4 frames (with 1 scanline of jitter depending on the timing of the split), there are frames on which rendering after the screen split begins at a location that does not correspond to the values written to PPU_ADDRESS.

I also have a repro as a patch for the Zelda PRG0 ROM, which I've attached below. The split_scroll_test was an attempt to narrow down the cause a little bit, since there are unusual things going on when it occurs in Zelda (DPCM, extra reads of PPU_DATA after the PPU_ADDRESS writes, and writing the full nametable address to PPU_ADDRESS, which causes an unexpected fine y adjustment). It does seem to just be the timing of the writes.

Does the same quirk exist in the PRG1 version of Zelda? If not, then that may be something they fixed (either directly or by revamping code). Doesn't change the question about accurate emulation, but still.

It's also present in PRG1. It was 'fixed' in the Japanese cartridge release (which came after the NA versions, as this was originally on FDS in Japan) by changing the timing of the writes to be earlier in the scanline, which makes the split even less clean in the non-DPCM case. My interest here is not just in accurate emulation, but also for development (testing in emulator and knowing what I actually need to do to avoid this problem).

Alyosha_TAS wrote:ok, I can get the exact same behaviour as in the videos if I do the following things.
[...]
-Have a race condition between the h and v increments on cycle 256 and the latching from $2006 occurring on the same cycle that results in all related variables being reset to 0.

lidnariq wrote:... no, it can't be exactly the same glitch, because this sticks for the remainder of the frame, but that one is only a single scanline

They're similar in that they're both race conditions that seem to occur around pixel 256.

With 8-bit logic, wouldn't the counters would be incremented in pieces? That would explain these glitches. Say, if the lower 8 bits were glitched to zero, but the high bits remain? Or vice versa depending on the cycle and register.

This scroll test and the glitch line test are small and cut to the chase to be run with Visual2C02 to pinpoint what happens.