diff --git a/src/mame/machine/megacd.c b/src/mame/machine/megacd.c index 4f2ef7fd958..2b27d286d21 100644 --- a/src/mame/machine/megacd.c +++ b/src/mame/machine/megacd.c @@ -100,7 +100,7 @@ ADDRESS_MAP_START( segacd_map, AS_PROGRAM, 16, sega_segacd_device ) AM_RANGE(0xff8004 ,0xff8005) AM_DEVREADWRITE("tempcdc",lc89510_temp_device, segacd_cdc_mode_address_r, segacd_cdc_mode_address_w) AM_RANGE(0xff8006 ,0xff8007) AM_DEVREADWRITE("tempcdc",lc89510_temp_device,segacd_cdc_data_r, segacd_cdc_data_w) AM_RANGE(0xff8008, 0xff8009) AM_DEVREAD("tempcdc",lc89510_temp_device, cdc_data_sub_r) - AM_RANGE(0xff800a, 0xff800b) AM_DEVREADWRITE("tempcdc",lc89510_temp_device,cdc_dmaaddr_r,cdc_dmaaddr_w) // CDC DMA Address + AM_RANGE(0xff800a, 0xff800b) AM_READWRITE(segacd_dmaaddr_r,segacd_dmaaddr_w) // DMA Address (not CDC, used in conjunction with) AM_RANGE(0xff800c, 0xff800d) AM_READWRITE(segacd_stopwatch_timer_r, segacd_stopwatch_timer_w)// Stopwatch timer AM_RANGE(0xff800e ,0xff800f) AM_READWRITE(segacd_comms_flags_r, segacd_comms_flags_subcpu_w) AM_RANGE(0xff8010 ,0xff801f) AM_READWRITE(segacd_comms_sub_part1_r, segacd_comms_sub_part1_w) @@ -1678,6 +1678,16 @@ void sega_segacd_device::device_start() // todo register save state stuff } +READ16_MEMBER( sega_segacd_device::segacd_dmaaddr_r ) +{ + return m_dmaaddr; +} + +WRITE16_MEMBER( sega_segacd_device::segacd_dmaaddr_w ) +{ + COMBINE_DATA(&m_dmaaddr); +} + void sega_segacd_device::device_reset() { @@ -1693,6 +1703,7 @@ void sega_segacd_device::device_reset() lc89510_temp = machine().device(":segacd:tempcdc"); lc89510_temp->reset_cd(); + m_dmaaddr = 0; scd_dma_timer->adjust(attotime::zero); stopwatch_timer = machine().device(":segacd:sw_timer"); @@ -1753,7 +1764,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( sega_segacd_device::scd_dma_timer_callback ) } // todo: tidy up, too many CDC internals here -void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination ) +void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination ) { int length = dmacount; UINT8 *dest; @@ -1765,12 +1776,12 @@ void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UIN if (destination==DMA_PCM) { - dstoffset = (SEGACD_DMA_ADDRESS & 0x03FF) << 2; + dstoffset = (m_dmaaddr & 0x03FF) << 2; PCM_DMA = true; } else { - dstoffset = (SEGACD_DMA_ADDRESS & 0xFFFF) << 3; + dstoffset = (m_dmaaddr & 0xFFFF) << 3; } @@ -1849,11 +1860,11 @@ void sega_segacd_device::SegaCD_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UIN if (PCM_DMA) { - SEGACD_DMA_ADDRESS += length >> 1; + m_dmaaddr += length >> 1; } else { - SEGACD_DMA_ADDRESS += length >> 2; + m_dmaaddr += length >> 2; } } diff --git a/src/mame/machine/megacd.h b/src/mame/machine/megacd.h index 80905b8051f..c2701914bf3 100644 --- a/src/mame/machine/megacd.h +++ b/src/mame/machine/megacd.h @@ -272,6 +272,9 @@ public: UINT16 segacd_1meg_mode_word_read(int offset, UINT16 mem_mask); void segacd_1meg_mode_word_write(running_machine& machine, int offset, UINT16 data, UINT16 mem_mask, int use_pm); + DECLARE_READ16_MEMBER( segacd_dmaaddr_r ); + DECLARE_WRITE16_MEMBER( segacd_dmaaddr_w ); + UINT16 m_dmaaddr; @@ -365,7 +368,7 @@ public: READ16_MEMBER( segacd_font_converted_r ); TIMER_DEVICE_CALLBACK_MEMBER( scd_dma_timer_callback ); - void SegaCD_CDC_Do_DMA( int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination ); + void SegaCD_CDC_Do_DMA( int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination ); timer_device* scd_dma_timer; protected: diff --git a/src/mame/machine/megacdcd.c b/src/mame/machine/megacdcd.c index 647b7f30d6a..2eaf9d5359f 100644 --- a/src/mame/machine/megacdcd.c +++ b/src/mame/machine/megacdcd.c @@ -28,12 +28,6 @@ lc89510_temp_device::lc89510_temp_device(const machine_config &mconfig, const ch for (int i=0;i<2352;i++) NeoCDSectorData[i] = 0; bNeoCDLoadSector = false; - NeoCDDMAAddress1 = 0; - NeoCDDMAAddress2 = 0; - NeoCDDMAValue1 = 0; - NeoCDDMAValue2 = 0; - NeoCDDMACount = 0; - NeoCDDMAMode = 0; CDC_REG0 = 0; nNeoCDIRQVectorAck = 0; nNeoCDIRQVector = 0; @@ -53,7 +47,7 @@ void lc89510_temp_device::set_is_neoCD(device_t &device, bool is_neoCD) } // HACK for DMA handling, this gets replaced -void lc89510_temp_device::Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination ) +void lc89510_temp_device::Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination ) { fatalerror("Fake_CDC_Do_DMA\n"); } @@ -455,7 +449,7 @@ void lc89510_temp_device::lc89510_Reset(void) CDD_Reset(); CDC_Reset(); - CDC_REG0 = CDC_REG1 = SEGACD_DMA_ADDRESS = SCD_STATUS_CDC = CDD_DONE = 0; + CDC_REG0 = CDC_REG1 = SCD_STATUS_CDC = CDD_DONE = 0; } void lc89510_temp_device::CDC_End_Transfer(running_machine& machine) @@ -504,7 +498,7 @@ void lc89510_temp_device::CDC_Do_DMA(running_machine& machine, int rate) UINT16 dma_addrc = LC8951RegistersW[REG_W_DACL] | (LC8951RegistersW[REG_W_DACH]<<8); // HACK - segacd_dma_callback(dmacount, CDC_BUFFER, SEGACD_DMA_ADDRESS, dma_addrc, destination ); + segacd_dma_callback(dmacount, CDC_BUFFER, dma_addrc, destination ); dma_addrc += length*2; @@ -894,15 +888,7 @@ WRITE8_MEMBER( lc89510_temp_device::segacd_cdd_tx_w ) -READ16_MEMBER( lc89510_temp_device::cdc_dmaaddr_r ) -{ - return SEGACD_DMA_ADDRESS; -} -WRITE16_MEMBER( lc89510_temp_device::cdc_dmaaddr_w ) -{ - COMBINE_DATA(&SEGACD_DMA_ADDRESS); -} READ16_MEMBER( lc89510_temp_device::segacd_cdfader_r ) { @@ -1061,252 +1047,6 @@ void lc89510_temp_device::NeoCDCommsReset() nff0016 = 0; } -static INT32 SekIdle(INT32 nCycles) -{ - return nCycles; -} - -void lc89510_temp_device::NeoCDDoDMA() -{ - - // The LC8953 chip has a programmable DMA controller, which is not properly emulated. - // Since the software only uses it in a limited way, we can apply a simple heuristic - // to determnine the requested operation. - - // Additionally, we don't know how many cycles DMA operations take. - // Here, only bus access is used to get a rough approximation -- - // each read/write takes a single cycle, setup and everything else is ignored. - -// bprintf(PRINT_IMPORTANT, _T(" - DMA controller transfer started (PC: 0x%06X)\n"), SekGetPC(-1)); - - switch (NeoCDDMAMode) { - - case 0xCFFD: { -// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 8); - - // - DMA controller 0x7E -> 0xCFFD (PC: 0xC07CE2) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) - // - DMA controller program[02] -> 0xE8DA (PC: 0xC07CEE) - // - DMA controller program[04] -> 0x92DA (PC: 0xC07CF4) - // - DMA controller program[06] -> 0x92DB (PC: 0xC07CFA) - // - DMA controller program[08] -> 0x96DB (PC: 0xC07D00) - // - DMA controller program[10] -> 0x96F6 (PC: 0xC07D06) - // - DMA controller program[12] -> 0x2E02 (PC: 0xC07D0C) - // - DMA controller program[14] -> 0xFDFF (PC: 0xC07D12) - - SekIdle(NeoCDDMACount * 4); - - while (NeoCDDMACount--) { - SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 24); - SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 16); - SekWriteWord(NeoCDDMAAddress1 + 4, NeoCDDMAAddress1 >> 8); - SekWriteWord(NeoCDDMAAddress1 + 6, NeoCDDMAAddress1 >> 0); - NeoCDDMAAddress1 += 8; - } - - break; - } - - case 0xE2DD: { -// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X, skip odd bytes\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); - - // - DMA controller 0x7E -> 0xE2DD (PC: 0xC0A190) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) - // - DMA controller program[02] -> 0x82BE (PC: 0xC0A194) - // - DMA controller program[04] -> 0x93DA (PC: 0xC0A196) - // - DMA controller program[06] -> 0xBE93 (PC: 0xC0A198) - // - DMA controller program[08] -> 0xDABE (PC: 0xC0A19A) - // - DMA controller program[10] -> 0xF62D (PC: 0xC0A19C) - // - DMA controller program[12] -> 0x02FD (PC: 0xC0A19E) - // - DMA controller program[14] -> 0xFFFF (PC: 0xC0A1A0) - - SekIdle(NeoCDDMACount * 1); - - while (NeoCDDMACount--) { - SekWriteWord(NeoCDDMAAddress2 + 0, SekReadByte(NeoCDDMAAddress1 + 0)); - SekWriteWord(NeoCDDMAAddress2 + 2, SekReadByte(NeoCDDMAAddress1 + 1)); - NeoCDDMAAddress1 += 2; - NeoCDDMAAddress2 += 4; - } - - break; - } - - case 0xFC2D: { -// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); - - // - DMA controller 0x7E -> 0xFC2D (PC: 0xC0A190) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) - // - DMA controller program[02] -> 0x8492 (PC: 0xC0A194) - // - DMA controller program[04] -> 0xDA92 (PC: 0xC0A196) - // - DMA controller program[06] -> 0xDAF6 (PC: 0xC0A198) - // - DMA controller program[08] -> 0x2A02 (PC: 0xC0A19A) - // - DMA controller program[10] -> 0xFDFF (PC: 0xC0A19C) - // - DMA controller program[12] -> 0x48E7 (PC: 0xC0A19E) - // - DMA controller program[14] -> 0xFFFE (PC: 0xC0A1A0) - - char* data = LC8915InitTransfer(); - if (data == NULL) { - break; - } - - SekIdle(NeoCDDMACount * 4); - - while (NeoCDDMACount--) { - SekWriteByte(NeoCDDMAAddress1 + 0, data[0]); - SekWriteByte(NeoCDDMAAddress1 + 2, data[1]); - NeoCDDMAAddress1 += 4; - data += 2; - } - - LC8915EndTransfer(); - - break; - } - - case 0xFE3D: - - // - DMA controller 0x7E -> 0xFE3D (PC: 0xC0A190) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) - // - DMA controller program[02] -> 0x82BF (PC: 0xC0A194) - // - DMA controller program[04] -> 0x93BF (PC: 0xC0A196) - // - DMA controller program[06] -> 0xF629 (PC: 0xC0A198) - // - DMA controller program[08] -> 0x02FD (PC: 0xC0A19A) - // - DMA controller program[10] -> 0xFFFF (PC: 0xC0A19C) - // - DMA controller program[12] -> 0xF17D (PC: 0xC0A19E) - // - DMA controller program[14] -> 0xFCF5 (PC: 0xC0A1A0) - - case 0xFE6D: { -// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2); - - // - DMA controller 0x7E -> 0xFE6D (PC: 0xC0FD7A) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0FD7C) - // - DMA controller program[02] -> 0x82BF (PC: 0xC0FD7E) - // - DMA controller program[04] -> 0xF693 (PC: 0xC0FD80) - // - DMA controller program[06] -> 0xBF29 (PC: 0xC0FD82) - // - DMA controller program[08] -> 0x02FD (PC: 0xC0FD84) - // - DMA controller program[10] -> 0xFFFF (PC: 0xC0FD86) - // - DMA controller program[12] -> 0xC515 (PC: 0xC0FD88) - // - DMA controller program[14] -> 0xFCF5 (PC: 0xC0FD8A) - - SekIdle(NeoCDDMACount * 1); - - while (NeoCDDMACount--) { - SekWriteWord(NeoCDDMAAddress2, SekReadWord(NeoCDDMAAddress1)); - NeoCDDMAAddress1 += 2; - NeoCDDMAAddress2 += 2; - } - -if (NeoCDDMAAddress2 == 0x0800) { -// MapVectorTable(false); -// bprintf(PRINT_ERROR, _T(" RAM vectors mapped (PC = 0x%08X\n"), SekGetPC(0)); -// extern INT32 bRunPause; -// bRunPause = 1; -} - break; - } - - case 0xFEF5: { -// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); - - // - DMA controller 0x7E -> 0xFEF5 (PC: 0xC07CE2) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) - // - DMA controller program[02] -> 0x92E8 (PC: 0xC07CEE) - // - DMA controller program[04] -> 0xBE96 (PC: 0xC07CF4) - // - DMA controller program[06] -> 0xF629 (PC: 0xC07CFA) - // - DMA controller program[08] -> 0x02FD (PC: 0xC07D00) - // - DMA controller program[10] -> 0xFFFF (PC: 0xC07D06) - // - DMA controller program[12] -> 0xFC3D (PC: 0xC07D0C) - // - DMA controller program[14] -> 0xFCF5 (PC: 0xC07D12) - - SekIdle(NeoCDDMACount * 2); - - while (NeoCDDMACount--) { - SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 16); - SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 0); - NeoCDDMAAddress1 += 4; - } - - break; - } - - case 0xFFC5: { -// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2); - - // - DMA controller 0x7E -> 0xFFC5 (PC: 0xC0A190) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) - // - DMA controller program[02] -> 0xA6F6 (PC: 0xC0A194) - // - DMA controller program[04] -> 0x2602 (PC: 0xC0A196) - // - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198) - // - DMA controller program[08] -> 0xFC2D (PC: 0xC0A19A) - // - DMA controller program[10] -> 0xFCF5 (PC: 0xC0A19C) - // - DMA controller program[12] -> 0x8492 (PC: 0xC0A19E) - // - DMA controller program[14] -> 0xDA92 (PC: 0xC0A1A0) - - char* data = LC8915InitTransfer(); - if (data == NULL) { - break; - } - - SekIdle(NeoCDDMACount * 4); - - while (NeoCDDMACount--) { - SekWriteByte(NeoCDDMAAddress1 + 0, data[0]); - SekWriteByte(NeoCDDMAAddress1 + 1, data[1]); - NeoCDDMAAddress1 += 2; - data += 2; - } - - LC8915EndTransfer(); - - break; - } - - case 0xFFCD: - - // - DMA controller 0x7E -> 0xFFCD (PC: 0xC0A190) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) - // - DMA controller program[02] -> 0x92F6 (PC: 0xC0A194) - // - DMA controller program[04] -> 0x2602 (PC: 0xC0A196) - // - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198) - // - DMA controller program[08] -> 0x7006 (PC: 0xC0A19A) - // - DMA controller program[10] -> 0x6100 (PC: 0xC0A19C) - // - DMA controller program[12] -> 0x2412 (PC: 0xC0A19E) - // - DMA controller program[14] -> 0x13FC (PC: 0xC0A1A0) - - case 0xFFDD: { -// bprintf(PRINT_NORMAL, _T(" Fill: 0x%08X - 0x%08X <- 0x%04X\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2, NeoCDDMAValue1); - - // - DMA controller 0x7E -> 0xFFDD (PC: 0xC07CE2) - // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) - // - DMA controller program[02] -> 0x92F6 (PC: 0xC07CEE) - // - DMA controller program[04] -> 0x2602 (PC: 0xC07CF4) - // - DMA controller program[06] -> 0xFDFF (PC: 0xC07CFA) - // - DMA controller program[08] -> 0xFFFF (PC: 0xC07D00) - // - DMA controller program[10] -> 0xFCF5 (PC: 0xC07D06) - // - DMA controller program[12] -> 0x8AF0 (PC: 0xC07D0C) - // - DMA controller program[14] -> 0x1609 (PC: 0xC07D12) - - SekIdle(NeoCDDMACount * 1); - - while (NeoCDDMACount--) { - SekWriteWord(NeoCDDMAAddress1, NeoCDDMAValue1); - NeoCDDMAAddress1 += 2; - } - - break; - } - default: { - //bprintf(PRINT_ERROR, _T(" Unknown transfer type 0x%04X (PC: 0x%06X)\n"), NeoCDDMAMode, SekGetPC(-1)); - //bprintf(PRINT_NORMAL, _T(" ??? : 0x%08X 0x%08X 0x%04X 0x%04X 0x%08X\n"), NeoCDDMAAddress1, NeoCDDMAAddress2, NeoCDDMAValue1, NeoCDDMAValue2, NeoCDDMACount); - -//extern INT32 bRunPause; -//bRunPause = 1; - - } - } -} - void lc89510_temp_device::NeoCDProcessCommand() { @@ -1506,7 +1246,7 @@ void lc89510_temp_device::LC8951UpdateHeader() // neocd } } -char* lc89510_temp_device::LC8915InitTransfer() +char* lc89510_temp_device::LC8915InitTransfer(int NeoCDDMACount) { if (!LC8951RegistersW[REG_W_DTTRG]) { //bprintf(PRINT_ERROR, _T(" LC8951 DTTRG status invalid\n")); @@ -1550,49 +1290,6 @@ void lc89510_temp_device::LC8951Reset() LC8951UpdateHeader(); } -void lc89510_temp_device::set_DMA_regs(int offset, UINT16 wordValue) -{ - switch (offset) - { - case 0x0064: - NeoCDDMAAddress1 &= 0x0000FFFF; - NeoCDDMAAddress1 |= wordValue << 16; - break; - case 0x0066: - NeoCDDMAAddress1 &= 0xFFFF0000; - NeoCDDMAAddress1 |= wordValue; - break; - case 0x0068: - NeoCDDMAAddress2 &= 0x0000FFFF; - NeoCDDMAAddress2 |= wordValue << 16; - break; - case 0x006A: - NeoCDDMAAddress2 &= 0xFFFF0000; - NeoCDDMAAddress2 |= wordValue; - break; - case 0x006C: - NeoCDDMAValue1 = wordValue; - break; - case 0x006E: - NeoCDDMAValue2 = wordValue; - break; - case 0x0070: - NeoCDDMACount &= 0x0000FFFF; - NeoCDDMACount |= wordValue << 16; - break; - case 0x0072: - NeoCDDMACount &= 0xFFFF0000; - NeoCDDMACount |= wordValue; - break; - - case 0x007E: - NeoCDDMAMode = wordValue; -// bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1)); - break; - - } -} - void lc89510_temp_device::reset_NeoCd(void) { { @@ -1787,32 +1484,6 @@ int lc89510_temp_device::Read_LBA_To_Buffer(running_machine& machine) -void lc89510_temp_device::SekWriteWord(UINT32 a, UINT16 d) -{ -// printf("write word %08x %04x\n", a, d); - dma_space->write_word(a,d); -} - -void lc89510_temp_device::SekWriteByte(UINT32 a, UINT8 d) -{ -// printf("write byte %08x %02x\n", a, d); - dma_space->write_byte(a,d); -} - -UINT32 lc89510_temp_device::SekReadByte(UINT32 a) -{ -// printf("read byte %08x\n", a); - return dma_space->read_byte(a); -} - - -UINT32 lc89510_temp_device::SekReadWord(UINT32 a) -{ -// printf("read WORD %08x\n", a); - return dma_space->read_word(a); -} - - void lc89510_temp_device::NeoCDIRQUpdate(UINT8 byteValue) { // do we also need to check the regular interrupts like FBA? diff --git a/src/mame/machine/megacdcd.h b/src/mame/machine/megacdcd.h index 9b539116a3c..d9f2041bcca 100644 --- a/src/mame/machine/megacdcd.h +++ b/src/mame/machine/megacdcd.h @@ -3,7 +3,7 @@ #include "imagedev/chd_cd.h" -typedef device_delegate segacd_dma_delegate; +typedef device_delegate segacd_dma_delegate; @@ -150,7 +150,7 @@ public: // HACK for DMA handling segacd_dma_delegate segacd_dma_callback; - void Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &SEGACD_DMA_ADDRESS, UINT16 &dma_addrc, UINT16 &destination ); + void Fake_CDC_Do_DMA(int &dmacount, UINT8 *CDC_BUFFER, UINT16 &dma_addrc, UINT16 &destination ); static void set_CDC_Do_DMA(device_t &device,segacd_dma_delegate new_segacd_dma_callback); static void set_is_neoCD(device_t &device, bool is_neoCD); @@ -182,7 +182,6 @@ public: UINT16 CDC_DECODE; UINT16 CDC_REG0; UINT16 CDC_REG1; - UINT16 SEGACD_DMA_ADDRESS; UINT8 CDC_BUFFER[(32 * 1024 * 2) + SECTOR_SIZE]; @@ -245,8 +244,6 @@ public: WRITE16_MEMBER( segacd_cdd_ctrl_w ); READ8_MEMBER( segacd_cdd_rx_r ); WRITE8_MEMBER( segacd_cdd_tx_w ); - READ16_MEMBER( cdc_dmaaddr_r ); - WRITE16_MEMBER( cdc_dmaaddr_w ); READ16_MEMBER( segacd_cdfader_r ); WRITE16_MEMBER( segacd_cdfader_w ); @@ -285,13 +282,7 @@ public: bool bNeoCDLoadSector; - INT32 NeoCDDMAAddress1; - INT32 NeoCDDMAAddress2; - INT32 NeoCDDMAValue1; - INT32 NeoCDDMAValue2; - INT32 NeoCDDMACount; - INT32 NeoCDDMAMode; int nNeoCDIRQVectorAck; int get_nNeoCDIRQVectorAck(void) { return nNeoCDIRQVectorAck; } void set_nNeoCDIRQVectorAck(int val) { nNeoCDIRQVectorAck = val; } @@ -303,22 +294,15 @@ public: void NeoCDCommsControl(UINT8 clock, UINT8 send); void NeoCDProcessCommand(); void LC8951UpdateHeader(); - char* LC8915InitTransfer(); + char* LC8915InitTransfer(int NeoCDDMACount); void LC8915EndTransfer(); void LC8951Reset(); void neocd_cdd_tx_w(UINT8 data); UINT8 neocd_cdd_rx_r(); void NeoCDCommsReset(); - void NeoCDDoDMA(); - void SekWriteWord(UINT32 a, UINT16 d); - void SekWriteByte(UINT32 a, UINT8 d); - UINT32 SekReadByte(UINT32 a); - UINT32 SekReadWord(UINT32 a); INT32 CDEmuLoadSector(INT32 LBA, char* pBuffer); - void set_DMA_regs(int offset, UINT16 wordValue); void reset_NeoCd(void); - address_space* dma_space; void nLC8951_w(UINT16 byteValue); UINT16 nLC8951_r(void); diff --git a/src/mess/drivers/ng_aes.c b/src/mess/drivers/ng_aes.c index 478be71108b..01aaeee8864 100644 --- a/src/mess/drivers/ng_aes.c +++ b/src/mess/drivers/ng_aes.c @@ -87,12 +87,22 @@ public: : neogeo_state(mconfig, type, tag), m_tempcdc(*this,"tempcdc") { + NeoCDDMAAddress1 = 0; + NeoCDDMAAddress2 = 0; + NeoCDDMAValue1 = 0; + NeoCDDMAValue2 = 0; + NeoCDDMACount = 0; + NeoCDDMAMode = 0; } - required_device m_tempcdc; + optional_device m_tempcdc; + + void NeoCDDoDMA(); + void set_DMA_regs(int offset, UINT16 wordValue); + UINT8 *m_memcard_data; DECLARE_WRITE8_MEMBER(audio_cpu_clear_nmi_w); DECLARE_WRITE16_MEMBER(io_control_w); @@ -134,6 +144,16 @@ public: INT32 nActiveTransferArea; INT32 nSpriteTransferBank; INT32 nADPCMTransferBank; + INT32 NeoCDDMAAddress1; + INT32 NeoCDDMAAddress2; + INT32 NeoCDDMAValue1; + INT32 NeoCDDMAValue2; + INT32 NeoCDDMACount; + INT32 NeoCDDMAMode; + void SekWriteWord(UINT32 a, UINT16 d); + void SekWriteByte(UINT32 a, UINT8 d); + UINT32 SekReadByte(UINT32 a); + UINT32 SekReadWord(UINT32 a); UINT8 nTransferWriteEnable; @@ -655,7 +675,6 @@ void ng_aes_state::neogeoWriteTransfer(UINT32 sekAddress, UINT8 byteValue, int i case 0: // Sprites address = (nSpriteTransferBank + (sekAddress & 0x0FFFFF)); - // wtf? is this just due to how we decode the sprite gfx or is something bad happening? if ((address&3)==0) NeoSpriteRAM[address] = byteValue; if ((address&3)==1) NeoSpriteRAM[address^3] = byteValue; if ((address&3)==2) NeoSpriteRAM[address^3] = byteValue; @@ -740,7 +759,7 @@ void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue) // DMA controller case 0x0060: if (byteValue & 0x40) { - m_tempcdc->NeoCDDoDMA(); + NeoCDDoDMA(); } break; @@ -753,7 +772,7 @@ void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue) case 0x0070: case 0x0072: case 0x007E: - m_tempcdc->set_DMA_regs(sekAddress & 0xFFFE, wordValue); + set_DMA_regs(sekAddress & 0xFFFE, wordValue); break; // upload DMA controller program @@ -934,6 +953,328 @@ WRITE16_MEMBER(ng_aes_state::neocd_transfer_w) } + + +void ng_aes_state::set_DMA_regs(int offset, UINT16 wordValue) +{ + switch (offset) + { + case 0x0064: + NeoCDDMAAddress1 &= 0x0000FFFF; + NeoCDDMAAddress1 |= wordValue << 16; + break; + case 0x0066: + NeoCDDMAAddress1 &= 0xFFFF0000; + NeoCDDMAAddress1 |= wordValue; + break; + case 0x0068: + NeoCDDMAAddress2 &= 0x0000FFFF; + NeoCDDMAAddress2 |= wordValue << 16; + break; + case 0x006A: + NeoCDDMAAddress2 &= 0xFFFF0000; + NeoCDDMAAddress2 |= wordValue; + break; + case 0x006C: + NeoCDDMAValue1 = wordValue; + break; + case 0x006E: + NeoCDDMAValue2 = wordValue; + break; + case 0x0070: + NeoCDDMACount &= 0x0000FFFF; + NeoCDDMACount |= wordValue << 16; + break; + case 0x0072: + NeoCDDMACount &= 0xFFFF0000; + NeoCDDMACount |= wordValue; + break; + + case 0x007E: + NeoCDDMAMode = wordValue; +// bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1)); + break; + + } +} + + + +void ng_aes_state::SekWriteWord(UINT32 a, UINT16 d) +{ +// printf("write word %08x %04x\n", a, d); + curr_space->write_word(a,d); +} + +void ng_aes_state::SekWriteByte(UINT32 a, UINT8 d) +{ +// printf("write byte %08x %02x\n", a, d); + curr_space->write_byte(a,d); +} + +UINT32 ng_aes_state::SekReadByte(UINT32 a) +{ +// printf("read byte %08x\n", a); + return curr_space->read_byte(a); +} + + +UINT32 ng_aes_state::SekReadWord(UINT32 a) +{ +// printf("read WORD %08x\n", a); + return curr_space->read_word(a); +} + + + +static INT32 SekIdle(INT32 nCycles) +{ + return nCycles; +} + + +void ng_aes_state::NeoCDDoDMA() +{ + + // The LC8953 chip has a programmable DMA controller, which is not properly emulated. + // Since the software only uses it in a limited way, we can apply a simple heuristic + // to determnine the requested operation. + + // Additionally, we don't know how many cycles DMA operations take. + // Here, only bus access is used to get a rough approximation -- + // each read/write takes a single cycle, setup and everything else is ignored. + +// bprintf(PRINT_IMPORTANT, _T(" - DMA controller transfer started (PC: 0x%06X)\n"), SekGetPC(-1)); + + switch (NeoCDDMAMode) { + + case 0xCFFD: { +// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 8); + + // - DMA controller 0x7E -> 0xCFFD (PC: 0xC07CE2) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) + // - DMA controller program[02] -> 0xE8DA (PC: 0xC07CEE) + // - DMA controller program[04] -> 0x92DA (PC: 0xC07CF4) + // - DMA controller program[06] -> 0x92DB (PC: 0xC07CFA) + // - DMA controller program[08] -> 0x96DB (PC: 0xC07D00) + // - DMA controller program[10] -> 0x96F6 (PC: 0xC07D06) + // - DMA controller program[12] -> 0x2E02 (PC: 0xC07D0C) + // - DMA controller program[14] -> 0xFDFF (PC: 0xC07D12) + + SekIdle(NeoCDDMACount * 4); + + while (NeoCDDMACount--) { + SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 24); + SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 16); + SekWriteWord(NeoCDDMAAddress1 + 4, NeoCDDMAAddress1 >> 8); + SekWriteWord(NeoCDDMAAddress1 + 6, NeoCDDMAAddress1 >> 0); + NeoCDDMAAddress1 += 8; + } + + break; + } + + case 0xE2DD: { +// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X, skip odd bytes\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); + + // - DMA controller 0x7E -> 0xE2DD (PC: 0xC0A190) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) + // - DMA controller program[02] -> 0x82BE (PC: 0xC0A194) + // - DMA controller program[04] -> 0x93DA (PC: 0xC0A196) + // - DMA controller program[06] -> 0xBE93 (PC: 0xC0A198) + // - DMA controller program[08] -> 0xDABE (PC: 0xC0A19A) + // - DMA controller program[10] -> 0xF62D (PC: 0xC0A19C) + // - DMA controller program[12] -> 0x02FD (PC: 0xC0A19E) + // - DMA controller program[14] -> 0xFFFF (PC: 0xC0A1A0) + + SekIdle(NeoCDDMACount * 1); + + while (NeoCDDMACount--) { + SekWriteWord(NeoCDDMAAddress2 + 0, SekReadByte(NeoCDDMAAddress1 + 0)); + SekWriteWord(NeoCDDMAAddress2 + 2, SekReadByte(NeoCDDMAAddress1 + 1)); + NeoCDDMAAddress1 += 2; + NeoCDDMAAddress2 += 4; + } + + break; + } + + case 0xFC2D: { +// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer, skip odd bytes\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); + + // - DMA controller 0x7E -> 0xFC2D (PC: 0xC0A190) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) + // - DMA controller program[02] -> 0x8492 (PC: 0xC0A194) + // - DMA controller program[04] -> 0xDA92 (PC: 0xC0A196) + // - DMA controller program[06] -> 0xDAF6 (PC: 0xC0A198) + // - DMA controller program[08] -> 0x2A02 (PC: 0xC0A19A) + // - DMA controller program[10] -> 0xFDFF (PC: 0xC0A19C) + // - DMA controller program[12] -> 0x48E7 (PC: 0xC0A19E) + // - DMA controller program[14] -> 0xFFFE (PC: 0xC0A1A0) + + char* data = m_tempcdc->LC8915InitTransfer(NeoCDDMACount); + if (data == NULL) { + break; + } + + SekIdle(NeoCDDMACount * 4); + + while (NeoCDDMACount--) { + SekWriteByte(NeoCDDMAAddress1 + 0, data[0]); + SekWriteByte(NeoCDDMAAddress1 + 2, data[1]); + NeoCDDMAAddress1 += 4; + data += 2; + } + + m_tempcdc->LC8915EndTransfer(); + + break; + } + + case 0xFE3D: + + // - DMA controller 0x7E -> 0xFE3D (PC: 0xC0A190) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) + // - DMA controller program[02] -> 0x82BF (PC: 0xC0A194) + // - DMA controller program[04] -> 0x93BF (PC: 0xC0A196) + // - DMA controller program[06] -> 0xF629 (PC: 0xC0A198) + // - DMA controller program[08] -> 0x02FD (PC: 0xC0A19A) + // - DMA controller program[10] -> 0xFFFF (PC: 0xC0A19C) + // - DMA controller program[12] -> 0xF17D (PC: 0xC0A19E) + // - DMA controller program[14] -> 0xFCF5 (PC: 0xC0A1A0) + + case 0xFE6D: { +// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- 0x%08X - 0x%08X\n"), NeoCDDMAAddress2, NeoCDDMAAddress2 + NeoCDDMACount * 2, NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2); + + // - DMA controller 0x7E -> 0xFE6D (PC: 0xC0FD7A) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0FD7C) + // - DMA controller program[02] -> 0x82BF (PC: 0xC0FD7E) + // - DMA controller program[04] -> 0xF693 (PC: 0xC0FD80) + // - DMA controller program[06] -> 0xBF29 (PC: 0xC0FD82) + // - DMA controller program[08] -> 0x02FD (PC: 0xC0FD84) + // - DMA controller program[10] -> 0xFFFF (PC: 0xC0FD86) + // - DMA controller program[12] -> 0xC515 (PC: 0xC0FD88) + // - DMA controller program[14] -> 0xFCF5 (PC: 0xC0FD8A) + + SekIdle(NeoCDDMACount * 1); + + while (NeoCDDMACount--) { + SekWriteWord(NeoCDDMAAddress2, SekReadWord(NeoCDDMAAddress1)); + NeoCDDMAAddress1 += 2; + NeoCDDMAAddress2 += 2; + } + +if (NeoCDDMAAddress2 == 0x0800) { +// MapVectorTable(false); +// bprintf(PRINT_ERROR, _T(" RAM vectors mapped (PC = 0x%08X\n"), SekGetPC(0)); +// extern INT32 bRunPause; +// bRunPause = 1; +} + break; + } + + case 0xFEF5: { +// bprintf(PRINT_NORMAL, _T(" adr : 0x%08X - 0x%08X <- address\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 4); + + // - DMA controller 0x7E -> 0xFEF5 (PC: 0xC07CE2) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) + // - DMA controller program[02] -> 0x92E8 (PC: 0xC07CEE) + // - DMA controller program[04] -> 0xBE96 (PC: 0xC07CF4) + // - DMA controller program[06] -> 0xF629 (PC: 0xC07CFA) + // - DMA controller program[08] -> 0x02FD (PC: 0xC07D00) + // - DMA controller program[10] -> 0xFFFF (PC: 0xC07D06) + // - DMA controller program[12] -> 0xFC3D (PC: 0xC07D0C) + // - DMA controller program[14] -> 0xFCF5 (PC: 0xC07D12) + + SekIdle(NeoCDDMACount * 2); + + while (NeoCDDMACount--) { + SekWriteWord(NeoCDDMAAddress1 + 0, NeoCDDMAAddress1 >> 16); + SekWriteWord(NeoCDDMAAddress1 + 2, NeoCDDMAAddress1 >> 0); + NeoCDDMAAddress1 += 4; + } + + break; + } + + case 0xFFC5: { +// bprintf(PRINT_NORMAL, _T(" copy: 0x%08X - 0x%08X <- LC8951 external buffer\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2); + + // - DMA controller 0x7E -> 0xFFC5 (PC: 0xC0A190) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) + // - DMA controller program[02] -> 0xA6F6 (PC: 0xC0A194) + // - DMA controller program[04] -> 0x2602 (PC: 0xC0A196) + // - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198) + // - DMA controller program[08] -> 0xFC2D (PC: 0xC0A19A) + // - DMA controller program[10] -> 0xFCF5 (PC: 0xC0A19C) + // - DMA controller program[12] -> 0x8492 (PC: 0xC0A19E) + // - DMA controller program[14] -> 0xDA92 (PC: 0xC0A1A0) + + char* data = m_tempcdc->LC8915InitTransfer(NeoCDDMACount); + if (data == NULL) { + break; + } + + SekIdle(NeoCDDMACount * 4); + + while (NeoCDDMACount--) { + SekWriteByte(NeoCDDMAAddress1 + 0, data[0]); + SekWriteByte(NeoCDDMAAddress1 + 1, data[1]); + NeoCDDMAAddress1 += 2; + data += 2; + } + + m_tempcdc->LC8915EndTransfer(); + + break; + } + + case 0xFFCD: + + // - DMA controller 0x7E -> 0xFFCD (PC: 0xC0A190) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC0A192) + // - DMA controller program[02] -> 0x92F6 (PC: 0xC0A194) + // - DMA controller program[04] -> 0x2602 (PC: 0xC0A196) + // - DMA controller program[06] -> 0xFDFF (PC: 0xC0A198) + // - DMA controller program[08] -> 0x7006 (PC: 0xC0A19A) + // - DMA controller program[10] -> 0x6100 (PC: 0xC0A19C) + // - DMA controller program[12] -> 0x2412 (PC: 0xC0A19E) + // - DMA controller program[14] -> 0x13FC (PC: 0xC0A1A0) + + case 0xFFDD: { +// bprintf(PRINT_NORMAL, _T(" Fill: 0x%08X - 0x%08X <- 0x%04X\n"), NeoCDDMAAddress1, NeoCDDMAAddress1 + NeoCDDMACount * 2, NeoCDDMAValue1); + + // - DMA controller 0x7E -> 0xFFDD (PC: 0xC07CE2) + // - DMA controller program[00] -> 0xFCF5 (PC: 0xC07CE8) + // - DMA controller program[02] -> 0x92F6 (PC: 0xC07CEE) + // - DMA controller program[04] -> 0x2602 (PC: 0xC07CF4) + // - DMA controller program[06] -> 0xFDFF (PC: 0xC07CFA) + // - DMA controller program[08] -> 0xFFFF (PC: 0xC07D00) + // - DMA controller program[10] -> 0xFCF5 (PC: 0xC07D06) + // - DMA controller program[12] -> 0x8AF0 (PC: 0xC07D0C) + // - DMA controller program[14] -> 0x1609 (PC: 0xC07D12) + + SekIdle(NeoCDDMACount * 1); + + while (NeoCDDMACount--) { + SekWriteWord(NeoCDDMAAddress1, NeoCDDMAValue1); + NeoCDDMAAddress1 += 2; + } + + break; + } + default: { + //bprintf(PRINT_ERROR, _T(" Unknown transfer type 0x%04X (PC: 0x%06X)\n"), NeoCDDMAMode, SekGetPC(-1)); + //bprintf(PRINT_NORMAL, _T(" ??? : 0x%08X 0x%08X 0x%04X 0x%04X 0x%08X\n"), NeoCDDMAAddress1, NeoCDDMAAddress2, NeoCDDMAValue1, NeoCDDMAValue2, NeoCDDMACount); + +//extern INT32 bRunPause; +//bRunPause = 1; + + } + } +} + + /* * Handling selectable controller types */ @@ -1170,7 +1511,6 @@ MACHINE_RESET_MEMBER(ng_aes_state,neogeo) NeoZ80ROMActive = memregion("audiocpu")->base(); NeoTextRAM = memregion("fixed")->base(); curr_space = &machine().device("maincpu")->memory().space(AS_PROGRAM); - m_tempcdc->dma_space = curr_space; m_tempcdc->NeoCDCommsReset();