When I try the game on the Exodus emulator, it now and then hangs. Sometimes it takes a couple of minutes, sometimes it doesn't happen at all. And always on the 'add d6, d2' instruction, the one just after the start of the DMA command (see below).
This is how the routine looks:
I build the screen in RAM from address screenbuf + 256, and copy it row by row to plane A, which starts at address C000. I don't write 94 (high byte length) since it is 0 from the last DMA. I don't rewrite the RAM source address after the first time because the registers already contain the right values.
Code: Select all
move.l #9700h | >>(screenbuf >> 1) & 127 :: 8f02, (a4) ; these values are leftover from another DMA, so written before that DMA
move.l #93h : 38 :: 4000h | 0c000h & 3fffh, d2 ; length 38 en low part dest
move.w #80h | (0c000h & 0c000h) >> 14, (a6) ; high part destination in (a6)
move.l #95009600h | (<((screenbuf + 256) >> 1) :: 0) | >((screenbuf + 256) >> 1), (a4) ; low and mid source
move.l d2, (a4) ; length and low part address \ repeat 29 times
move.w d4, (a5) ; z80 pause
move.w d5, (a5) ; z80 resume
move.w (a6), (a4) ; high part address and DMA command
add.w d6, d2 ; next row (d6 = 128) /
move.l d2, (a4) ; line 30
move.w d4, (a5)
move.w d5, (a5)
move.w (a6), (a4)
- Is the problem I see just something that is related to the Exodus emulator? I didn't encounter it yet on my Mega Drive model 2, or with other emulators. But maybe it does happen on other mega drive or genesis models and Exodus is just a better emulator than others?
- The sega manual says I have to disable DMA in VDP register 1 when it's finished. Is there any software that does this?
- Is there a order in which the source registers should be written? Probably not because I've seen 95, 96, 97 and 96, 95, 97. Never 97 first though.
- Is it a problem I don't write the high byte of the length?
- Is it a problem I don't write the highest byte of the source registers since those don't change? This byte does contain part of the DMA command after all.
All examples I could find just write all length and source registers, but this doesn't seem to be necessary apart from the problem with Exodus.