diff --git a/parallel-rsp/parallel.cpp b/parallel-rsp/parallel.cpp index 69f0388..0f43ada 100644 --- a/parallel-rsp/parallel.cpp +++ b/parallel-rsp/parallel.cpp @@ -76,9 +76,6 @@ extern "C" EXPORT unsigned int CALL DoRspCycles(unsigned int first_run) { - if (*RSP::rsp.SP_STATUS_REG & (SP_STATUS_HALT | SP_STATUS_BROKE)) - return 0; - // We don't know if Mupen from the outside invalidated our IMEM. if (first_run) RSP::cpu.invalidate_imem(); @@ -103,10 +100,7 @@ extern "C" break; } - *RSP::rsp.SP_PC_REG = 0x04001000 | (RSP::cpu.get_state().pc & 0xffc); - *RSP::rsp.SP_DMA_BUSY_REG = 0; - *RSP::rsp.SP_DMA_FULL_REG = 0; - *RSP::rsp.SP_STATUS_REG &= ~(SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL); + *RSP::rsp.SP_PC_REG = (RSP::cpu.get_state().pc & 0xffc); // From CXD4. if (*RSP::rsp.SP_STATUS_REG & SP_STATUS_BROKE) diff --git a/parallel-rsp/rsp/cp0.cpp b/parallel-rsp/rsp/cp0.cpp index 4df1f13..c5abb31 100644 --- a/parallel-rsp/rsp/cp0.cpp +++ b/parallel-rsp/rsp/cp0.cpp @@ -52,6 +52,46 @@ extern "C" return MODE_CONTINUE; } + static inline void rdp_status_write(RSP::CPUState *rsp, uint32_t rt) + { + uint32_t status = *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS]; + if (rt & DPC_CLR_XBUS_DMEM_DMA) + status &= ~DPC_STATUS_XBUS_DMEM_DMA; + else if (rt & DPC_SET_XBUS_DMEM_DMA) + status |= DPC_STATUS_XBUS_DMEM_DMA; + + if (rt & DPC_CLR_FREEZE) + status &= ~DPC_STATUS_FREEZE; + else if (rt & DPC_SET_FREEZE) + status |= DPC_STATUS_FREEZE; + + if (rt & DPC_CLR_FLUSH) + status &= ~DPC_STATUS_FLUSH; + else if (rt & DPC_SET_FLUSH) + status |= DPC_STATUS_FLUSH; + + if (rt & DPC_CLR_TMEM_CTR) + { + status &= ~DPC_STATUS_TMEM_BUSY; + *rsp->cp0.cr[CP0_REGISTER_CMD_TMEM_BUSY] = 0; + } + if (rt & DPC_CLR_PIPE_CTR) + { + status &= ~DPC_STATUS_PIPE_BUSY; + *rsp->cp0.cr[CP0_REGISTER_CMD_PIPE_BUSY] = 0; + } + if (rt & DPC_CLR_CMD_CTR) + { + status &= ~DPC_STATUS_CMD_BUSY; + *rsp->cp0.cr[CP0_REGISTER_CMD_BUSY] = 0; + } + + if (rt & DPC_CLR_CLOCK_CTR) + *rsp->cp0.cr[CP0_REGISTER_CMD_CLOCK] = 0; + + *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] = status; + } + static inline int rsp_status_write(RSP::CPUState *rsp, uint32_t rt) { //fprintf(stderr, "Writing 0x%x to status reg!\n", rt); @@ -278,18 +318,25 @@ extern "C" case CP0_REGISTER_CMD_START: #ifdef INTENSE_DEBUG - fprintf(stderr, "CMD_START 0x%x\n", val & 0xfffffff8u); + fprintf(stderr, "CMD_START 0x%x\n", val & 0xfffff8u); #endif - *rsp->cp0.cr[CP0_REGISTER_CMD_START] = *rsp->cp0.cr[CP0_REGISTER_CMD_CURRENT] = - *rsp->cp0.cr[CP0_REGISTER_CMD_END] = val & 0xfffffff8u; + if (!(*rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] & DPC_STATUS_START_VALID)) + { + *rsp->cp0.cr[CP0_REGISTER_CMD_START] = val & 0xfffff8u; + } + *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] |= DPC_STATUS_START_VALID; break; case CP0_REGISTER_CMD_END: #ifdef INTENSE_DEBUG - fprintf(stderr, "CMD_END 0x%x\n", val & 0xfffffff8u); + fprintf(stderr, "CMD_END 0x%x\n", val & 0xfffff8u); #endif - *rsp->cp0.cr[CP0_REGISTER_CMD_END] = val & 0xfffffff8u; - + *rsp->cp0.cr[CP0_REGISTER_CMD_END] = val & 0xfffff8u; + if (*rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] & DPC_STATUS_START_VALID) + { + *rsp->cp0.cr[CP0_REGISTER_CMD_CURRENT] = *rsp->cp0.cr[CP0_REGISTER_CMD_START]; + *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] &= ~DPC_STATUS_START_VALID; + } #ifdef PARALLEL_INTEGRATION RSP::rsp.ProcessRdpList(); #endif @@ -300,14 +347,7 @@ extern "C" break; case CP0_REGISTER_CMD_STATUS: - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] &= ~(!!(val & 0x1) << 0); - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] |= (!!(val & 0x2) << 0); - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] &= ~(!!(val & 0x4) << 1); - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] |= (!!(val & 0x8) << 1); - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] &= ~(!!(val & 0x10) << 2); - *rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] |= (!!(val & 0x20) << 2); - *rsp->cp0.cr[CP0_REGISTER_CMD_TMEM_BUSY] &= !(val & 0x40) * -1; - *rsp->cp0.cr[CP0_REGISTER_CMD_CLOCK] &= !(val & 0x200) * -1; + rdp_status_write(rsp, val); break; case CP0_REGISTER_CMD_CURRENT: diff --git a/parallel-rsp/state.hpp b/parallel-rsp/state.hpp index afb2ab0..dba036e 100644 --- a/parallel-rsp/state.hpp +++ b/parallel-rsp/state.hpp @@ -48,6 +48,31 @@ enum CP0Registers CP0_REGISTER_CMD_TMEM_BUSY = 15, }; +// CMD_STATUS read bits. +#define DPC_STATUS_XBUS_DMEM_DMA 0x001 +#define DPC_STATUS_FREEZE 0x002 +#define DPC_STATUS_FLUSH 0x004 +#define DPC_STATUS_START_GCLK 0x008 +#define DPC_STATUS_TMEM_BUSY 0x010 +#define DPC_STATUS_PIPE_BUSY 0x020 +#define DPC_STATUS_CMD_BUSY 0x040 +#define DPC_STATUS_CBUF_READY 0x080 +#define DPC_STATUS_DMA_BUSY 0x100 +#define DPC_STATUS_END_VALID 0x200 +#define DPC_STATUS_START_VALID 0x400 + +// CMD_STATUS write bits. +#define DPC_CLR_XBUS_DMEM_DMA 0x001 +#define DPC_SET_XBUS_DMEM_DMA 0x002 +#define DPC_CLR_FREEZE 0x004 +#define DPC_SET_FREEZE 0x008 +#define DPC_CLR_FLUSH 0x010 +#define DPC_SET_FLUSH 0x020 +#define DPC_CLR_TMEM_CTR 0x040 +#define DPC_CLR_PIPE_CTR 0x080 +#define DPC_CLR_CMD_CTR 0x100 +#define DPC_CLR_CLOCK_CTR 0x200 + // SP_STATUS read bits. #define SP_STATUS_HALT 0x0001 #define SP_STATUS_BROKE 0x0002