diff --git a/parallel-rsp/parallel.cpp b/parallel-rsp/parallel.cpp index 396361e..1ca7a5b 100644 --- a/parallel-rsp/parallel.cpp +++ b/parallel-rsp/parallel.cpp @@ -43,8 +43,6 @@ RSP::CPU cpu; #else RSP::JIT::CPU cpu; #endif -uint32_t MFC0_count[32]; -uint32_t SP_STATUS_TIMEOUT; } // namespace RSP extern "C" @@ -86,15 +84,13 @@ extern "C" // Run CPU until we either break or we need to fire an IRQ. RSP::cpu.get_state().pc = *RSP::rsp.SP_PC_REG & 0xfff; RSP::cpu.get_state().instruction_count = 0; + RSP::cpu.get_state().did_mfc0 = 0; #ifdef INTENSE_DEBUG fprintf(stderr, "RUN TASK: %u\n", RSP::cpu.get_state().pc); log_rsp_mem_parallel(); #endif - for (auto &count : RSP::MFC0_count) - count = 0; - while (!(*RSP::rsp.SP_STATUS_REG & SP_STATUS_HALT)) { auto mode = RSP::cpu.run(); @@ -106,12 +102,6 @@ extern "C" *RSP::rsp.SP_PC_REG = (RSP::cpu.get_state().pc & 0xffc); - // From CXD4. - if (*RSP::rsp.SP_STATUS_REG & SP_STATUS_BROKE) - return RSP::cpu.get_state().instruction_count * 1.5; // Converting RCP clock rate to CPU clock rate - else if (*RSP::cpu.get_state().cp0.irq & 1) - RSP::rsp.CheckInterrupts(); - return RSP::cpu.get_state().instruction_count * 1.5; // Converting RCP clock rate to CPU clock rate } @@ -174,9 +164,6 @@ extern "C" *cr[RSP::CP0_REGISTER_SP_STATUS] = SP_STATUS_HALT; RSP::cpu.get_state().cp0.irq = RSP::rsp.MI_INTR_REG; - // From CXD4. - RSP::SP_STATUS_TIMEOUT = 256; - RSP::cpu.set_dmem(reinterpret_cast(Rsp_Info.DMEM)); RSP::cpu.set_imem(reinterpret_cast(Rsp_Info.IMEM)); RSP::cpu.set_rdram(reinterpret_cast(Rsp_Info.RDRAM)); diff --git a/parallel-rsp/rsp/cp0.cpp b/parallel-rsp/rsp/cp0.cpp index 55cdc9a..b3b683a 100644 --- a/parallel-rsp/rsp/cp0.cpp +++ b/parallel-rsp/rsp/cp0.cpp @@ -6,8 +6,6 @@ namespace RSP { extern RSP_INFO rsp; -extern uint32_t MFC0_count[32]; -extern uint32_t SP_STATUS_TIMEOUT; } // namespace RSP #endif @@ -29,20 +27,19 @@ extern "C" #ifdef PARALLEL_INTEGRATION // WAIT_FOR_CPU_HOST. From CXD4. - if (rd == CP0_REGISTER_SP_STATUS) + if (rd == CP0_REGISTER_SP_RESERVED) { - --rsp->instruction_count; // Some games check the STATUS reg more than normal since we don't really yield properly - RSP::MFC0_count[rt] += 1; - } - else if (rd == CP0_REGISTER_SP_RESERVED) - { - rsp->instruction_count += 2; // Needed for DK64 - RSP::MFC0_count[rt] += 1; + rsp->instruction_count += 4; // Needed for DK64 *rsp->cp0.cr[CP0_REGISTER_SP_RESERVED] = 1; + rsp->did_mfc0 = 1; + return MODE_EXIT; } // We don't return control to the CPU if the RDP FREEZE bit is set, doing so seems to cause flickering - if (RSP::MFC0_count[rt] >= RSP::SP_STATUS_TIMEOUT && (*rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] & DPC_STATUS_FREEZE) == 0) + else if (rd == CP0_REGISTER_SP_STATUS && (*rsp->cp0.cr[CP0_REGISTER_CMD_STATUS] & DPC_STATUS_FREEZE) == 0) + { + rsp->did_mfc0 = 1; return MODE_EXIT; + } #endif //if (rd == 4) // SP_STATUS_REG diff --git a/parallel-rsp/rsp_jit.cpp b/parallel-rsp/rsp_jit.cpp index 56af17f..221f5ac 100644 --- a/parallel-rsp/rsp_jit.cpp +++ b/parallel-rsp/rsp_jit.cpp @@ -909,7 +909,11 @@ void CPU::jit_instruction(jit_state_t *_jit, uint32_t pc, uint32_t instr, auto *vuop = ops[op]; if (!vuop) + { + printf("UNKNOWN RSP VU COMMAND %u\n", op); + exit(1); vuop = RSP_RESERVED; + } regs.flush_caller_save_registers(_jit); jit_begin_call(_jit); @@ -1731,6 +1735,8 @@ void CPU::jit_instruction(jit_state_t *_jit, uint32_t pc, uint32_t instr, } default: + printf("UNKNOWN RSP SU COMMAND %o\n", type); + exit(1); break; } } @@ -1967,8 +1973,6 @@ ReturnMode CPU::run() { case MODE_BREAK: *state.cp0.cr[CP0_REGISTER_SP_STATUS] |= SP_STATUS_BROKE | SP_STATUS_HALT; - if (*state.cp0.cr[CP0_REGISTER_SP_STATUS] & SP_STATUS_INTR_BREAK) - *state.cp0.irq |= 1; #ifndef PARALLEL_INTEGRATION print_registers(); #endif @@ -1980,7 +1984,10 @@ ReturnMode CPU::run() return static_cast(ret); default: - break; + if (state.did_mfc0) + return static_cast(MODE_EXIT); + else + break; } } } diff --git a/parallel-rsp/state.hpp b/parallel-rsp/state.hpp index 90de304..9e4ea88 100644 --- a/parallel-rsp/state.hpp +++ b/parallel-rsp/state.hpp @@ -144,6 +144,7 @@ struct CPUState uint32_t pc = 0; uint32_t instruction_count = 0; uint32_t last_instruction_type = 0; + uint32_t did_mfc0 = 0; uint32_t dirty_blocks = 0; static_assert(CODE_BLOCKS <= 32, "Code blocks must fit in 32-bit register.");