# HG changeset patch # User Michael Pavone # Date 1647665730 25200 # Node ID 95b3752925e0a303ade9f5e1d1e18017fdef961e # Parent 9caebcfeac7238d1fd3c87ad7e34863f246a94fb Can now pass all CDC DMA3 tests in mcd-verificator diff -r 9caebcfeac72 -r 95b3752925e0 segacd.c --- a/segacd.c Fri Mar 18 20:49:07 2022 -0700 +++ b/segacd.c Fri Mar 18 21:55:30 2022 -0700 @@ -740,6 +740,7 @@ //cd->gate_array[reg] &= 0xC000; //apparently this clears EDT, should it also clear DSR? cd->gate_array[reg] = value & 0x0700; + cd->gate_array[GA_CDC_DMA_ADDR] = 0; cd->cdc_dst_low = 0; break; case GA_CDC_REG_DATA: @@ -748,6 +749,10 @@ lc8951_reg_write(&cd->cdc, value); calculate_target_cycle(m68k); break; + case GA_CDC_HOST_DATA: + //writes to this register have the same side effects as reads + sub_gate_read16(address, vcontext); + break; case GA_CDC_DMA_ADDR: cdd_run(cd, m68k->current_cycle); cd->gate_array[reg] = value; @@ -914,6 +919,12 @@ return sub_gate_write16(address, vcontext, value16); } +static uint8_t can_main_access_prog(segacd_context *cd) +{ + //TODO: use actual busack + return cd->busreq || !cd->reset; +} + static uint8_t handle_cdc_byte(void *vsys, uint8_t value) { segacd_context *cd = vsys; @@ -962,6 +973,9 @@ cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; break; case DST_PROG_RAM: + if (can_main_access_prog(cd)) { + return 0; + } cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1); dma_addr++; @@ -971,9 +985,10 @@ case DST_WORD_RAM: if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { //1M mode, write to bank assigned to Sub CPU - dma_addr &= (1 << 17) - 2; - cd->m68k->mem_pointers[1][dma_addr] = cd->gate_array[GA_CDC_HOST_DATA]; - m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1); + + uint32_t masked = dma_addr & (1 << 17) - 2; + cd->m68k->mem_pointers[1][masked] = cd->gate_array[GA_CDC_HOST_DATA]; + m68k_invalidate_code_range(cd->m68k, 0x0C0000 + masked - 1, 0x0C0000 + masked + 1); } else { //2M mode, check if Sub CPU has access if (cd->main_has_word2m) { @@ -995,12 +1010,6 @@ return 1; } -static uint8_t can_main_access_prog(segacd_context *cd) -{ - //TODO: use actual busack - return cd->busreq || !cd->reset; -} - static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) { timers_run(cd, cycle); @@ -1225,8 +1234,10 @@ m68k->mem_pointers[cd->memptr_start_index] = NULL; m68k_invalidate_code_range(m68k, cd->base + 0x220000, cd->base + 0x240000); m68k_invalidate_code_range(cd->m68k, bank * 0x20000, (bank + 1) * 0x20000); - if (!new_access) { - dump_prog_ram(cd); + dump_prog_ram(cd); + uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; + if (dst == DST_PROG_RAM) { + lc8951_resume_transfer(&cd->cdc, cd->cdc.cycle); } } break; @@ -1276,6 +1287,10 @@ case GA_HINT_VECTOR: cd->rom_mut[0x72/2] = value; break; + case GA_CDC_HOST_DATA: + //writes to this register have the same side effects as reads + main_gate_read16(address, vcontext); + break; case GA_COMM_FLAG: //Main CPU can only write the upper byte; cd->gate_array[reg] &= 0xFF;