From a2981ff4d89d2378f5d1d1b107e6be91fb64fd21 Mon Sep 17 00:00:00 2001 From: zilmar Date: Mon, 19 Sep 2022 21:36:36 +0930 Subject: [PATCH] Core: Make Load/Store use 64bit vaddr --- .../N64System/Interpreter/InterpreterOps.cpp | 74 +++++----- .../N64System/Interpreter/InterpreterOps.h | 6 +- .../N64System/Mips/MemoryVirtualMem.cpp | 126 ++++++++++-------- .../N64System/Mips/MemoryVirtualMem.h | 16 +-- .../N64System/Mips/Register.cpp | 33 ++--- .../Project64-core/N64System/Mips/Register.h | 40 +++++- Source/Project64-core/N64System/N64System.cpp | 8 +- .../Debugger/Debugger-RegisterTabs.cpp | 4 +- 8 files changed, 186 insertions(+), 121 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 95710c374..9624d8bda 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -1009,7 +1009,7 @@ int32_t LDL_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; void R4300iOp::LDL() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t MemoryValue; if (g_MMU->LD_Memory((Address & ~7), MemoryValue)) { @@ -1027,7 +1027,7 @@ int32_t LDR_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 }; void R4300iOp::LDR() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t MemoryValue; if (g_MMU->LD_Memory((Address & ~7), MemoryValue)) { @@ -1039,7 +1039,7 @@ void R4300iOp::LDR() void R4300iOp::LB() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint8_t MemoryValue; if (g_MMU->LB_Memory(Address, MemoryValue)) { @@ -1049,7 +1049,7 @@ void R4300iOp::LB() void R4300iOp::LH() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint16_t MemoryValue; if (g_MMU->LH_Memory(Address, MemoryValue)) { @@ -1059,7 +1059,9 @@ void R4300iOp::LH() void R4300iOp::LWL() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->LW_Memory((Address & ~3), MemoryValue)) { uint32_t Offset = Address & 3; @@ -1070,7 +1072,9 @@ void R4300iOp::LWL() void R4300iOp::LW() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->LW_Memory(Address, MemoryValue)) { _GPR[m_Opcode.rt].DW = (int32_t)MemoryValue; @@ -1079,7 +1083,7 @@ void R4300iOp::LW() void R4300iOp::LBU() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint8_t MemoryValue; if (g_MMU->LB_Memory(Address, MemoryValue)) { @@ -1089,7 +1093,7 @@ void R4300iOp::LBU() void R4300iOp::LHU() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint16_t MemoryValue; if (g_MMU->LH_Memory(Address, MemoryValue)) { @@ -1099,7 +1103,9 @@ void R4300iOp::LHU() void R4300iOp::LWR() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->LW_Memory((Address & ~3), MemoryValue)) { uint32_t Offset = Address & 3; @@ -1110,7 +1116,9 @@ void R4300iOp::LWR() void R4300iOp::LWU() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->LW_Memory(Address, MemoryValue)) { _GPR[m_Opcode.rt].UDW = MemoryValue; @@ -1119,19 +1127,21 @@ void R4300iOp::LWU() void R4300iOp::SB() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SB_Memory(Address, _GPR[m_Opcode.rt].UW[0]); } void R4300iOp::SH() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SH_Memory(Address, _GPR[m_Opcode.rt].UW[0]); } void R4300iOp::SWL() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->MemoryValue32(Address & ~3, MemoryValue)) { uint32_t Offset = Address & 3; @@ -1147,7 +1157,7 @@ void R4300iOp::SWL() void R4300iOp::SW() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SW_Memory(Address, _GPR[m_Opcode.rt].UW[0]); } @@ -1163,7 +1173,7 @@ int32_t SDL_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 }; void R4300iOp::SDL() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t MemoryValue; if (g_MMU->MemoryValue64((Address & ~7), MemoryValue)) { @@ -1191,7 +1201,7 @@ int32_t SDR_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 }; void R4300iOp::SDR() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; uint64_t MemoryValue; if (g_MMU->MemoryValue64((Address & ~7), MemoryValue)) { @@ -1208,7 +1218,9 @@ void R4300iOp::SDR() void R4300iOp::SWR() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->MemoryValue32((Address & ~3), MemoryValue)) { uint32_t Offset = Address & 3; @@ -1234,7 +1246,9 @@ void R4300iOp::CACHE() void R4300iOp::LL() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; + uint32_t MemoryValue; + if (g_MMU->LW_Memory(Address, MemoryValue)) { _GPR[m_Opcode.rt].DW = (int32_t)MemoryValue; @@ -1251,7 +1265,7 @@ void R4300iOp::LWC1() void R4300iOp::SC() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; if ((*_LLBit) != 1 || g_MMU->SW_Memory(Address, _GPR[m_Opcode.rt].UW[0])) { _GPR[m_Opcode.rt].UW[0] = (*_LLBit); @@ -1260,7 +1274,7 @@ void R4300iOp::SC() void R4300iOp::LD() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; if (g_MMU->LD_Memory(Address, _GPR[m_Opcode.rt].UDW)) { #ifdef Interpreter_StackTest @@ -1275,7 +1289,7 @@ void R4300iOp::LD() void R4300iOp::LDC1() { TEST_COP1_USABLE_EXCEPTION(); - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]); } @@ -1283,20 +1297,20 @@ void R4300iOp::SWC1() { TEST_COP1_USABLE_EXCEPTION(); - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]); } void R4300iOp::SDC1() { TEST_COP1_USABLE_EXCEPTION(); - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SD_Memory(Address, *((uint64_t *)_FPR_D[m_Opcode.ft])); } void R4300iOp::SD() { - uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset; + uint64_t Address = _GPR[m_Opcode.base].DW + (int16_t)m_Opcode.offset; g_MMU->SD_Memory(Address, _GPR[m_Opcode.rt].UDW); } @@ -1945,7 +1959,7 @@ void R4300iOp::COP0_DMF() void R4300iOp::COP0_MT() { - g_Reg->Cop0_MT(m_Opcode.rd, _GPR[m_Opcode.rt].UW[0]); + g_Reg->Cop0_MT(m_Opcode.rd, (int64_t)_GPR[m_Opcode.rt].W[0]); } void R4300iOp::COP0_DMT() @@ -2669,7 +2683,7 @@ bool R4300iOp::MemoryBreakpoint() return false; } -void R4300iOp::GenerateAddressErrorException(uint32_t VAddr, bool FromRead) +void R4300iOp::GenerateAddressErrorException(uint64_t VAddr, bool FromRead) { g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr, FromRead); g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; @@ -2683,22 +2697,22 @@ void R4300iOp::GenerateOverflowException(void) g_System->m_JumpToLocation = (*_PROGRAM_COUNTER); } -void R4300iOp::GenerateTLBReadException(uint32_t VAddr, const char * function) +void R4300iOp::GenerateTLBReadException(uint64_t VAddr, const char * function) { if (bShowTLBMisses()) { - g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, VAddr).c_str()); + g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, (uint32_t)VAddr).c_str()); } g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr); g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER); } -void R4300iOp::GenerateTLBWriteException(uint32_t VAddr, const char * function) +void R4300iOp::GenerateTLBWriteException(uint64_t VAddr, const char * function) { if (bShowTLBMisses()) { - g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, VAddr).c_str()); + g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, (uint32_t)VAddr).c_str()); } g_Reg->DoTLBWriteMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr); g_System->m_PipelineStage = PIPELINE_STAGE_JUMP; diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 2e5a38aab..5acc17fab 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -243,10 +243,10 @@ protected: static Func Jump_CoP1_W[64]; static Func Jump_CoP1_L[64]; - static void GenerateAddressErrorException(uint32_t VAddr, bool FromRead); + static void GenerateAddressErrorException(uint64_t VAddr, bool FromRead); static void GenerateOverflowException(void); - static void GenerateTLBReadException(uint32_t VAddr, const char * function); - static void GenerateTLBWriteException(uint32_t VAddr, const char * function); + static void GenerateTLBReadException(uint64_t VAddr, const char * function); + static void GenerateTLBWriteException(uint64_t VAddr, const char * function); static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4]; static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4]; diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index aefe914c0..60b2154e0 100755 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -377,202 +377,218 @@ bool CMipsMemoryVM::UpdateMemoryValue32(uint32_t VAddr, uint32_t Value) return true; } -bool CMipsMemoryVM::LB_Memory(uint32_t VAddr, uint8_t& Value) +bool CMipsMemoryVM::LB_Memory(uint64_t VAddr, uint8_t& Value) { - if (HaveReadBP() && g_Debugger->ReadBP8(VAddr) && MemoryBreakpoint()) + uint32_t VAddr32 = (uint32_t)VAddr; + + if (HaveReadBP() && g_Debugger->ReadBP8(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t*)-1) { - Value = *(uint8_t*)(MemoryPtr + (VAddr ^ 3)); + Value = *(uint8_t*)(MemoryPtr + (VAddr32 ^ 3)); return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { GenerateTLBReadException(VAddr, __FUNCTION__); return false; } - return LB_NonMemory(VAddr, Value); + return LB_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::LH_Memory(uint32_t VAddr, uint16_t & Value) +bool CMipsMemoryVM::LH_Memory(uint64_t VAddr, uint16_t & Value) { - if ((VAddr & 1) != 0) + uint32_t VAddr32 = (uint32_t)VAddr; + + if ((VAddr32 & 1) != 0) { GenerateAddressErrorException(VAddr, true); return false; } - if (HaveReadBP() && g_Debugger->ReadBP16(VAddr) && MemoryBreakpoint()) + if (HaveReadBP() && g_Debugger->ReadBP16(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t*)-1) { - Value = *(uint16_t*)(MemoryPtr + (VAddr ^ 2)); + Value = *(uint16_t*)(MemoryPtr + (VAddr32 ^ 2)); return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { GenerateTLBReadException(VAddr, __FUNCTION__); return false; } - return LH_NonMemory(VAddr, Value); + return LH_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::LW_Memory(uint32_t VAddr, uint32_t & Value) +bool CMipsMemoryVM::LW_Memory(uint64_t VAddr, uint32_t & Value) { - if ((VAddr & 3) != 0) + uint32_t VAddr32 = (uint32_t)VAddr; + + if ((VAddr32 & 3) != 0) { GenerateAddressErrorException(VAddr, true); return false; } - if (HaveReadBP() && g_Debugger->ReadBP32(VAddr) && MemoryBreakpoint()) + if (HaveReadBP() && g_Debugger->ReadBP32(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - Value = *(uint32_t*)(MemoryPtr + VAddr); + Value = *(uint32_t*)(MemoryPtr + VAddr32); return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { GenerateTLBReadException(VAddr, __FUNCTION__); return false; } - return LW_NonMemory(VAddr, Value); + return LW_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::LD_Memory(uint32_t VAddr, uint64_t& Value) +bool CMipsMemoryVM::LD_Memory(uint64_t VAddr, uint64_t& Value) { - if ((VAddr & 7) != 0) + uint32_t VAddr32 = (uint32_t)VAddr; + + if ((VAddr32 & 7) != 0) { GenerateAddressErrorException(VAddr, true); return false; } - if (HaveReadBP() && g_Debugger->ReadBP64(VAddr) && MemoryBreakpoint()) + if (HaveReadBP() && g_Debugger->ReadBP64(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - *((uint32_t*)(&Value) + 1) = *(uint32_t*)(MemoryPtr + VAddr); - *((uint32_t*)(&Value) + 0) = *(uint32_t*)(MemoryPtr + VAddr + 4); + *((uint32_t*)(&Value) + 1) = *(uint32_t*)(MemoryPtr + VAddr32); + *((uint32_t*)(&Value) + 0) = *(uint32_t*)(MemoryPtr + VAddr32 + 4); return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { return false; } - return LD_NonMemory(VAddr, Value); + return LD_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::SB_Memory(uint32_t VAddr, uint32_t Value) +bool CMipsMemoryVM::SB_Memory(uint64_t VAddr, uint32_t Value) { - if (HaveWriteBP() && g_Debugger->WriteBP8(VAddr) && MemoryBreakpoint()) + uint32_t VAddr32 = (uint32_t)VAddr; + + if (HaveWriteBP() && g_Debugger->WriteBP8(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - *(uint8_t*)(MemoryPtr + (VAddr ^ 3)) = (uint8_t)Value; + *(uint8_t*)(MemoryPtr + (VAddr32 ^ 3)) = (uint8_t)Value; return true; } - if (m_TLB_WriteMap[VAddr >> 12] == -1) + if (m_TLB_WriteMap[VAddr32 >> 12] == -1) { GenerateTLBWriteException(VAddr, __FUNCTION__); return false; } - return SB_NonMemory(VAddr, Value); + return SB_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::SH_Memory(uint32_t VAddr, uint32_t Value) +bool CMipsMemoryVM::SH_Memory(uint64_t VAddr, uint32_t Value) { - if ((VAddr & 1) != 0) + uint32_t VAddr32 = (uint32_t)VAddr; + + if ((VAddr32 & 1) != 0) { GenerateAddressErrorException(VAddr, false); return false; } - if (HaveWriteBP() && g_Debugger->WriteBP16(VAddr) && MemoryBreakpoint()) + if (HaveWriteBP() && g_Debugger->WriteBP16(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - *(uint16_t*)(MemoryPtr + (VAddr ^ 2)) = (uint16_t)Value; + *(uint16_t*)(MemoryPtr + (VAddr32 ^ 2)) = (uint16_t)Value; return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { GenerateTLBWriteException(VAddr, __FUNCTION__); return false; } - return SH_NonMemory(VAddr, Value); + return SH_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::SW_Memory(uint32_t VAddr, uint32_t Value) +bool CMipsMemoryVM::SW_Memory(uint64_t VAddr, uint32_t Value) { - if ((VAddr & 3) != 0) + uint32_t VAddr32 = (uint32_t)VAddr; + + if ((VAddr32 & 3) != 0) { GenerateAddressErrorException(VAddr, false); return false; } - if (HaveWriteBP() && g_Debugger->WriteBP32(VAddr) && MemoryBreakpoint()) + if (HaveWriteBP() && g_Debugger->WriteBP32(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - *(uint32_t*)(MemoryPtr + VAddr) = Value; + *(uint32_t*)(MemoryPtr + VAddr32) = Value; return true; } - uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12]; + uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12]; if (BaseAddress == -1) { GenerateTLBWriteException(VAddr, __FUNCTION__); return false; } - return SW_NonMemory(VAddr, Value); + return SW_NonMemory(VAddr32, Value); } -bool CMipsMemoryVM::SD_Memory(uint32_t VAddr, uint64_t Value) +bool CMipsMemoryVM::SD_Memory(uint64_t VAddr, uint64_t Value) { + uint32_t VAddr32 = (uint32_t)VAddr; + if ((VAddr & 7) != 0) { GenerateAddressErrorException(VAddr, false); return false; } - if (HaveWriteBP() && g_Debugger->WriteBP64(VAddr) && MemoryBreakpoint()) + if (HaveWriteBP() && g_Debugger->WriteBP64(VAddr32) && MemoryBreakpoint()) { return false; } - uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12]; + uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr32 >> 12]; if (MemoryPtr != (uint8_t *)-1) { - *(uint32_t*)(MemoryPtr + VAddr + 0) = *((uint32_t*)(&Value) + 1); - *(uint32_t*)(MemoryPtr + VAddr + 4) = *((uint32_t*)(&Value)); + *(uint32_t*)(MemoryPtr + VAddr32 + 0) = *((uint32_t*)(&Value) + 1); + *(uint32_t*)(MemoryPtr + VAddr32 + 4) = *((uint32_t*)(&Value)); return true; } - if (m_TLB_WriteMap[VAddr >> 12] == -1) + if (m_TLB_WriteMap[VAddr32 >> 12] == -1) { GenerateTLBWriteException(VAddr, __FUNCTION__); return false; } - return SD_NonMemory(VAddr, Value); + return SD_NonMemory(VAddr32, Value); } bool CMipsMemoryVM::ValidVaddr(uint32_t VAddr) const diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h index bf8f44648..e428bf9f4 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h @@ -83,15 +83,15 @@ public: bool UpdateMemoryValue16(uint32_t VAddr, uint16_t Value); bool UpdateMemoryValue32(uint32_t VAddr, uint32_t Value); - bool LB_Memory(uint32_t VAddr, uint8_t & Value); - bool LH_Memory(uint32_t VAddr, uint16_t & Value); - bool LW_Memory(uint32_t VAddr, uint32_t & Value); - bool LD_Memory(uint32_t VAddr, uint64_t & Value); + bool LB_Memory(uint64_t VAddr, uint8_t & Value); + bool LH_Memory(uint64_t VAddr, uint16_t & Value); + bool LW_Memory(uint64_t VAddr, uint32_t & Value); + bool LD_Memory(uint64_t VAddr, uint64_t & Value); - bool SB_Memory(uint32_t VAddr, uint32_t Value); - bool SH_Memory(uint32_t VAddr, uint32_t Value); - bool SW_Memory(uint32_t VAddr, uint32_t Value); - bool SD_Memory(uint32_t VAddr, uint64_t Value); + bool SB_Memory(uint64_t VAddr, uint32_t Value); + bool SH_Memory(uint64_t VAddr, uint32_t Value); + bool SW_Memory(uint64_t VAddr, uint32_t Value); + bool SD_Memory(uint64_t VAddr, uint64_t Value); int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer); diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index e9c26106c..5be8b1660 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -236,7 +236,7 @@ CP0registers::CP0registers(uint64_t * _CP0) : RANDOM_REGISTER(_CP0[1]), ENTRYLO0_REGISTER(_CP0[2]), ENTRYLO1_REGISTER(_CP0[3]), - CONTEXT_REGISTER(_CP0[4]), + CONTEXT_REGISTER((COP0Context &)_CP0[4]), PAGE_MASK_REGISTER(_CP0[5]), WIRED_REGISTER(_CP0[6]), BAD_VADDR_REGISTER(_CP0[8]), @@ -248,6 +248,7 @@ CP0registers::CP0registers(uint64_t * _CP0) : EPC_REGISTER(_CP0[14]), PREVID_REGISTER(_CP0[15]), CONFIG_REGISTER(_CP0[16]), + XCONTEXT_REGISTER((COP0XContext &)_CP0[20]), TAGLO_REGISTER(_CP0[28]), TAGHI_REGISTER(_CP0[29]), ERROREPC_REGISTER(_CP0[30]), @@ -392,7 +393,7 @@ void CRegisters::Cop0_MT(uint32_t Reg, uint64_t Value) m_CP0[Reg] = Value; break; case 4: // Context - m_CP0[Reg] = Value & 0xFF800000; + m_CP0[Reg] = Value & 0xFFFFFFFFFF800000; break; case 9: // Count g_SystemTimer->UpdateTimers(); @@ -484,7 +485,7 @@ void CRegisters::CheckInterrupts() } } -void CRegisters::DoAddressError(bool DelaySlot, uint32_t BadVaddr, bool FromRead) +void CRegisters::DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead) { if (BreakOnAddressError()) { @@ -500,14 +501,18 @@ void CRegisters::DoAddressError(bool DelaySlot, uint32_t BadVaddr, bool FromRead CAUSE_REGISTER = EXC_WADE; } BAD_VADDR_REGISTER = BadVaddr; + CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; + XCONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; + XCONTEXT_REGISTER.R = BadVaddr >> 62; + if (DelaySlot) { CAUSE_REGISTER |= CAUSE_BD; - EPC_REGISTER = m_PROGRAM_COUNTER - 4; + EPC_REGISTER = (int32_t)(m_PROGRAM_COUNTER - 4); } else { - EPC_REGISTER = m_PROGRAM_COUNTER; + EPC_REGISTER = (int32_t)m_PROGRAM_COUNTER; } STATUS_REGISTER |= STATUS_EXL; m_PROGRAM_COUNTER = 0x80000180; @@ -681,12 +686,11 @@ void CRegisters::DoOverflowException(bool DelaySlot) STATUS_REGISTER |= STATUS_EXL; } -void CRegisters::DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr) +void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr) { CAUSE_REGISTER = EXC_RMISS; BAD_VADDR_REGISTER = BadVaddr; - CONTEXT_REGISTER &= 0xFF80000F; - CONTEXT_REGISTER |= (BadVaddr >> 9) & 0x007FFFF0; + CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); if ((STATUS_REGISTER & STATUS_EXL) == 0) { @@ -699,7 +703,7 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr) { EPC_REGISTER = m_PROGRAM_COUNTER; } - if (g_TLB->AddressDefined(BadVaddr)) + if (g_TLB->AddressDefined((uint32_t)BadVaddr)) { m_PROGRAM_COUNTER = 0x80000180; } @@ -713,18 +717,17 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr) { if (HaveDebugger()) { - g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", BadVaddr, g_TLB->AddressDefined(BadVaddr) ? "true" : "false").c_str()); + g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", (uint32_t)BadVaddr, g_TLB->AddressDefined((uint32_t)BadVaddr) ? "true" : "false").c_str()); } m_PROGRAM_COUNTER = 0x80000180; } } -void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr) +void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr) { CAUSE_REGISTER = EXC_WMISS; BAD_VADDR_REGISTER = BadVaddr; - CONTEXT_REGISTER &= 0xFF80000F; - CONTEXT_REGISTER |= (BadVaddr >> 9) & 0x007FFFF0; + CONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13; ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000); if ((STATUS_REGISTER & STATUS_EXL) == 0) { @@ -737,7 +740,7 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr) { EPC_REGISTER = m_PROGRAM_COUNTER; } - if (g_TLB->AddressDefined(BadVaddr)) + if (g_TLB->AddressDefined((uint32_t)BadVaddr)) { m_PROGRAM_COUNTER = 0x80000180; } @@ -751,7 +754,7 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr) { if (HaveDebugger()) { - g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", BadVaddr, g_TLB->AddressDefined(BadVaddr) ? "true" : "false").c_str()); + g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", (uint32_t)BadVaddr, g_TLB->AddressDefined((uint32_t)BadVaddr) ? "true" : "false").c_str()); } m_PROGRAM_COUNTER = 0x80000180; } diff --git a/Source/Project64-core/N64System/Mips/Register.h b/Source/Project64-core/N64System/Mips/Register.h index 0e06a25ac..59388525f 100644 --- a/Source/Project64-core/N64System/Mips/Register.h +++ b/Source/Project64-core/N64System/Mips/Register.h @@ -16,6 +16,37 @@ #include #include +#pragma warning(push) +#pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union + +union COP0Context +{ + uint64_t Value; + + struct + { + unsigned : 4; + unsigned BadVPN2 : 19; + unsigned PTEBaseHi : 9; + unsigned PTEBaseLo : 32; + }; +}; + +union COP0XContext +{ + uint64_t Value; + + struct + { + unsigned : 4; + unsigned BadVPN2 : 27; + unsigned R : 2; + unsigned PTEBase : 31; + }; +}; + +#pragma warning(pop) + // CPO registers by name class CP0registers { @@ -27,7 +58,7 @@ public: uint64_t & RANDOM_REGISTER; uint64_t & ENTRYLO0_REGISTER; uint64_t & ENTRYLO1_REGISTER; - uint64_t & CONTEXT_REGISTER; + COP0Context & CONTEXT_REGISTER; uint64_t & PAGE_MASK_REGISTER; uint64_t & WIRED_REGISTER; uint64_t & BAD_VADDR_REGISTER; @@ -39,6 +70,7 @@ public: uint64_t & EPC_REGISTER; uint64_t & PREVID_REGISTER; uint64_t & CONFIG_REGISTER; + COP0XContext & XCONTEXT_REGISTER; uint64_t & TAGLO_REGISTER; uint64_t & TAGHI_REGISTER; uint64_t & ERROREPC_REGISTER; @@ -264,15 +296,15 @@ public: CRegisters(CN64System * System, CSystemEvents * SystemEvents); void CheckInterrupts(); - void DoAddressError( bool DelaySlot, uint32_t BadVaddr, bool FromRead ); + void DoAddressError( bool DelaySlot, uint64_t BadVaddr, bool FromRead ); void DoBreakException( bool DelaySlot ); void DoTrapException( bool DelaySlot ); void DoCopUnusableException( bool DelaySlot, int32_t Coprocessor ); bool DoIntrException( bool DelaySlot ); void DoIllegalInstructionException(bool DelaySlot); void DoOverflowException(bool DelaySlot); - void DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr); - void DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr); + void DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr); + void DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr); void DoSysCallException ( bool DelaySlot); void FixFpuLocations(); void Reset(); diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index a80803a2a..c66010d56 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -1028,10 +1028,10 @@ void CN64System::InitRegisters(bool bPostPif, CMipsMemoryVM & MMU) m_Reg.MI_VERSION_REG = 0x02020102; m_Reg.SP_STATUS_REG = 0x00000001; m_Reg.CAUSE_REGISTER = 0x0000005C; - m_Reg.CONTEXT_REGISTER = 0x007FFFF0; - m_Reg.EPC_REGISTER = 0xFFFFFFFF; - m_Reg.BAD_VADDR_REGISTER = 0xFFFFFFFF; - m_Reg.ERROREPC_REGISTER = 0xFFFFFFFF; + m_Reg.CONTEXT_REGISTER.Value = 0x007FFFF0; + m_Reg.EPC_REGISTER = 0xFFFFFFFFFFFFFFFF; + m_Reg.BAD_VADDR_REGISTER = 0xFFFFFFFFFFFFFFFF; + m_Reg.ERROREPC_REGISTER = 0xFFFFFFFFFFFFFFFF; m_Reg.PREVID_REGISTER = 0x00000B22; m_Reg.CONFIG_REGISTER = 0x7006E463; m_Reg.STATUS_REGISTER = 0x34000000; diff --git a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp index 97ce8a88f..49d4ee8cc 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-RegisterTabs.cpp @@ -135,7 +135,7 @@ void CRegisterTabs::RefreshEdits() m_COP0Edits[1].SetValue((uint32_t)g_Reg->RANDOM_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[2].SetValue((uint32_t)g_Reg->ENTRYLO0_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[3].SetValue((uint32_t)g_Reg->ENTRYLO1_REGISTER, DisplayMode::ZeroExtend); - m_COP0Edits[4].SetValue((uint32_t)g_Reg->CONTEXT_REGISTER, DisplayMode::ZeroExtend); + m_COP0Edits[4].SetValue((uint32_t)g_Reg->CONTEXT_REGISTER.Value, DisplayMode::ZeroExtend); m_COP0Edits[5].SetValue((uint32_t)g_Reg->PAGE_MASK_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[6].SetValue((uint32_t)g_Reg->WIRED_REGISTER, DisplayMode::ZeroExtend); m_COP0Edits[7].SetValue((uint32_t)g_Reg->BAD_VADDR_REGISTER, DisplayMode::ZeroExtend); @@ -315,7 +315,7 @@ void CRegisterTabs::RegisterChanged(HWND hDlg, TAB_ID srcTabId, WPARAM wParam) case IDC_COP0_1_EDIT: g_Reg->RANDOM_REGISTER = value; break; case IDC_COP0_2_EDIT: g_Reg->ENTRYLO0_REGISTER = value; break; case IDC_COP0_3_EDIT: g_Reg->ENTRYLO1_REGISTER = value; break; - case IDC_COP0_4_EDIT: g_Reg->CONTEXT_REGISTER = value; break; + case IDC_COP0_4_EDIT: g_Reg->CONTEXT_REGISTER.Value = value; break; case IDC_COP0_5_EDIT: g_Reg->PAGE_MASK_REGISTER = value; break; case IDC_COP0_6_EDIT: g_Reg->WIRED_REGISTER = value; break; case IDC_COP0_7_EDIT: g_Reg->BAD_VADDR_REGISTER = value; break;