Mercurial > repos > blastem
diff genesis.c @ 2025:e7a516f08cec
Implement serial IO, a generic serial device type and external interrupts
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 10 Feb 2021 20:12:16 -0800 |
parents | 270a4c875e0a |
children | 894bf99a13f1 |
line wrap: on
line diff
--- a/genesis.c Tue Nov 24 23:15:25 2020 -0800 +++ b/genesis.c Wed Feb 10 20:12:16 2021 -0800 @@ -234,13 +234,14 @@ context->sync_cycle = context->current_cycle + gen->max_cycles; } context->int_cycle = CYCLE_NEVER; - if ((context->status & 0x7) < 6) { + uint8_t mask = context->status & 0x7; + if (mask < 6) { uint32_t next_vint = vdp_next_vint(v_context); if (next_vint != CYCLE_NEVER) { context->int_cycle = next_vint; context->int_num = 6; } - if ((context->status & 0x7) < 4) { + if (mask < 4) { uint32_t next_hint = vdp_next_hint(v_context); if (next_hint != CYCLE_NEVER) { next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint; @@ -250,6 +251,21 @@ } } + if (mask < 2 && (v_context->regs[REG_MODE_3] & BIT_EINT_EN)) { + uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle); + uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle); + uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle); + uint32_t next_eint = next_eint_port0 < next_eint_port1 + ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2) + : (next_eint_port1 < next_eint_port2 ? next_eint_port1 : next_eint_port2); + if (next_eint != CYCLE_NEVER) { + next_eint = next_eint < context->current_cycle ? context->current_cycle : next_eint; + if (next_eint < context->int_cycle) { + context->int_cycle = next_eint; + context->int_num = 2; + } + } + } } } if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { @@ -379,6 +395,9 @@ sync_z80(z_context, mclks); sync_sound(gen, mclks); vdp_run_context(v_context, mclks); + io_run(gen->io.ports, mclks); + io_run(gen->io.ports + 1, mclks); + io_run(gen->io.ports + 2, mclks); if (mclks >= gen->reset_cycle) { gen->reset_requested = 1; context->should_return = 1; @@ -793,7 +812,7 @@ io_control_write(gen->io.ports+2, value, context->current_cycle); break; case 0x7: - gen->io.ports[0].serial_out = value; + io_tx_write(gen->io.ports, value, context->current_cycle); break; case 0x8: case 0xB: @@ -801,19 +820,20 @@ //serial input port is not writeable break; case 0x9: + io_sctrl_write(gen->io.ports, value, context->current_cycle); gen->io.ports[0].serial_ctrl = value; break; case 0xA: - gen->io.ports[1].serial_out = value; + io_tx_write(gen->io.ports + 1, value, context->current_cycle); break; case 0xC: - gen->io.ports[1].serial_ctrl = value; + io_sctrl_write(gen->io.ports + 1, value, context->current_cycle); break; case 0xD: - gen->io.ports[2].serial_out = value; + io_tx_write(gen->io.ports + 2, value, context->current_cycle); break; case 0xF: - gen->io.ports[2].serial_ctrl = value; + io_sctrl_write(gen->io.ports + 2, value, context->current_cycle); break; } } else { @@ -949,28 +969,28 @@ value = gen->io.ports[0].serial_out; break; case 0x8: - value = gen->io.ports[0].serial_in; + value = io_rx_read(gen->io.ports, context->current_cycle); break; case 0x9: - value = gen->io.ports[0].serial_ctrl; + value = io_sctrl_read(gen->io.ports, context->current_cycle); break; case 0xA: value = gen->io.ports[1].serial_out; break; case 0xB: - value = gen->io.ports[1].serial_in; + value = io_rx_read(gen->io.ports + 1, context->current_cycle); break; case 0xC: - value = gen->io.ports[1].serial_ctrl; + value = io_sctrl_read(gen->io.ports, context->current_cycle); break; case 0xD: value = gen->io.ports[2].serial_out; break; case 0xE: - value = gen->io.ports[2].serial_in; + value = io_rx_read(gen->io.ports + 1, context->current_cycle); break; case 0xF: - value = gen->io.ports[2].serial_ctrl; + value = io_sctrl_read(gen->io.ports, context->current_cycle); break; default: value = get_open_bus_value(&gen->header) >> 8;