diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 27acd69a..b79a6555 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -375,7 +375,17 @@ FORCE_INLINE bool Is64BitAddressing(const Cop0 &cp0, const u64 addr) { void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) { Registers& regs = Core::GetRegs(); - const bool old_exl = status.exl; + + u16 vectorOffset = 0x0180; + if(tlbError == MISS && (code == ExceptionCode::TLBLoad || code == ExceptionCode::TLBStore)) { + if(!status.exl) { + if(Is64BitAddressing(*this, badVaddr)) vectorOffset = 0x0080; + else vectorOffset = 0x0000; + } + } + + cause.copError = cop; + cause.exceptionCode = static_cast(code); if (!status.exl) { if ((cause.branchDelay = regs.prevDelaySlot)) { @@ -386,45 +396,12 @@ void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) { EPC = pc; } - cause.copError = cop; - cause.exceptionCode = static_cast(code); - if (status.bev) { panic("BEV bit set!"); - } else { - switch (code) { - case ExceptionCode::Interrupt: - case ExceptionCode::TLBModification: - case ExceptionCode::AddressErrorLoad: - case ExceptionCode::AddressErrorStore: - case ExceptionCode::InstructionBusError: - case ExceptionCode::DataBusError: - case ExceptionCode::Syscall: - case ExceptionCode::Breakpoint: - case ExceptionCode::ReservedInstruction: - case ExceptionCode::CoprocessorUnusable: - case ExceptionCode::Overflow: - case ExceptionCode::Trap: - case ExceptionCode::FloatingPointError: - case ExceptionCode::Watch: - regs.SetPC32(s32(0x80000180)); - break; - case ExceptionCode::TLBLoad: - case ExceptionCode::TLBStore: - if (old_exl || regs.cop0.tlbError == INVALID) { - regs.SetPC32(s32(0x80000180)); - } else if (Is64BitAddressing(regs.cop0, regs.cop0.badVaddr)) { - regs.SetPC32(s32(0x80000080)); - } else { - regs.SetPC32(s32(0x80000000)); - } - break; - default: - panic("Unhandled exception! {}", static_cast(code)); - } } - regs.cop0.Update(); + regs.SetPC32(s32(0x80000000 + vectorOffset)); + Update(); } void Cop0::HandleTLBException(const u64 vaddr) {