Core: Move memory exceptions out of interrupter ops and in to Memory Manager
This commit is contained in:
parent
d2b33022fb
commit
86aa483a38
|
@ -49,12 +49,6 @@ const int32_t R4300iOp::SWR_SHIFT[4] = { 24, 16, 8, 0 };
|
|||
const int32_t R4300iOp::LWL_SHIFT[4] = { 0, 8, 16, 24 };
|
||||
const int32_t R4300iOp::LWR_SHIFT[4] = { 24, 16, 8, 0 };
|
||||
|
||||
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
|
||||
g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address,FromRead);\
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
|
||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
|
||||
return;
|
||||
|
||||
#define TEST_COP1_USABLE_EXCEPTION() \
|
||||
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\
|
||||
g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,1);\
|
||||
|
@ -988,21 +982,12 @@ 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;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t Value;
|
||||
if (!g_MMU->LD_Memory((Address & ~7), Value))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
uint64_t MemoryValue;
|
||||
if (g_MMU->LD_Memory((Address & ~7), MemoryValue))
|
||||
{
|
||||
uint32_t Offset = Address & 7;
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDL_MASK[Offset];
|
||||
_GPR[m_Opcode.rt].DW += Value << LDL_SHIFT[Offset];
|
||||
_GPR[m_Opcode.rt].DW += MemoryValue << LDL_SHIFT[Offset];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,253 +1000,127 @@ 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;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t Value;
|
||||
if (!g_MMU->LD_Memory((Address & ~7), Value))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
uint64_t MemoryValue;
|
||||
if (g_MMU->LD_Memory((Address & ~7), MemoryValue))
|
||||
{
|
||||
uint32_t Offset = Address & 7;
|
||||
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDR_MASK[Offset];
|
||||
_GPR[m_Opcode.rt].DW += Value >> LDR_SHIFT[Offset];
|
||||
_GPR[m_Opcode.rt].DW += MemoryValue >> LDR_SHIFT[Offset];
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LB()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint())
|
||||
uint8_t MemoryValue;
|
||||
if (g_MMU->LB_Memory(Address, MemoryValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].B[0];
|
||||
_GPR[m_Opcode.rt].DW = (int8_t)MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LH()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 1) != 0)
|
||||
uint16_t MemoryValue;
|
||||
if (g_MMU->LH_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].HW[0];
|
||||
_GPR[m_Opcode.rt].DW = (int16_t)MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LWL()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t Value;
|
||||
if (!g_MMU->LW_Memory((Address & ~3), Value))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory((Address & ~3), MemoryValue))
|
||||
{
|
||||
uint32_t Offset = Address & 3;
|
||||
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]);
|
||||
_GPR[m_Opcode.rt].DW += (int32_t)(Value << LWL_SHIFT[Offset]);
|
||||
_GPR[m_Opcode.rt].DW += (int32_t)(MemoryValue << LWL_SHIFT[Offset]);
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LW()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].W[0];
|
||||
_GPR[m_Opcode.rt].DW = (int32_t)MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LBU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint())
|
||||
uint8_t MemoryValue;
|
||||
if (g_MMU->LB_Memory(Address, MemoryValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UDW = _GPR[m_Opcode.rt].UB[0];
|
||||
_GPR[m_Opcode.rt].UDW = MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LHU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 1) != 0)
|
||||
uint16_t MemoryValue;
|
||||
if (g_MMU->LH_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UDW = _GPR[m_Opcode.rt].UHW[0];
|
||||
_GPR[m_Opcode.rt].UDW = MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LWR()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t Value;
|
||||
if (!g_MMU->LW_Memory((Address & ~3), Value))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory((Address & ~3), MemoryValue))
|
||||
{
|
||||
uint32_t Offset = Address & 3;
|
||||
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]);
|
||||
_GPR[m_Opcode.rt].DW += (int32_t)(Value >> LWR_SHIFT[Offset]);
|
||||
_GPR[m_Opcode.rt].DW += (int32_t)(MemoryValue >> LWR_SHIFT[Offset]);
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LWU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UDW = _GPR[m_Opcode.rt].UW[0];
|
||||
_GPR[m_Opcode.rt].UDW = MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::SB()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP8(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->SB_VAddr(Address, _GPR[m_Opcode.rt].UB[0]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
g_MMU->SB_Memory(Address, _GPR[m_Opcode.rt].UB[0]);
|
||||
}
|
||||
|
||||
void R4300iOp::SH()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 1) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP16(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->SH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
g_MMU->SH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]);
|
||||
}
|
||||
|
||||
void R4300iOp::SWL()
|
||||
{
|
||||
uint32_t Offset, Address, Value;
|
||||
|
||||
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(Address) && MemoryBreakpoint())
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->MemoryValue32(Address & ~3, MemoryValue))
|
||||
{
|
||||
return;
|
||||
uint32_t Offset = Address & 3;
|
||||
MemoryValue &= SWL_MASK[Offset];
|
||||
MemoryValue += _GPR[m_Opcode.rt].UW[0] >> SWL_SHIFT[Offset];
|
||||
g_MMU->SW_Memory(Address & ~3, MemoryValue);
|
||||
}
|
||||
Offset = Address & 3;
|
||||
|
||||
if (!g_MMU->LW_Memory((Address & ~3), Value))
|
||||
else
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
Value &= SWL_MASK[Offset];
|
||||
Value += _GPR[m_Opcode.rt].UW[0] >> SWL_SHIFT[Offset];
|
||||
g_MMU->SW_VAddr((Address & ~0x03), Value);
|
||||
}
|
||||
|
||||
void R4300iOp::SW()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
g_MMU->SW_Memory(Address, _GPR[m_Opcode.rt].UW[0]);
|
||||
}
|
||||
|
||||
uint64_t SDL_MASK[8] = { 0, 0xFF00000000000000,
|
||||
|
@ -1276,24 +1135,19 @@ int32_t SDL_SHIFT[8] = { 0, 8, 16, 24, 32, 40, 48, 56 };
|
|||
|
||||
void R4300iOp::SDL()
|
||||
{
|
||||
uint32_t Offset, Address;
|
||||
uint64_t Value;
|
||||
|
||||
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP64(Address) && MemoryBreakpoint())
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
uint64_t MemoryValue;
|
||||
if (g_MMU->MemoryValue64((Address & ~7), MemoryValue))
|
||||
{
|
||||
return;
|
||||
uint32_t Offset = Address & 7;
|
||||
MemoryValue &= SDL_MASK[Offset];
|
||||
MemoryValue += _GPR[m_Opcode.rt].UDW >> SDL_SHIFT[Offset];
|
||||
g_MMU->SD_Memory((Address & ~7), MemoryValue);
|
||||
}
|
||||
Offset = Address & 7;
|
||||
|
||||
if (!g_MMU->LD_Memory((Address & ~7), Value))
|
||||
else
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
|
||||
Value &= SDL_MASK[Offset];
|
||||
Value += _GPR[m_Opcode.rt].UDW >> SDL_SHIFT[Offset];
|
||||
g_MMU->SD_VAddr((Address & ~7), Value);
|
||||
}
|
||||
|
||||
uint64_t SDR_MASK[8] = { 0x00FFFFFFFFFFFFFF,
|
||||
|
@ -1309,43 +1163,30 @@ int32_t SDR_SHIFT[8] = { 56, 48, 40, 32, 24, 16, 8, 0 };
|
|||
|
||||
void R4300iOp::SDR()
|
||||
{
|
||||
uint32_t Offset, Address;
|
||||
uint64_t Value;
|
||||
|
||||
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP64(Address) && MemoryBreakpoint())
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
uint64_t MemoryValue;
|
||||
if (g_MMU->MemoryValue64((Address & ~7), MemoryValue))
|
||||
{
|
||||
return;
|
||||
uint32_t Offset = Address & 7;
|
||||
MemoryValue &= SDR_MASK[Offset];
|
||||
MemoryValue += _GPR[m_Opcode.rt].UDW << SDR_SHIFT[Offset];
|
||||
g_MMU->SD_Memory((Address & ~7), MemoryValue);
|
||||
}
|
||||
Offset = Address & 7;
|
||||
|
||||
if (!g_MMU->LD_Memory((Address & ~7), Value))
|
||||
else
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
Value &= SDR_MASK[Offset];
|
||||
Value += _GPR[m_Opcode.rt].UDW << SDR_SHIFT[Offset];
|
||||
g_MMU->SD_VAddr((Address & ~7), Value);
|
||||
}
|
||||
|
||||
void R4300iOp::SWR()
|
||||
{
|
||||
uint32_t Offset, Address, Value;
|
||||
|
||||
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(Address) && MemoryBreakpoint())
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->MemoryValue32((Address & ~3), MemoryValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Offset = Address & 3;
|
||||
|
||||
if (g_MMU->LW_Memory((Address & ~3), Value))
|
||||
{
|
||||
Value &= SWR_MASK[Offset];
|
||||
Value += _GPR[m_Opcode.rt].UW[0] << SWR_SHIFT[Offset];
|
||||
g_MMU->SW_VAddr((Address & ~0x03), Value);
|
||||
uint32_t Offset = Address & 3;
|
||||
MemoryValue &= SWR_MASK[Offset];
|
||||
MemoryValue += _GPR[m_Opcode.rt].UW[0] << SWR_SHIFT[Offset];
|
||||
g_MMU->SW_Memory((Address & ~0x03), MemoryValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1365,165 +1206,70 @@ void R4300iOp::CACHE()
|
|||
|
||||
void R4300iOp::LL()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].W[0];
|
||||
_GPR[m_Opcode.rt].DW = (int32_t)MemoryValue;
|
||||
(*_LLBit) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LWC1()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (uint32_t)((int16_t)m_Opcode.offset);
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
if ((Address & 3) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (uint32_t)((int16_t)m_Opcode.offset);
|
||||
g_MMU->LW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]);
|
||||
}
|
||||
|
||||
void R4300iOp::SC()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
if ((*_LLBit) != 1 || g_MMU->SW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
_GPR[m_Opcode.rt].UW[0] = (*_LLBit);
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((*_LLBit) == 1)
|
||||
{
|
||||
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_GPR[m_Opcode.rt].UW[0] = (*_LLBit);
|
||||
}
|
||||
|
||||
void R4300iOp::LD()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 7) != 0)
|
||||
if (g_MMU->LD_Memory(Address, _GPR[m_Opcode.rt].UDW))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LD_Memory(Address, _GPR[m_Opcode.rt].UDW))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
#ifdef Interpreter_StackTest
|
||||
if (m_Opcode.rt == 29)
|
||||
{
|
||||
StackValue = _GPR[m_Opcode.rt].W[0];
|
||||
}
|
||||
if (m_Opcode.rt == 29)
|
||||
{
|
||||
StackValue = _GPR[m_Opcode.rt].W[0];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::LDC1()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
if ((Address & 7) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
g_MMU->LD_Memory(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]);
|
||||
}
|
||||
|
||||
void R4300iOp::SWC1()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
if ((Address & 3) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_MMU->SW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
g_MMU->SW_Memory(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]);
|
||||
}
|
||||
|
||||
void R4300iOp::SDC1()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
|
||||
TEST_COP1_USABLE_EXCEPTION();
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Address & 7) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
}
|
||||
if (!g_MMU->SD_VAddr(Address, *(int64_t *)_FPR_D[m_Opcode.ft]))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (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;
|
||||
if ((Address & 7) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, false);
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP64(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->SD_VAddr(Address, _GPR[m_Opcode.rt].UDW))
|
||||
{
|
||||
GenerateTLBWriteException(Address, __FUNCTION__);
|
||||
}
|
||||
g_MMU->SD_Memory(Address, _GPR[m_Opcode.rt].UDW);
|
||||
}
|
||||
|
||||
// R4300i opcodes: Special
|
||||
|
@ -2890,6 +2636,13 @@ bool R4300iOp::MemoryBreakpoint()
|
|||
return false;
|
||||
}
|
||||
|
||||
void R4300iOp::GenerateAddressErrorException(uint32_t VAddr, bool FromRead)
|
||||
{
|
||||
g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr, FromRead);
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||
}
|
||||
|
||||
void R4300iOp::GenerateTLBReadException(uint32_t VAddr, const char * function)
|
||||
{
|
||||
if (bShowTLBMisses())
|
||||
|
|
|
@ -238,6 +238,7 @@ protected:
|
|||
static Func Jump_CoP1_W[64];
|
||||
static Func Jump_CoP1_L[64];
|
||||
|
||||
static void GenerateAddressErrorException(uint32_t VAddr, bool FromRead);
|
||||
static void GenerateTLBReadException(uint32_t VAddr, const char * function);
|
||||
static void GenerateTLBWriteException(uint32_t VAddr, const char * function);
|
||||
|
||||
|
|
|
@ -10,12 +10,6 @@
|
|||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
|
||||
g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address,FromRead);\
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
|
||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
|
||||
return;
|
||||
|
||||
#define TEST_COP1_USABLE_EXCEPTION \
|
||||
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\
|
||||
g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,1);\
|
||||
|
@ -878,184 +872,82 @@ void R4300iOp32::BGTZL()
|
|||
void R4300iOp32::LB()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint())
|
||||
uint8_t MemoryValue;
|
||||
if (g_MMU->LB_Memory(Address, MemoryValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].B[0];
|
||||
_GPR[m_Opcode.rt].W[0] = (int8_t)MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp32::LH()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 1) != 0)
|
||||
uint16_t MemoryValue;
|
||||
if (g_MMU->LH_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].HW[0];
|
||||
_GPR[m_Opcode.rt].W[0] = (int16_t)MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp32::LWL()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t Value;
|
||||
if (!g_MMU->LW_Memory((Address & ~3), Value))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory((Address & ~3), MemoryValue))
|
||||
{
|
||||
uint32_t Offset = Address & 3;
|
||||
_GPR[m_Opcode.rt].W[0] = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]);
|
||||
_GPR[m_Opcode.rt].W[0] += (int32_t)(Value << LWL_SHIFT[Offset]);
|
||||
_GPR[m_Opcode.rt].W[0] += (int32_t)(MemoryValue << LWL_SHIFT[Offset]);
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp32::LW()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0];
|
||||
}
|
||||
g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]);
|
||||
}
|
||||
|
||||
void R4300iOp32::LBU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP8(Address) && MemoryBreakpoint())
|
||||
uint8_t MemoryValue;
|
||||
if (g_MMU->LB_Memory(Address, MemoryValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LB_Memory(Address, _GPR[m_Opcode.rt].UB[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UB[0];
|
||||
_GPR[m_Opcode.rt].UW[0] = MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp32::LHU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 1) != 0)
|
||||
uint16_t MemoryValue;
|
||||
if (g_MMU->LH_Memory(Address, MemoryValue))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP16(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LH_Memory(Address, _GPR[m_Opcode.rt].UHW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UHW[0];
|
||||
_GPR[m_Opcode.rt].UW[0] = MemoryValue;
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp32::LWR()
|
||||
{
|
||||
uint32_t Offset, Address, Value;
|
||||
|
||||
Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
Offset = Address & 3;
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset, MemoryValue;
|
||||
if (g_MMU->LW_Memory((Address & ~3), MemoryValue))
|
||||
{
|
||||
return;
|
||||
uint32_t Offset = Address & 3;
|
||||
_GPR[m_Opcode.rt].W[0] = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]);
|
||||
_GPR[m_Opcode.rt].W[0] += (int32_t)(MemoryValue >> LWR_SHIFT[Offset]);
|
||||
}
|
||||
if (!g_MMU->LW_Memory((Address & ~3), Value))
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
if (bShowTLBMisses())
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_GPR[m_Opcode.rt].W[0] = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]);
|
||||
_GPR[m_Opcode.rt].W[0] += (int32_t)(Value >> LWR_SHIFT[Offset]);
|
||||
}
|
||||
|
||||
void R4300iOp32::LWU()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UW[0];
|
||||
}
|
||||
g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]);
|
||||
}
|
||||
|
||||
void R4300iOp32::LL()
|
||||
{
|
||||
uint32_t Address = _GPR[m_Opcode.base].UW[0] + (int16_t)m_Opcode.offset;
|
||||
if ((Address & 3) != 0)
|
||||
if (g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
ADDRESS_ERROR_EXCEPTION(Address, true);
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(Address) && MemoryBreakpoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!g_MMU->LW_Memory(Address, _GPR[m_Opcode.rt].UW[0]))
|
||||
{
|
||||
GenerateTLBReadException(Address, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
{
|
||||
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0];
|
||||
(*_LLBit) = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <Project64-core\N64System\Recompiler\RecompilerCodeLog.h>
|
||||
#include <Project64-core\N64System\Mips\OpcodeName.h>
|
||||
#include <Project64-core\N64System\Mips\Disk.h>
|
||||
#include <Project64-core\Debugger.h>
|
||||
#include <Project64-core\ExceptionHandler.h>
|
||||
#include <Common\MemoryManagement.h>
|
||||
#include <stdio.h>
|
||||
|
@ -266,27 +267,27 @@ void CMipsMemoryVM::FreeMemory()
|
|||
CPifRam::Reset();
|
||||
}
|
||||
|
||||
uint8_t * CMipsMemoryVM::MemoryPtr(uint32_t VAddr, uint32_t size, bool Read)
|
||||
uint8_t * CMipsMemoryVM::MemoryPtr(uint32_t VAddr, uint32_t Size, bool Read)
|
||||
{
|
||||
if (m_TLB_ReadMap[VAddr >> 12] == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
uint32_t PAddr = m_TLB_ReadMap[VAddr >> 12] + VAddr;
|
||||
if ((PAddr + size) < m_AllocatedRdramSize)
|
||||
if ((PAddr + Size) < m_AllocatedRdramSize)
|
||||
{
|
||||
return (uint8_t*)(m_RDRAM + PAddr);
|
||||
}
|
||||
|
||||
if (PAddr >= 0x04000000 && (PAddr + size) < 0x04001000)
|
||||
if (PAddr >= 0x04000000 && (PAddr + Size) < 0x04001000)
|
||||
{
|
||||
return (uint8_t*)(m_DMEM + (PAddr - 0x04000000));
|
||||
}
|
||||
if (PAddr >= 0x04001000 && (PAddr + size) < 0x04002000)
|
||||
if (PAddr >= 0x04001000 && (PAddr + Size) < 0x04002000)
|
||||
{
|
||||
return (uint8_t*)(m_IMEM + (PAddr - 0x04001000));
|
||||
}
|
||||
if (Read && PAddr >= 0x10000000 && (PAddr + size) < (0x10000000 + m_Rom.GetRomSize()))
|
||||
if (Read && PAddr >= 0x10000000 && (PAddr + Size) < (0x10000000 + m_Rom.GetRomSize()))
|
||||
{
|
||||
return (uint8_t *)&m_Rom.GetRomAddress()[PAddr - 0x10000000];
|
||||
}
|
||||
|
@ -329,6 +330,17 @@ bool CMipsMemoryVM::MemoryValue32(uint32_t VAddr, uint32_t & Value)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::MemoryValue64(uint32_t VAddr, uint64_t & Value)
|
||||
{
|
||||
uint8_t * ptr = MemoryPtr(VAddr, 8, true);
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Value = *(uint64_t*)(ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::UpdateMemoryValue8(uint32_t VAddr, uint8_t Value)
|
||||
{
|
||||
uint8_t * ptr = MemoryPtr(VAddr ^ 3, 1, false);
|
||||
|
@ -364,6 +376,10 @@ bool CMipsMemoryVM::UpdateMemoryValue32(uint32_t VAddr, uint32_t Value)
|
|||
|
||||
bool CMipsMemoryVM::LB_Memory(uint32_t VAddr, uint8_t& Value)
|
||||
{
|
||||
if (HaveReadBP() && g_Debugger->ReadBP8(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t*)-1)
|
||||
{
|
||||
|
@ -373,6 +389,7 @@ bool CMipsMemoryVM::LB_Memory(uint32_t VAddr, uint8_t& Value)
|
|||
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
|
||||
if (BaseAddress == -1)
|
||||
{
|
||||
GenerateTLBReadException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return LB_NonMemory(VAddr, Value);
|
||||
|
@ -380,6 +397,15 @@ bool CMipsMemoryVM::LB_Memory(uint32_t VAddr, uint8_t& Value)
|
|||
|
||||
bool CMipsMemoryVM::LH_Memory(uint32_t VAddr, uint16_t & Value)
|
||||
{
|
||||
if ((VAddr & 1) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, true);
|
||||
return false;
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP16(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t*)-1)
|
||||
{
|
||||
|
@ -389,6 +415,7 @@ bool CMipsMemoryVM::LH_Memory(uint32_t VAddr, uint16_t & Value)
|
|||
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
|
||||
if (BaseAddress == -1)
|
||||
{
|
||||
GenerateTLBReadException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return LH_NonMemory(VAddr, Value);
|
||||
|
@ -396,6 +423,15 @@ bool CMipsMemoryVM::LH_Memory(uint32_t VAddr, uint16_t & Value)
|
|||
|
||||
bool CMipsMemoryVM::LW_Memory(uint32_t VAddr, uint32_t & Value)
|
||||
{
|
||||
if ((VAddr & 3) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, true);
|
||||
return false;
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP32(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -405,6 +441,7 @@ bool CMipsMemoryVM::LW_Memory(uint32_t VAddr, uint32_t & Value)
|
|||
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
|
||||
if (BaseAddress == -1)
|
||||
{
|
||||
GenerateTLBReadException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return LW_NonMemory(VAddr, Value);
|
||||
|
@ -412,6 +449,15 @@ bool CMipsMemoryVM::LW_Memory(uint32_t VAddr, uint32_t & Value)
|
|||
|
||||
bool CMipsMemoryVM::LD_Memory(uint32_t VAddr, uint64_t& Value)
|
||||
{
|
||||
if ((VAddr & 7) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, true);
|
||||
return false;
|
||||
}
|
||||
if (HaveReadBP() && g_Debugger->ReadBP64(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryReadMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -427,8 +473,12 @@ bool CMipsMemoryVM::LD_Memory(uint32_t VAddr, uint64_t& Value)
|
|||
return LD_NonMemory(VAddr, Value);
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value)
|
||||
bool CMipsMemoryVM::SB_Memory(uint32_t VAddr, uint8_t Value)
|
||||
{
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP8(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -437,13 +487,23 @@ bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value)
|
|||
}
|
||||
if (m_TLB_WriteMap[VAddr >> 12] == -1)
|
||||
{
|
||||
GenerateTLBWriteException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return SB_NonMemory(VAddr, Value);
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value)
|
||||
bool CMipsMemoryVM::SH_Memory(uint32_t VAddr, uint16_t Value)
|
||||
{
|
||||
if ((VAddr & 1) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, false);
|
||||
return false;
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP16(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -453,13 +513,23 @@ bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value)
|
|||
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
|
||||
if (BaseAddress == -1)
|
||||
{
|
||||
GenerateTLBWriteException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return SH_NonMemory(VAddr, Value);
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value)
|
||||
bool CMipsMemoryVM::SW_Memory(uint32_t VAddr, uint32_t Value)
|
||||
{
|
||||
if ((VAddr & 3) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, false);
|
||||
return false;
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP32(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -469,13 +539,24 @@ bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value)
|
|||
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
|
||||
if (BaseAddress == -1)
|
||||
{
|
||||
GenerateTLBWriteException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return SW_NonMemory(VAddr, Value);
|
||||
}
|
||||
|
||||
bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value)
|
||||
bool CMipsMemoryVM::SD_Memory(uint32_t VAddr, uint64_t Value)
|
||||
{
|
||||
if ((VAddr & 7) != 0)
|
||||
{
|
||||
GenerateAddressErrorException(VAddr, false);
|
||||
return false;
|
||||
}
|
||||
if (HaveWriteBP() && g_Debugger->WriteBP64(VAddr) && MemoryBreakpoint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t * MemoryPtr = (uint8_t*)m_MemoryWriteMap[VAddr >> 12];
|
||||
if (MemoryPtr != (uint8_t *)-1)
|
||||
{
|
||||
|
@ -485,6 +566,7 @@ bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value)
|
|||
}
|
||||
if (m_TLB_WriteMap[VAddr >> 12] == -1)
|
||||
{
|
||||
GenerateTLBWriteException(VAddr, __FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
return SD_NonMemory(VAddr, Value);
|
||||
|
|
|
@ -73,11 +73,12 @@ public:
|
|||
CSram & GetSram() { return m_CartridgeDomain2Address2Handler.Sram(); }
|
||||
CFlashRam & GetFlashRam() { return m_CartridgeDomain2Address2Handler.FlashRam(); }
|
||||
|
||||
uint8_t * MemoryPtr(uint32_t VAddr, uint32_t size, bool Read);
|
||||
uint8_t * MemoryPtr(uint32_t VAddr, uint32_t Size, bool Read);
|
||||
|
||||
bool MemoryValue8(uint32_t VAddr, uint8_t & Value);
|
||||
bool MemoryValue16(uint32_t VAddr, uint16_t & Value);
|
||||
bool MemoryValue32(uint32_t VAddr, uint32_t & Value);
|
||||
bool MemoryValue64(uint32_t VAddr, uint64_t & Value);
|
||||
|
||||
bool UpdateMemoryValue8(uint32_t VAddr, uint8_t Value);
|
||||
bool UpdateMemoryValue16(uint32_t VAddr, uint16_t Value);
|
||||
|
@ -88,10 +89,10 @@ public:
|
|||
bool LW_Memory(uint32_t VAddr, uint32_t & Value);
|
||||
bool LD_Memory(uint32_t VAddr, uint64_t & Value);
|
||||
|
||||
bool SB_VAddr(uint32_t VAddr, uint8_t Value);
|
||||
bool SH_VAddr(uint32_t VAddr, uint16_t Value);
|
||||
bool SW_VAddr(uint32_t VAddr, uint32_t Value);
|
||||
bool SD_VAddr(uint32_t VAddr, uint64_t Value);
|
||||
bool SB_Memory(uint32_t VAddr, uint8_t Value);
|
||||
bool SH_Memory(uint32_t VAddr, uint16_t Value);
|
||||
bool SW_Memory(uint32_t VAddr, uint32_t Value);
|
||||
bool SD_Memory(uint32_t VAddr, uint64_t Value);
|
||||
|
||||
int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer);
|
||||
|
||||
|
|
Loading…
Reference in New Issue