+ .text
+
+#include "hwregs.h"
+#include "vdp.inc"
+
+ | dma_systovram(vmem_addr, src, count)
+ .globl dma_systovram
+dma_systovram:
+ vdp_setreg VDP_REG_MODE2, VDP_M2_INIT + VDP_M2_DISP + VDP_M2_DMA
+
+ | set source address
+ move.l 8(%sp), %d0
+ move.l %d0, %d1
+ vdp_setreg_reg VDP_REG_DMASRCL, %d0
+ lsr.w #8, %d1
+ vdp_setreg_reg VDP_REG_DMASRCM, %d1
+ swap %d0
+ vdp_setreg_reg VDP_REG_DMASRCH, %d0
+ | set count (in words)
+ move.w 14(%sp), %d0
+ move.w %d0, %d1
+ vdp_setreg_reg VDP_REG_DMACNTL, %d0
+ lsr.w #8, %d1
+ vdp_setreg_reg VDP_REG_DMACNTH, %d1
+ | set the destination address.
+ move.w 6(%sp), %d0
+ move.w %d0, %d1
+ and.w #0x3fff, %d0
+ or.w #(VDP_VRAM_DMA >> 16), %d0
+ move.w %d0, VDP_CTL_PORT
+ | 2 upper bits and rest of the type flags
+ rol.w #2, %d1
+ and.w #3, %d1
+ or.w #(VDP_VRAM_DMA & 0xf0), %d1
+ | last word needs to come from RAM, so we push it on the stack
+ move.w %d1, -(%sp)
+ move.w (%sp), VDP_CTL_PORT
+ add.l #2, %sp
+
+ | after DMA ends the cpu can continue, turn DMA off
+ vdp_setreg VDP_REG_MODE2, VDP_M2_INIT + VDP_M2_DISP
+ rts
+
+| vi:ft=gas68k: