void gt64xxx_device::perform_dma(address_space &space, int which) { do { offs_t srcaddr = m_reg[GREG_DMA0_SOURCE + which]; offs_t dstaddr = m_reg[GREG_DMA0_DEST + which]; UINT32 bytesleft = m_reg[GREG_DMA0_COUNT + which] & 0xffff; int srcinc, dstinc; m_dma_active = which; m_reg[GREG_DMA0_CONTROL + which] |= 0x5000; /* determine src/dst inc */ switch ((m_reg[GREG_DMA0_CONTROL + which] >> 2) & 3) { default: case 0: srcinc = 1; break; case 1: srcinc = -1; break; case 2: srcinc = 0; break; } switch ((m_reg[GREG_DMA0_CONTROL + which] >> 4) & 3) { default: case 0: dstinc = 1; break; case 1: dstinc = -1; break; case 2: dstinc = 0; break; } if (LOG_DMA) logerror("Performing DMA%d: src=%08X dst=%08X bytes=%04X sinc=%d dinc=%d\n", which, srcaddr, dstaddr, bytesleft, srcinc, dstinc); /* standard transfer */ while (bytesleft > 0) { space.write_byte(dstaddr, space.read_byte(srcaddr)); srcaddr += srcinc; dstaddr += dstinc; bytesleft--; } /* not verified, but seems logical these should be updated byte the end */ m_reg[GREG_DMA0_SOURCE + which] = srcaddr; m_reg[GREG_DMA0_DEST + which] = dstaddr; m_reg[GREG_DMA0_COUNT + which] = (m_reg[GREG_DMA0_COUNT + which] & ~0xffff) | bytesleft; m_dma_active = -1; /* if we did not hit zero, punt and return later */ if (bytesleft != 0) return; /* interrupt? */ if (!(m_reg[GREG_DMA0_CONTROL + which] & 0x400)) { m_reg[GREG_INT_STATE] |= 1 << (GINT_DMA0COMP_SHIFT + which); update_irqs(); } } while (dma_fetch_next(space, which)); m_reg[GREG_DMA0_CONTROL + which] &= ~0x5000; }
void c65_state::DMAgicExecute(address_space &space,UINT32 address) { UINT8 cmd;// = space.read_byte(address++); UINT16 length; //= space.read_byte(address++); UINT32 src, dst; static const char *const dma_cmd_string[] = { "COPY", // 0 "MIX", "SWAP", "FILL" }; cmd = space.read_byte(address++); length = space.read_byte(address++); length|=(space.read_byte(address++)<<8); src = space.read_byte(address++); src|=(space.read_byte(address++)<<8); src|=(space.read_byte(address++)<<16); dst = space.read_byte(address++); dst|=(space.read_byte(address++)<<8); dst|=(space.read_byte(address++)<<16); if(cmd & 0xfc) printf("%02x\n",cmd & 0xfc); switch(cmd & 3) { case 0: // copy - TODO: untested { if(length != 1) printf("DMAgic %s %02x -> %08x %04x (CHAIN=%s)\n",dma_cmd_string[cmd & 3],src,dst,length,cmd & 4 ? "yes" : "no"); UINT32 SourceIndex; UINT32 DestIndex; UINT16 SizeIndex; SourceIndex = src & 0xfffff; DestIndex = dst & 0xfffff; SizeIndex = length; do { space.write_byte(DestIndex++,space.read_byte(SourceIndex++)); SizeIndex--; }while(SizeIndex != 0); return; } case 3: // fill { /* TODO: upper bits of source */ printf("DMAgic %s %02x -> %08x %04x (CHAIN=%s)\n",dma_cmd_string[cmd & 3],src & 0xff,dst,length,cmd & 4 ? "yes" : "no"); UINT8 FillValue; UINT32 DestIndex; UINT16 SizeIndex; FillValue = src & 0xff; DestIndex = dst & 0xfffff; SizeIndex = length; do { space.write_byte(DestIndex++,FillValue); SizeIndex--; }while(SizeIndex != 0); } return; } printf("DMAgic %s %08x %08x %04x (CHAIN=%s)\n",dma_cmd_string[cmd & 3],src,dst,length,cmd & 4 ? "yes" : "no"); }
static void memory_write_byte(address_space &space, offs_t address, UINT8 data, UINT8 mem_mask) { space.write_byte(address, data); }