Well, it looks like we're about done here for the time being. Considering I seem to have correctly guessed why the code wasn't working on my first try, both times, I'm going to just assume it works properly until such time as I can justify buying a SNES Jr. (for unrelated reasons: I'll want to do compatibility tests for my shmup port).
Thanks to everyone who helped out! Maybe something interesting will come of this knowledge someday...
Only one thing still bugs me. It looks like the dead line problem doesn't happen on a real SNES. So why does it happen on all versions of bsnes/higan?
93143 wrote:it also allows me to start the DMA before the beginning of the active scanline and buffer enough colours to get through the DRAM refresh
I still don't entirely get this because DRAM refresh is smack in the middle of the screen for 40 clocks.
The main/sub trick allows me to preload a number of colours in advance by increasing the offset between the loading and display patterns. This allows me to start with a buffer that stays filled until I need it, without requiring me to break up the linear bitmap format of the image.
I start each line well back in HBlank. I manually set the CGRAM index to the index used at the beginning of the display pattern and start the DMA early enough that four colours get written during HBlank, with the CGRAM address incrementing normally without interference from the PPU. The first column of the loading pattern is actually the same index as the fifth
column of the display pattern, and it remains four columns (16 dots) ahead until DRAM refresh.
DRAM refresh is handled by making one of the columns in the loading pattern 14 pixels wide instead of 4. This leaves the loading pattern only 6 dots ahead of the display pattern rather than 16. (If what fullsnes says about half-dot CPU 'wakeups' during refresh is true, it should be possible in principle to hit one of those and have the write go to the wrong pattern, but I... guess I dodged a bullet?)
You may notice that the actual data in the ROM has some extra colour and palette indices offscreen. That's a relic of my (successful) attempt to fix the dead line problem in bsnes/higan. But if the problem doesn't show up on a real SNES, why then it doesn't need fixing, does it?
As for why there's a colour #1 stripe at the right-hand edge of the loading pattern... I was trying to get the PPU to reset the CGRAM index for me, so I wouldn't have to waste time doing it manually. But it didn't work.
Source is attached. There are a few inconsequential details that are different from last time, such as the IRQ clear during the NMI routine - I was paranoid about breaking it this time, so I didn't change anything but the comments and formatting. The checksum should be the same as dmac_align_i.sfc.
Should I try to find a different picture? I've just kinda been using your photo as a reference standard...