Mercurial > repos > blastem
comparison 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 |
comparison
equal
deleted
inserted
replaced
2022:380bc5d4a2cf | 2025:e7a516f08cec |
---|---|
232 genesis_context *gen = context->system; | 232 genesis_context *gen = context->system; |
233 if (context->sync_cycle - context->current_cycle > gen->max_cycles) { | 233 if (context->sync_cycle - context->current_cycle > gen->max_cycles) { |
234 context->sync_cycle = context->current_cycle + gen->max_cycles; | 234 context->sync_cycle = context->current_cycle + gen->max_cycles; |
235 } | 235 } |
236 context->int_cycle = CYCLE_NEVER; | 236 context->int_cycle = CYCLE_NEVER; |
237 if ((context->status & 0x7) < 6) { | 237 uint8_t mask = context->status & 0x7; |
238 if (mask < 6) { | |
238 uint32_t next_vint = vdp_next_vint(v_context); | 239 uint32_t next_vint = vdp_next_vint(v_context); |
239 if (next_vint != CYCLE_NEVER) { | 240 if (next_vint != CYCLE_NEVER) { |
240 context->int_cycle = next_vint; | 241 context->int_cycle = next_vint; |
241 context->int_num = 6; | 242 context->int_num = 6; |
242 } | 243 } |
243 if ((context->status & 0x7) < 4) { | 244 if (mask < 4) { |
244 uint32_t next_hint = vdp_next_hint(v_context); | 245 uint32_t next_hint = vdp_next_hint(v_context); |
245 if (next_hint != CYCLE_NEVER) { | 246 if (next_hint != CYCLE_NEVER) { |
246 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint; | 247 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint; |
247 if (next_hint < context->int_cycle) { | 248 if (next_hint < context->int_cycle) { |
248 context->int_cycle = next_hint; | 249 context->int_cycle = next_hint; |
249 context->int_num = 4; | 250 context->int_num = 4; |
250 | 251 |
252 } | |
253 } | |
254 if (mask < 2 && (v_context->regs[REG_MODE_3] & BIT_EINT_EN)) { | |
255 uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle); | |
256 uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle); | |
257 uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle); | |
258 uint32_t next_eint = next_eint_port0 < next_eint_port1 | |
259 ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2) | |
260 : (next_eint_port1 < next_eint_port2 ? next_eint_port1 : next_eint_port2); | |
261 if (next_eint != CYCLE_NEVER) { | |
262 next_eint = next_eint < context->current_cycle ? context->current_cycle : next_eint; | |
263 if (next_eint < context->int_cycle) { | |
264 context->int_cycle = next_eint; | |
265 context->int_num = 2; | |
266 } | |
251 } | 267 } |
252 } | 268 } |
253 } | 269 } |
254 } | 270 } |
255 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { | 271 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { |
377 | 393 |
378 uint32_t mclks = context->current_cycle; | 394 uint32_t mclks = context->current_cycle; |
379 sync_z80(z_context, mclks); | 395 sync_z80(z_context, mclks); |
380 sync_sound(gen, mclks); | 396 sync_sound(gen, mclks); |
381 vdp_run_context(v_context, mclks); | 397 vdp_run_context(v_context, mclks); |
398 io_run(gen->io.ports, mclks); | |
399 io_run(gen->io.ports + 1, mclks); | |
400 io_run(gen->io.ports + 2, mclks); | |
382 if (mclks >= gen->reset_cycle) { | 401 if (mclks >= gen->reset_cycle) { |
383 gen->reset_requested = 1; | 402 gen->reset_requested = 1; |
384 context->should_return = 1; | 403 context->should_return = 1; |
385 gen->reset_cycle = CYCLE_NEVER; | 404 gen->reset_cycle = CYCLE_NEVER; |
386 } | 405 } |
791 break; | 810 break; |
792 case 0x6: | 811 case 0x6: |
793 io_control_write(gen->io.ports+2, value, context->current_cycle); | 812 io_control_write(gen->io.ports+2, value, context->current_cycle); |
794 break; | 813 break; |
795 case 0x7: | 814 case 0x7: |
796 gen->io.ports[0].serial_out = value; | 815 io_tx_write(gen->io.ports, value, context->current_cycle); |
797 break; | 816 break; |
798 case 0x8: | 817 case 0x8: |
799 case 0xB: | 818 case 0xB: |
800 case 0xE: | 819 case 0xE: |
801 //serial input port is not writeable | 820 //serial input port is not writeable |
802 break; | 821 break; |
803 case 0x9: | 822 case 0x9: |
823 io_sctrl_write(gen->io.ports, value, context->current_cycle); | |
804 gen->io.ports[0].serial_ctrl = value; | 824 gen->io.ports[0].serial_ctrl = value; |
805 break; | 825 break; |
806 case 0xA: | 826 case 0xA: |
807 gen->io.ports[1].serial_out = value; | 827 io_tx_write(gen->io.ports + 1, value, context->current_cycle); |
808 break; | 828 break; |
809 case 0xC: | 829 case 0xC: |
810 gen->io.ports[1].serial_ctrl = value; | 830 io_sctrl_write(gen->io.ports + 1, value, context->current_cycle); |
811 break; | 831 break; |
812 case 0xD: | 832 case 0xD: |
813 gen->io.ports[2].serial_out = value; | 833 io_tx_write(gen->io.ports + 2, value, context->current_cycle); |
814 break; | 834 break; |
815 case 0xF: | 835 case 0xF: |
816 gen->io.ports[2].serial_ctrl = value; | 836 io_sctrl_write(gen->io.ports + 2, value, context->current_cycle); |
817 break; | 837 break; |
818 } | 838 } |
819 } else { | 839 } else { |
820 uint32_t masked = location & 0xFFF00; | 840 uint32_t masked = location & 0xFFF00; |
821 if (masked == 0x11100) { | 841 if (masked == 0x11100) { |
947 break; | 967 break; |
948 case 0x7: | 968 case 0x7: |
949 value = gen->io.ports[0].serial_out; | 969 value = gen->io.ports[0].serial_out; |
950 break; | 970 break; |
951 case 0x8: | 971 case 0x8: |
952 value = gen->io.ports[0].serial_in; | 972 value = io_rx_read(gen->io.ports, context->current_cycle); |
953 break; | 973 break; |
954 case 0x9: | 974 case 0x9: |
955 value = gen->io.ports[0].serial_ctrl; | 975 value = io_sctrl_read(gen->io.ports, context->current_cycle); |
956 break; | 976 break; |
957 case 0xA: | 977 case 0xA: |
958 value = gen->io.ports[1].serial_out; | 978 value = gen->io.ports[1].serial_out; |
959 break; | 979 break; |
960 case 0xB: | 980 case 0xB: |
961 value = gen->io.ports[1].serial_in; | 981 value = io_rx_read(gen->io.ports + 1, context->current_cycle); |
962 break; | 982 break; |
963 case 0xC: | 983 case 0xC: |
964 value = gen->io.ports[1].serial_ctrl; | 984 value = io_sctrl_read(gen->io.ports, context->current_cycle); |
965 break; | 985 break; |
966 case 0xD: | 986 case 0xD: |
967 value = gen->io.ports[2].serial_out; | 987 value = gen->io.ports[2].serial_out; |
968 break; | 988 break; |
969 case 0xE: | 989 case 0xE: |
970 value = gen->io.ports[2].serial_in; | 990 value = io_rx_read(gen->io.ports + 1, context->current_cycle); |
971 break; | 991 break; |
972 case 0xF: | 992 case 0xF: |
973 value = gen->io.ports[2].serial_ctrl; | 993 value = io_sctrl_read(gen->io.ports, context->current_cycle); |
974 break; | 994 break; |
975 default: | 995 default: |
976 value = get_open_bus_value(&gen->header) >> 8; | 996 value = get_open_bus_value(&gen->header) >> 8; |
977 } | 997 } |
978 } else { | 998 } else { |