From f56e1bafa2c3b43611bcc5432828d1bb0429ab66 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Sun, 19 Feb 2023 12:16:20 +0100 Subject: [PATCH] have two different functions to set PC in r4300i, for word and dword + set the initial PC after PIF HLE instead of Registers constructor --- src/backend/core/dynarec/cop/cop0instructions.cpp | 4 ++-- src/backend/core/dynarec/instructions.cpp | 2 +- src/backend/core/interpreter/cop/cop0instructions.cpp | 4 ++-- src/backend/core/interpreter/instructions.cpp | 2 +- src/backend/core/mmio/PIF.cpp | 1 + src/backend/core/registers/Cop0.cpp | 8 ++++---- src/backend/core/registers/Registers.cpp | 11 +++++++---- src/backend/core/registers/Registers.hpp | 3 ++- 8 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/backend/core/dynarec/cop/cop0instructions.cpp b/src/backend/core/dynarec/cop/cop0instructions.cpp index 76c20f75..1e2e0bc5 100644 --- a/src/backend/core/dynarec/cop/cop0instructions.cpp +++ b/src/backend/core/dynarec/cop/cop0instructions.cpp @@ -21,10 +21,10 @@ void dmfc0(n64::Registers& regs, u32 instr) { void eret(n64::Registers& regs) { if(regs.cop0.status.erl) { - regs.SetPC(regs.cop0.ErrorEPC); + regs.SetPC64(regs.cop0.ErrorEPC); regs.cop0.status.erl = false; } else { - regs.SetPC(regs.cop0.EPC); + regs.SetPC64(regs.cop0.EPC); regs.cop0.status.exl = false; } regs.cop0.llbit = false; diff --git a/src/backend/core/dynarec/instructions.cpp b/src/backend/core/dynarec/instructions.cpp index 8beb8364..e0afa442 100644 --- a/src/backend/core/dynarec/instructions.cpp +++ b/src/backend/core/dynarec/instructions.cpp @@ -164,7 +164,7 @@ void branch_likely(Registers& regs, bool cond, s64 address) { if (cond) { regs.nextPC = address; } else { - regs.SetPC(regs.nextPC); + regs.SetPC64(regs.nextPC); } } diff --git a/src/backend/core/interpreter/cop/cop0instructions.cpp b/src/backend/core/interpreter/cop/cop0instructions.cpp index 84c4586b..8fde8b2a 100644 --- a/src/backend/core/interpreter/cop/cop0instructions.cpp +++ b/src/backend/core/interpreter/cop/cop0instructions.cpp @@ -21,10 +21,10 @@ void Cop0::dmfc0(Registers& regs, u32 instr) { void Cop0::eret(Registers& regs) { if(status.erl) { - regs.SetPC(ErrorEPC); + regs.SetPC64(ErrorEPC); status.erl = false; } else { - regs.SetPC(EPC); + regs.SetPC64(EPC); status.exl = false; } llbit = false; diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index 32760aee..6ff68364 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -163,7 +163,7 @@ void Interpreter::branch_likely(bool cond, s64 address) { if (cond) { regs.nextPC = address; } else { - regs.SetPC(regs.nextPC); + regs.SetPC64(regs.nextPC); } } diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 5378e90e..8ec5c6d0 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -333,6 +333,7 @@ void DoPIFHLE(Mem& mem, Registers& regs, CartInfo cartInfo) { regs.gpr[22] = (cicSeeds[cicType] >> 8) & 0xFF; regs.cop0.Reset(); mem.Write32(regs, 0x04300004, 0x01010101); + regs.SetPC32(0xA4000040); } void ExecutePIF(Mem& mem, Registers& regs, CartInfo cartInfo) { diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 9a495962..1bd97bf0 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -274,15 +274,15 @@ void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC) case ExceptionCode::ReservedInstruction: case ExceptionCode::CoprocessorUnusable: case ExceptionCode::Overflow: case ExceptionCode::Trap: case ExceptionCode::FloatingPointError: case ExceptionCode::Watch: - regs.SetPC(s64(s32(0x80000180))); + regs.SetPC32(0x80000180); break; case ExceptionCode::TLBLoad: case ExceptionCode::TLBStore: if(old_exl || regs.cop0.tlbError == INVALID) { - regs.SetPC(s64(s32(0x80000180))); + regs.SetPC32(0x80000180); } else if(Is64BitAddressing(regs.cop0, regs.cop0.badVaddr)) { - regs.SetPC(s64(s32(0x80000080))); + regs.SetPC32(0x80000080); } else { - regs.SetPC(s64(s32(0x80000000))); + regs.SetPC32(0x80000000); } break; default: Util::panic("Unhandled exception! {}\n", static_cast(code)); diff --git a/src/backend/core/registers/Registers.cpp b/src/backend/core/registers/Registers.cpp index fe5e3944..d96bc89a 100644 --- a/src/backend/core/registers/Registers.cpp +++ b/src/backend/core/registers/Registers.cpp @@ -9,14 +9,17 @@ void Registers::Reset() { delaySlot = false; prevDelaySlot = false; memset(gpr, 0, 32*sizeof(s64)); - oldPC = (s64)0xFFFFFFFFA4000040; - pc = oldPC; - nextPC = pc + 4; } -void Registers::SetPC(s64 val) { +void Registers::SetPC64(s64 val) { oldPC = pc; pc = val; nextPC = pc + 4; } + +void Registers::SetPC32(s32 val) { + oldPC = pc; + pc = s64(val); + nextPC = pc + 4; +} } diff --git a/src/backend/core/registers/Registers.hpp b/src/backend/core/registers/Registers.hpp index 08c1f741..39f17be5 100644 --- a/src/backend/core/registers/Registers.hpp +++ b/src/backend/core/registers/Registers.hpp @@ -6,7 +6,8 @@ namespace n64 { struct Registers { Registers(); void Reset(); - void SetPC(s64); + void SetPC64(s64); + void SetPC32(s32); s64 gpr[32]; Cop0 cop0; Cop1 cop1;