safer DMA on DMA_doDMA(..)
Make sure the VDP write issuing DMA command is a memory word write for safer DMA operation (see Sega technical bulletin to have more information about possible issue here)
@@ -425,12 +425,20 @@ void DMA_doDma(u8 location, u32 from, u16 to, u16 len, s16 step)
break;
}
- const u16 cmdh = cmd >> 16;
- const u16 cmdl = cmd;
-
- pw = (vu16*) GFX_CTRL_PORT;
pwz = (vu16*) Z80_HALT_PORT;
+ {
+ vu32 cmdbuf[1];
+ u16* cmdbufp;
+
+ // force storing DMA command into memory
+ cmdbuf[0] = cmd;
+
+ // then force issuing DMA from memory word operand
+ cmdbufp = (u16*) cmdbuf;
+ // first command word
+ *pw = *cmdbufp++;
+
// DISABLE Z80
*pwz = 0x0100;
#if (HALT_Z80_ON_DMA == 0)
@@ -442,9 +450,9 @@ void DMA_doDma(u8 location, u32 from, u16 to, u16 len, s16 step)
*pwz = z80restore;
#endif
- // trigger DMA
- *pw = cmdh;
- *pw = cmdl;
+ // trigger DMA (second word command wrote from memory to avoid possible failure on some MD)
+ *pw = *cmdbufp;
+ }
#if (HALT_Z80_ON_DMA != 0)
// re-enable Z80 after DMA (safer method)
