Mercurial > repos > blastem
diff segacd.c @ 2062:07ed42bd7b4c segacd
Some progress on CDC and CDD emulation. Now passes first 3 "CDC INIT" tests in mcd-verificator
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 28 Jan 2022 00:50:17 -0800 |
parents | 7c1760b5b3e5 |
children | 02a9846668d1 |
line wrap: on
line diff
--- a/segacd.c Thu Jan 27 00:33:41 2022 -0800 +++ b/segacd.c Fri Jan 28 00:50:17 2022 -0800 @@ -292,6 +292,12 @@ } } +static void cdd_run(segacd_context *cd, uint32_t cycle) +{ + cdd_mcu_run(&cd->cdd, cycle, cd->gate_array + GA_CDD_CTRL, &cd->cdc); + lc8951_run(&cd->cdc, cycle); +} + static uint32_t next_timer_int(segacd_context *cd) { if (cd->timer_pending) { @@ -311,27 +317,36 @@ segacd_context *cd = context->system; context->int_cycle = CYCLE_NEVER; uint8_t mask = context->status & 0x7; - if (mask < 4) { - if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) { - uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle; - if (cdd_cycle < context->int_cycle) { - context->int_cycle = cdd_cycle; - context->int_num = 4; + if (mask < 5) { + if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) { + uint32_t cdc_cycle = lc8951_next_interrupt(&cd->cdc); + if (cdc_cycle < context->int_cycle) { + context->int_cycle = cdc_cycle; + context->int_num = 5; } } - if (mask < 3) { - uint32_t next_timer; - if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) { - uint32_t next_timer_cycle = next_timer_int(cd); - if (next_timer_cycle < context->int_cycle) { - context->int_cycle = next_timer_cycle; - context->int_num = 3; + if (mask < 4) { + if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN4) { + uint32_t cdd_cycle = cd->cdd.int_pending ? context->current_cycle : cd->cdd.next_int_cycle; + if (cdd_cycle < context->int_cycle) { + context->int_cycle = cdd_cycle; + context->int_num = 4; } } - if (mask < 2) { - if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { - context->int_cycle = cd->int2_cycle; - context->int_num = 2; + if (mask < 3) { + uint32_t next_timer; + if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN3) { + uint32_t next_timer_cycle = next_timer_int(cd); + if (next_timer_cycle < context->int_cycle) { + context->int_cycle = next_timer_cycle; + context->int_num = 3; + } + } + if (mask < 2) { + if (cd->int2_cycle < context->int_cycle && (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN2)) { + context->int_cycle = cd->int2_cycle; + context->int_num = 2; + } } } } @@ -370,6 +385,7 @@ case GA_CDC_CTRL: return cd->gate_array[reg] | cd->cdc.ar; case GA_CDC_REG_DATA: + cdd_run(cd, m68k->current_cycle); return lc8951_reg_read(&cd->cdc); case GA_STOP_WATCH: case GA_TIMER: @@ -380,7 +396,7 @@ case GA_CDD_STATUS2: case GA_CDD_STATUS3: case GA_CDD_STATUS4: - cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, m68k->current_cycle); return cd->gate_array[reg]; break; case GA_FONT_DATA0: @@ -482,12 +498,15 @@ break; } case GA_CDC_CTRL: + cdd_run(cd, m68k->current_cycle); lc8951_ar_write(&cd->cdc, value); cd->gate_array[reg] &= 0xC000; cd->gate_array[reg] = value & 0x0700; break; case GA_CDC_REG_DATA: + cdd_run(cd, m68k->current_cycle); lc8951_reg_write(&cd->cdc, value); + calculate_target_cycle(m68k); break; case GA_STOP_WATCH: //docs say you should only write zero to reset @@ -520,7 +539,7 @@ calculate_target_cycle(m68k); break; case GA_CDD_CTRL: { - cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, m68k->current_cycle); uint16_t changed = cd->gate_array[reg] ^ value; cd->gate_array[reg] &= ~BIT_HOCK; cd->gate_array[reg] |= value & BIT_HOCK; @@ -538,11 +557,11 @@ case GA_CDD_CMD1: case GA_CDD_CMD2: case GA_CDD_CMD3: - cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, m68k->current_cycle); cd->gate_array[reg] = value & 0x0F0F; break; case GA_CDD_CMD4: - cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, m68k->current_cycle); cd->gate_array[reg] = value & 0x0F0F; cdd_mcu_start_cmd_recv(&cd->cdd, cd->gate_array + GA_CDD_CTRL); break; @@ -586,7 +605,7 @@ case GA_CDD_CMD4: if (!address) { //byte write to $FF804A should not trigger transfer - cdd_mcu_run(&cd->cdd, m68k->current_cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, m68k->current_cycle); cd->gate_array[reg] &= 0x0F; cd->gate_array[reg] |= (value << 8 & 0x0F00); return vcontext; @@ -611,7 +630,7 @@ static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) { timers_run(cd, cycle); - cdd_mcu_run(&cd->cdd, cycle, cd->gate_array + GA_CDD_CTRL); + cdd_run(cd, cycle); } static m68k_context *sync_components(m68k_context * context, uint32_t address)