I'm kinda cheating, actually. This is IRQ-driven with no special measures; hence the jitter byuu found.Sik wrote:What are you using as an anchor point on the SNES?
There's one DMA transfer per scanline, which means the data is exactly what fits on the screen (28KB) in a linear bitmap format. Originally I was going to trigger the DMA with timed code, which would have required me to use an IRQ at the top of the screen followed by a cycle-counted stagger-stepping technique based on an H-counter read to align to a particular dot (I've done this before). And once I found out that DMA always targets the main screen (on my SNES) I started thinking about exploiting that to align the CPU to half-dot precision. Unfortunately, if I've correctly understood the way DMA aligns itself, just writing straight to the active layer would inevitably result in a one-dot offset between scanlines, and the offset pattern would change every two frames.
So I set up a loading pattern on the main screen and a display pattern on the subscreen, turned on colour addition, and set it to clip the main screen to black before math (which results in the subscreen being displayed by itself). So the DMA now writes to the CGRAM index pointed to by the (invisible) main screen, and a bit later the subscreen displays the colour. This allows DMA writes to happen with up to three dots worth of jitter with no visible artifacting, and 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 could have done that with the live-write technique, but it would have required a less straightforward data format).
What it looks like to me is that the failure cases seem to involve the DMA targeting the subscreen instead of the main screen. This would actually be trivial to detect without checking the version number. If the alignment is consistent within a single runtime (ie: only a reset or power cycle can change it), it may be possible to fix this...
How much? fullsnes doesn't mention this...byuu wrote:DRAM refresh moving around between hardware revisions.
Because I need an uninterrupted loading pattern on the main screen, and it has to be invisible.Espozo wrote:I forgot, why can't using color math work the way you have it 93143?
Using timed code to write directly to a display layer would probably allow colour math, but because of the DMA alignment issue (8 master clocks since reset, and a scanline isn't a multiple of that; neither is every other frame) I wouldn't get nice static vertical columns like you see here. This might not matter as much for a video mode, but it'd probably look goofy for a still.
DMA on the Mega Drive goes at two pixels per word, just like on the SNES, but the word size is 16-bit. VRAM only accepts half a word, which is why screen coverage per VBlank is almost identical to the SNES (a touch lower, actually, but you can keep going into active display at a much slower rate if you don't mind the CPU hit). But CRAM and VSRAM take 16-bit words, meaning you can DMA a 9-bit value to CRAM in one shot.You know, what's the technical explanation as to why this goes by every 4 pixels instead of every 2 like on the Genesis?
The SNES has an 8-bit data bus, and the DMA unit is on the CPU, so it's 8-bit no matter what. This means you need two writes to update a colour, and at two pixels per byte that's four pixels.