void smpc_init(void) { irq_mux_t *vbo; uint32_t mask; /* Set both ports to "SMPC" control mode. */ MEMORY_WRITE(8, SMPC(EXLE1), 0x00); MEMORY_WRITE(8, SMPC(IOSEL1), 0x00); MEMORY_WRITE(8, SMPC(DDR1), 0x00); MEMORY_WRITE(8, SMPC(PDR1), 0x00); /* Disable interrupts */ cpu_intc_disable(); mask = IC_MASK_SYSTEM_MANAGER | IC_MASK_TIMER_0; scu_ic_mask_chg(IC_MASK_ALL, mask); scu_ic_interrupt_set(IC_INTERRUPT_TIMER_0, &smpc_peripheral_data); scu_ic_interrupt_set(IC_INTERRUPT_SYSTEM_MANAGER, &smpc_peripheral_system_manager); scu_ic_mask_chg(IC_MASK_ALL & ~mask, IC_MASK_NONE); scu_timer_0_set(5); scu_timer_1_set(0); scu_timer_1_mode_set(/* sp_line = */ true); /* Add to VDP2 VBLANK-OUT mux */ vbo = vdp2_tvmd_vblank_out_irq_get(); irq_mux_handle_add(vbo, smpc_peripheral_parse, NULL); /* Enable interrupts */ cpu_intc_enable(); }
static void handler_system_manager(void) { static uint32_t offset = 0; /* We don't have much time in the critical section. Just * buffer the registers */ uint32_t oreg; for (oreg = 0; oreg < SMPC_OREGS; oreg++, offset++) { OREG_SET(offset, MEMORY_READ(8, OREG(oreg))); } uint8_t sr; sr = MEMORY_READ(8, SMPC(SR)); if ((sr & 0x80) == 0x80) { if ((sr & NPE) == 0x00) { /* Mark that SMPC status and peripheral data * collection is complete */ _collection_complete = true; offset = 0; /* Issue a "BREAK" for the "INTBACK" command */ MEMORY_WRITE(8, IREG(0), BR); return; } } /* Issue a "CONTINUE" for the "INTBACK" command */ MEMORY_WRITE(8, IREG(0), CONT); }
void smpc_peripheral_init(void) { memb_init(&peripherals); smpc_peripheral_port_1.peripheral = peripheral_alloc(); TAILQ_INIT(&smpc_peripheral_port_1.peripherals); smpc_peripheral_port_2.peripheral = peripheral_alloc(); TAILQ_INIT(&smpc_peripheral_port_2.peripherals); /* Disablo interrupts */ cpu_intc_disable(); /* Set both ports to "SMPC" control mode */ MEMORY_WRITE(8, SMPC(EXLE1), 0x00); MEMORY_WRITE(8, SMPC(IOSEL1), 0x00); MEMORY_WRITE(8, SMPC(DDR1), 0x00); MEMORY_WRITE(8, SMPC(PDR1), 0x00); /* Send INTBACK at start of VBLANK-IN */ irq_mux_t *vblank_in; vblank_in = vdp2_tvmd_vblank_in_irq_get(); irq_mux_handle_add(vblank_in, irq_mux_vblank_in, NULL); /* Parse at start of VBLANK-OUT */ irq_mux_t *vblank_out; vblank_out = vdp2_tvmd_vblank_out_irq_get(); irq_mux_handle_add(vblank_out, irq_mux_vblank_out, NULL); uint32_t mask; mask = IC_MASK_SYSTEM_MANAGER; scu_ic_mask_chg(IC_MASK_ALL, mask); scu_ic_interrupt_set(IC_INTERRUPT_SYSTEM_MANAGER, &handler_system_manager); scu_ic_mask_chg(IC_MASK_ALL & ~mask, IC_MASK_NONE); /* Enable interrupts */ cpu_intc_enable(); }