diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 38a62de..f553bd2 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -65,11 +65,8 @@ void Core::LoadROM(const std::string &rom_) { } u32 Core::StepCPU() { - if (cpuType == Interpreted) { - auto taken = interpreter.Step() + regs.PopStalledCycles(); - StepRSP(taken); - return taken; - } + if (cpuType == Interpreted) + return interpreter.Step() + regs.PopStalledCycles(); if (cpuType == CachedInterpreter) return interpreter.ExecuteCached() + regs.PopStalledCycles(); @@ -85,12 +82,6 @@ u32 Core::StepCPU() { void Core::StepRSP(const u32 cpuCycles) { MMIO &mmio = mem->mmio; - if (mmio.rsp.spStatus.halt) { - regs.steps = 0; - mmio.rsp.steps = 0; - return; - } - static constexpr u32 cpuRatio = 3, rspRatio = 2; regs.steps += cpuCycles; @@ -119,8 +110,6 @@ void Core::Run(const float volumeL, const float volumeR) { } for (int cycles = 0; cycles < mem->mmio.vi.cyclesPerHalfline;) { - Scheduler::GetInstance().HandleEvents(); - const u32 taken = StepCPU(); cycles += taken; frameCycles += taken; diff --git a/src/backend/Scheduler.cpp b/src/backend/Scheduler.cpp index bb3db01..8356a98 100644 --- a/src/backend/Scheduler.cpp +++ b/src/backend/Scheduler.cpp @@ -27,13 +27,9 @@ u64 Scheduler::Remove(const EventType eventType) const { return ret; } -void Scheduler::SkipToNext() { - ticks = events.top().time; -} +void Scheduler::SkipToNext() { ticks = events.top().time; } -void Scheduler::Tick(const u64 t) { - ticks += t; -} +void Scheduler::Tick(const u64 t) { ticks += t; } void Scheduler::HandleEvents() { n64::Mem &mem = n64::Core::GetMem(); @@ -43,6 +39,9 @@ void Scheduler::HandleEvents() { while (ticks >= events.top().time) { switch (const auto type = events.top().type) { + case RSP_STEP: + n64::Core::GetInstance().StepRSP(1); + break; case SI_DMA: si.DMA(); break; diff --git a/src/backend/Scheduler.hpp b/src/backend/Scheduler.hpp index 51e43d5..0808a57 100644 --- a/src/backend/Scheduler.hpp +++ b/src/backend/Scheduler.hpp @@ -3,7 +3,7 @@ #include #include -enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE }; +enum EventType { NONE, RSP_STEP, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE }; struct Event { u64 time; diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 0e5573c..e248a1c 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -52,18 +52,6 @@ bool Interpreter::MaybeAdvance() { return false; } - regs.push_to_stack_trace(regs.pc); - if ((u32)regs.pc == 0x4) { - auto ®s = Core::GetRegs(); - std::sort(regs.stack_trace.begin(), regs.stack_trace.end()); - - std::println("Stack trace:"); - for (int i = 0; i < regs.stack_trace.size(); i++) { - std::println(" [{:016X}]", regs.stack_trace[i]); - } - exit(1); - } - regs.oldPC = regs.pc; regs.pc = regs.nextPC; regs.nextPC += 4; @@ -105,6 +93,14 @@ u32 Interpreter::Step() { DecodeExecute(instr); + if (!mem.mmio.rsp.spStatus.halt) { + rspSyncCount++; + if (rspSyncCount >= 3) + Scheduler::GetInstance().EnqueueRelative(0, RSP_STEP); + } + + Scheduler::GetInstance().HandleEvents(); + return 1; } @@ -142,7 +138,7 @@ void CachedState::EvictLine(u64 addr) { u32 Interpreter::ExecuteCached() { auto addr = regs.pc; - auto block_addr = addr; + auto blockAddr = addr; auto line = cachedState.GetLine(addr); if (line) { @@ -153,8 +149,7 @@ u32 Interpreter::ExecuteCached() { Instruction instr = line->code[i]; DecodeExecute(instr); - Core::GetInstance().StepRSP(1); - + Scheduler::GetInstance().HandleEvents(); // Branch likely with false condition, it wasn't taken so don't execute the delay slot if (IsBranchLikely(instr) && !regs.delaySlot) break; @@ -192,7 +187,16 @@ u32 Interpreter::ExecuteCached() { } } - cachedState.InsertLine(block_addr, std::make_shared(code, i, i)); + if (!mem.mmio.rsp.spStatus.halt) { + for (int j = 1; j <= (int)std::floor((double)i / 3); j++) { + Scheduler::GetInstance().EnqueueRelative(j * 3, RSP_STEP); + } + } else { + regs.steps = 0; + mem.mmio.rsp.steps = 0; + } + + cachedState.InsertLine(blockAddr, std::make_shared(code, i, i)); return ExecuteCached(); } diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 716a672..1f525d5 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -64,6 +64,7 @@ struct Interpreter final { Registers ®s; Mem &mem; u64 cop2Latch{}; + u32 rspSyncCount = 0; bool Fetch(Instruction &, u64); void CacheTypeData(u8, u64, u32, u32); diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index d7fe1c6..ac0a3cc 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -85,10 +85,7 @@ auto RSP::Read(const u32 addr) -> u32 { default: { auto ®s = Core::GetRegs(); - std::println("Stack trace:"); - for (int i = 0; i < regs.stack_trace.size(); i++) { - std::println(" [{:016X}]", regs.stack_trace[i]); - } + panic("Unimplemented SP register read {:08X} (cpu pc: 0x{:016X}, rsp pc: 0x{:04X}, ra: 0x{:016X})", addr, (u64)regs.oldPC, pc & 0xffc, (u64)regs.gpr[31]); } diff --git a/src/backend/core/registers/Registers.cpp b/src/backend/core/registers/Registers.cpp index 7543628..e5f6a21 100644 --- a/src/backend/core/registers/Registers.cpp +++ b/src/backend/core/registers/Registers.cpp @@ -6,10 +6,7 @@ namespace n64 { #ifdef KAIZEN_JIT_ENABLED Registers::Registers(JIT &jit) : jit(jit) { Reset(); } #else -Registers::Registers() { - stack_trace.resize(0x10000000); - Reset(); -} +Registers::Registers() { Reset(); } #endif void Registers::Reset() { @@ -17,7 +14,6 @@ void Registers::Reset() { lo = 0; delaySlot = false; prevDelaySlot = false; - std::fill(stack_trace.begin(), stack_trace.end(), 0); gpr.fill(0); regIsConstant = 1; // first bit is true indicating $zero is constant which yes it is always diff --git a/src/backend/core/registers/Registers.hpp b/src/backend/core/registers/Registers.hpp index 1c28569..f137b34 100644 --- a/src/backend/core/registers/Registers.hpp +++ b/src/backend/core/registers/Registers.hpp @@ -48,14 +48,6 @@ struct Registers { Cop0 cop0; Cop1 cop1; - std::vector stack_trace; - int stack_count = 0; - - void push_to_stack_trace(s64 val) { - stack_trace[stack_count++] = val; - stack_count %= stack_trace.size(); - } - void CpuStall(u32 cycles) { extraCycles += cycles; } u32 PopStalledCycles() {