int write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { struct rdp_core* dp = (struct rdp_core*)opaque; uint32_t reg = dpc_reg(address); switch(reg) { case DPC_STATUS_REG: if (update_dpc_status(dp, value & mask) != 0) do_SP_Task(dp->sp); case DPC_CURRENT_REG: case DPC_CLOCK_REG: case DPC_BUFBUSY_REG: case DPC_PIPEBUSY_REG: case DPC_TMEM_REG: return 0; } masked_write(&dp->dpc_regs[reg], value, mask); switch(reg) { case DPC_START_REG: dp->dpc_regs[DPC_CURRENT_REG] = dp->dpc_regs[DPC_START_REG]; break; case DPC_END_REG: gfx.processRDPList(); signal_rcp_interrupt(dp->r4300, MI_INTR_DP); break; } return 0; }
static void update_sp_status(struct rsp_core* sp, uint32_t w) { /* clear / set halt */ if (w & 0x1) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_HALT; if (w & 0x2) sp->regs[SP_STATUS_REG] |= SP_STATUS_HALT; /* clear broke */ if (w & 0x4) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_BROKE; /* clear SP interrupt */ if (w & 0x8) { clear_rcp_interrupt(sp->r4300, MI_INTR_SP); } /* set SP interrupt */ if (w & 0x10) { signal_rcp_interrupt(sp->r4300, MI_INTR_SP); } /* clear / set single step */ if (w & 0x20) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SSTEP; if (w & 0x40) sp->regs[SP_STATUS_REG] |= SP_STATUS_SSTEP; /* clear / set interrupt on break */ if (w & 0x80) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_INTR_BREAK; if (w & 0x100) sp->regs[SP_STATUS_REG] |= SP_STATUS_INTR_BREAK; /* clear / set signal 0 */ if (w & 0x200) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG0; if (w & 0x400) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG0; /* clear / set signal 1 */ if (w & 0x800) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG1; if (w & 0x1000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG1; /* clear / set signal 2 */ if (w & 0x2000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG2; if (w & 0x4000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG2; /* clear / set signal 3 */ if (w & 0x8000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG3; if (w & 0x10000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG3; /* clear / set signal 4 */ if (w & 0x20000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG4; if (w & 0x40000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG4; /* clear / set signal 5 */ if (w & 0x80000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG5; if (w & 0x100000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG5; /* clear / set signal 6 */ if (w & 0x200000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG6; if (w & 0x400000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG6; /* clear / set signal 7 */ if (w & 0x800000) sp->regs[SP_STATUS_REG] &= ~SP_STATUS_SIG7; if (w & 0x1000000) sp->regs[SP_STATUS_REG] |= SP_STATUS_SIG7; //if (get_event(SP_INT)) return; if (!(w & 0x1) && !(w & 0x4)) return; if (!(sp->regs[SP_STATUS_REG] & (SP_STATUS_HALT | SP_STATUS_BROKE))) do_SP_Task(sp); }
static void update_sp_status(struct rsp_core* sp, uint32_t w) { /* clear / set halt */ if (w & 0x1) sp->regs[SP_STATUS_REG] &= ~0x1; if (w & 0x2) sp->regs[SP_STATUS_REG] |= 0x1; /* clear broke */ if (w & 0x4) sp->regs[SP_STATUS_REG] &= ~0x2; /* clear SP interrupt */ if (w & 0x8) { clear_rcp_interrupt(sp->r4300, MI_INTR_SP); } /* set SP interrupt */ if (w & 0x10) { signal_rcp_interrupt(sp->r4300, MI_INTR_SP); } /* clear / set single step */ if (w & 0x20) sp->regs[SP_STATUS_REG] &= ~0x20; if (w & 0x40) sp->regs[SP_STATUS_REG] |= 0x20; /* clear / set interrupt on break */ if (w & 0x80) sp->regs[SP_STATUS_REG] &= ~0x40; if (w & 0x100) sp->regs[SP_STATUS_REG] |= 0x40; /* clear / set signal 0 */ if (w & 0x200) sp->regs[SP_STATUS_REG] &= ~0x80; if (w & 0x400) sp->regs[SP_STATUS_REG] |= 0x80; /* clear / set signal 1 */ if (w & 0x800) sp->regs[SP_STATUS_REG] &= ~0x100; if (w & 0x1000) sp->regs[SP_STATUS_REG] |= 0x100; /* clear / set signal 2 */ if (w & 0x2000) sp->regs[SP_STATUS_REG] &= ~0x200; if (w & 0x4000) sp->regs[SP_STATUS_REG] |= 0x200; /* clear / set signal 3 */ if (w & 0x8000) sp->regs[SP_STATUS_REG] &= ~0x400; if (w & 0x10000) sp->regs[SP_STATUS_REG] |= 0x400; /* clear / set signal 4 */ if (w & 0x20000) sp->regs[SP_STATUS_REG] &= ~0x800; if (w & 0x40000) sp->regs[SP_STATUS_REG] |= 0x800; /* clear / set signal 5 */ if (w & 0x80000) sp->regs[SP_STATUS_REG] &= ~0x1000; if (w & 0x100000) sp->regs[SP_STATUS_REG] |= 0x1000; /* clear / set signal 6 */ if (w & 0x200000) sp->regs[SP_STATUS_REG] &= ~0x2000; if (w & 0x400000) sp->regs[SP_STATUS_REG] |= 0x2000; /* clear / set signal 7 */ if (w & 0x800000) sp->regs[SP_STATUS_REG] &= ~0x4000; if (w & 0x1000000) sp->regs[SP_STATUS_REG] |= 0x4000; //if (get_event(SP_INT)) return; if (!(w & 0x1) && !(w & 0x4)) return; if (!(sp->regs[SP_STATUS_REG] & 0x3)) // !halt && !broke do_SP_Task(sp); }