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 {