There's a bug in the Legend of Zelda where scrolling vertically when DPCM audio is playing (used for boss roars) can cause the PPU address to be wrong after the HUD split. An example of this can be seen here: https://youtu.be/T4JtnUvhaHo?t=1671. I've been trying to find the mechanism behind this, but I haven't seen any information on NESdev about DPCM interfering with PPU writes. I'd debug the issue in an emulator, but I also haven't been able to reproduce this in any emulator I've tried.
Vertical scrolling in Zelda works by waiting for a sprite 0 hit at Bank5_8521 and then doing two writes at Bank5_8560 to PPU_ADDRESS ($2006) and two reads from PPU_DATA ($2007). When the bug occurs, the screen split still happens at the correct place, but the address seems to become either $2000 or $2100, at least in the examples I've examined. I've not been able to find any bugs in the game that would result in incorrect values being written (address high in $58 and low in $E2), and I would expect such a bug to occur in emulators, as well, so I'm at a bit of a loss.
Is anyone here familiar with what might be going on?
DPCM interfering with vertical scrolling
Moderator: Moderators
Re: DPCM interfering with vertical scrolling
The DPCM glitch affects reads, not writes. Since it's reading $2007, it's likely getting an extra read and blowing past whatever address it was expecting to read from.
https://wiki.nesdev.com/w/index.php?tit ... d_PPU_read
https://wiki.nesdev.com/w/index.php?tit ... d_PPU_read
Re: DPCM interfering with vertical scrolling
Interesting.
The PPU has not been at all designed to handle $2007 reads/writes in quick succession, so the DPCM fetch happening in the middle of the read could potentially mess something up. But that's a pure guess.
The PPU has not been at all designed to handle $2007 reads/writes in quick succession, so the DPCM fetch happening in the middle of the read could potentially mess something up. But that's a pure guess.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
Re: DPCM interfering with vertical scrolling
This problem seems to be independent of the $2007 reads. I created a test ROM that replaces them with reads from $8000 and asked someone with a flash cart to try it out: https://youtu.be/UMdJJNYbigM?t=10. You can see that the problem still occurs, and can verify in the video that the $2007 reads aren't happening because the screen is offset by 2 fewer scanlines.
Re: DPCM interfering with vertical scrolling
Is a cycle-timed wait loop involved? Because DPCM makes those take longer when the DMA unit steals a few cycles from the CPU for each sample byte.
Re: DPCM interfering with vertical scrolling
Yes, though it's not very well-timed; the test loop for the sprite 0 hit isn't as tight as it could be (uses LDA, AND, BEQ), and the wait loop doesn't land it in the idle region on the target scanline, so there can be a lot of jitter even without DPCM: https://youtu.be/T4JtnUvhaHo?t=1612
If DPCM throws off the timing a bit, do you know how that might result in the behavior in the first video? When the scroll first glitches, the game should be writing $2240 or so to PPU_ADDRESS, but it appears to get set to $2000.
If DPCM throws off the timing a bit, do you know how that might result in the behavior in the first video? When the scroll first glitches, the game should be writing $2240 or so to PPU_ADDRESS, but it appears to get set to $2000.
Re: DPCM interfering with vertical scrolling
Since the game originally didn't use DPCM for boss roaring I guess this bug only happens in cartridge versions?
Re: DPCM interfering with vertical scrolling
Dunno, but could the delays be causing code to spill out of vblank?
I'm guessing IRQs are not involved.
I'm guessing IRQs are not involved.
Re: DPCM interfering with vertical scrolling
That question about what versions this happens in was really helpful. To my knowledge, this doesn't happen on FDS, but it turns out it also doesn't happen on the Japanese cartridge version! I compared the scrolling functions and discovered that the J-cart retimes the split so it occurs earlier in the scanline. Porting that over to the US PRG0 fixes the bug, at the cost of showing a bit more garbage on the last line of the HUD. As tepples guessed, DPCM seems to matter, then, in how it impacts the timing of the split.
I guess my next question is why the timing of the write (around the end of the scanline) causes this. Looking at the PPU scrolling page on the wiki and the NTSC timing chart, nothing in hblank stands out to me as a likely culprit. I see that DMC DMA can cause delays of up to 4 cycles (12 dots), though I don't know how frequently that occurs, so I'm not sure how far that can put the $2006 writes into the scanline. Even then, are there specific dots that would result in this?
I guess my next question is why the timing of the write (around the end of the scanline) causes this. Looking at the PPU scrolling page on the wiki and the NTSC timing chart, nothing in hblank stands out to me as a likely culprit. I see that DMC DMA can cause delays of up to 4 cycles (12 dots), though I don't know how frequently that occurs, so I'm not sure how far that can put the $2006 writes into the scanline. Even then, are there specific dots that would result in this?
Re: DPCM interfering with vertical scrolling
The Japanese cartridge version is unique in some ways (it uses the same sound as NES versions but it uses the Japanese script and the microphone for Pols Voice like the FDS version), and as it was released very late (1992 after A Link to the Past) it's not hard to think that they might have tried to fix any known bugs for this release.