Core: Make Load/Store use 64bit vaddr

This commit is contained in:
zilmar 2022-09-19 21:36:36 +09:30
parent 1c77f6f0fd
commit a2981ff4d8
8 changed files with 186 additions and 121 deletions

View File

@ -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;

View File

@ -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];

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -16,6 +16,37 @@
#include <Project64-core\Settings\GameSettings.h>
#include <Project64-core\Logging.h>
#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();

View File

@ -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;

View File

@ -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;