Project64: Add TLB_WRITE_EXCEPTION

This commit is contained in:
zilmar 2020-03-04 10:33:18 +10:30
parent 28c9118912
commit 185c6586b4
3 changed files with 78 additions and 90 deletions

View File

@ -83,6 +83,12 @@ const int32_t R4300iOp::LWR_SHIFT[4] = { 24, 16, 8, 0 };
m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
#define TLB_WRITE_EXCEPTION(Address) \
g_Reg->DoTLBWriteMiss(m_NextInstruction == JUMP,Address);\
m_NextInstruction = JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;
void R4300iOp::SPECIAL()
{
Jump_Special[m_Opcode.funct]();
@ -1033,12 +1039,11 @@ void R4300iOp::LDL()
if (!g_MMU->LD_VAddr((Address & ~7), Value))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDL_MASK[Offset];
_GPR[m_Opcode.rt].DW += Value << LDL_SHIFT[Offset];
@ -1064,12 +1069,11 @@ void R4300iOp::LDR()
if (!g_MMU->LD_VAddr((Address & ~7), Value))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = _GPR[m_Opcode.rt].DW & LDR_MASK[Offset];
@ -1135,12 +1139,11 @@ void R4300iOp::LWL()
if (!g_MMU->LW_VAddr((Address & ~3), Value))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWL_MASK[Offset]);
@ -1236,12 +1239,11 @@ void R4300iOp::LWR()
if (!g_MMU->LW_VAddr((Address & ~3), Value))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_READ_EXCEPTION(Address);
}
_GPR[m_Opcode.rt].DW = (int32_t)(_GPR[m_Opcode.rt].W[0] & LWR_MASK[Offset]);
@ -1283,14 +1285,11 @@ void R4300iOp::SB()
}
if (!g_MMU->SB_VAddr(Address, _GPR[m_Opcode.rt].UB[0]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1307,14 +1306,11 @@ void R4300iOp::SH()
}
if (!g_MMU->SH_VAddr(Address, _GPR[m_Opcode.rt].UHW[0]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1331,15 +1327,11 @@ void R4300iOp::SWL()
if (!g_MMU->LW_VAddr((Address & ~3), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_WRITE_EXCEPTION(Address);
}
Value &= SWL_MASK[Offset];
@ -1347,14 +1339,11 @@ void R4300iOp::SWL()
if (!g_MMU->SW_VAddr((Address & ~0x03), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1375,14 +1364,11 @@ void R4300iOp::SW()
}
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1410,15 +1396,11 @@ void R4300iOp::SDL()
if (!g_MMU->LD_VAddr((Address & ~7), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_WRITE_EXCEPTION(Address);
}
Value &= SDL_MASK[Offset];
@ -1426,14 +1408,11 @@ void R4300iOp::SDL()
if (!g_MMU->SD_VAddr((Address & ~7), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1462,15 +1441,11 @@ void R4300iOp::SDR()
if (!g_MMU->LD_VAddr((Address & ~7), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_WRITE_EXCEPTION(Address);
}
Value &= SDR_MASK[Offset];
@ -1478,14 +1453,11 @@ void R4300iOp::SDR()
if (!g_MMU->SD_VAddr((Address & ~7), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1502,15 +1474,11 @@ void R4300iOp::SWR()
if (!g_MMU->LW_VAddr((Address & ~3), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_WRITE_EXCEPTION(Address);
}
Value &= SWR_MASK[Offset];
@ -1518,14 +1486,11 @@ void R4300iOp::SWR()
if (!g_MMU->SW_VAddr((Address & ~0x03), Value))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1604,11 +1569,11 @@ void R4300iOp::SC()
{
if (!g_MMU->SW_VAddr(Address, _GPR[m_Opcode.rt].UW[0]))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
_GPR[m_Opcode.rt].UW[0] = (*_LLBit);
@ -1627,15 +1592,11 @@ void R4300iOp::LD()
}
if (!g_MMU->LD_VAddr(Address, _GPR[m_Opcode.rt].UDW))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
return;
TLB_WRITE_EXCEPTION(Address);
}
#ifdef Interpreter_StackTest
if (m_Opcode.rt == 29)
@ -1660,14 +1621,11 @@ void R4300iOp::LDC1()
}
if (!g_MMU->LD_VAddr(Address, *(uint64_t *)_FPR_D[m_Opcode.ft]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_READ_EXCEPTION(Address);
}
}
@ -1686,14 +1644,11 @@ void R4300iOp::SWC1()
if (!g_MMU->SW_VAddr(Address, *(uint32_t *)_FPR_S[m_Opcode.ft]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1713,14 +1668,11 @@ void R4300iOp::SDC1()
}
if (!g_MMU->SD_VAddr(Address, *(int64_t *)_FPR_D[m_Opcode.ft]))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
@ -1737,14 +1689,11 @@ void R4300iOp::SD()
}
if (!g_MMU->SD_VAddr(Address, _GPR[m_Opcode.rt].UDW))
{
if (HaveDebugger())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", __FUNCTION__, Address).c_str());
}
TLB_WRITE_EXCEPTION(Address);
}
}
/********************** R4300i OpCodes: Special **********************/

View File

@ -454,7 +454,7 @@ void CRegisters::DoTrapException(bool DelaySlot)
}
void CRegisters::DoCopUnusableException(bool DelaySlot, int Coprocessor)
void CRegisters::DoCopUnusableException(bool DelaySlot, int32_t Coprocessor)
{
if (HaveDebugger())
{
@ -564,6 +564,44 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr)
}
}
void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr)
{
CAUSE_REGISTER = EXC_WMISS;
BAD_VADDR_REGISTER = BadVaddr;
CONTEXT_REGISTER &= 0xFF80000F;
CONTEXT_REGISTER |= (BadVaddr >> 9) & 0x007FFFF0;
ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000);
if ((STATUS_REGISTER & STATUS_EXL) == 0)
{
if (DelaySlot)
{
CAUSE_REGISTER |= CAUSE_BD;
EPC_REGISTER = m_PROGRAM_COUNTER - 4;
}
else
{
EPC_REGISTER = m_PROGRAM_COUNTER;
}
if (g_TLB->AddressDefined(BadVaddr))
{
m_PROGRAM_COUNTER = 0x80000180;
}
else
{
m_PROGRAM_COUNTER = 0x80000000;
}
STATUS_REGISTER |= STATUS_EXL;
}
else
{
if (HaveDebugger())
{
g_Notify->DisplayError(stdstr_f("TLBMiss - EXL Set\nBadVaddr = %X\nAddress Defined: %s", BadVaddr, g_TLB->AddressDefined(BadVaddr) ? "true" : "false").c_str());
}
m_PROGRAM_COUNTER = 0x80000180;
}
}
void CRegisters::DoSysCallException(bool DelaySlot)
{
if (HaveDebugger())

View File

@ -635,6 +635,7 @@ public:
void DoCopUnusableException( bool DelaySlot, int32_t Coprocessor );
bool DoIntrException( bool DelaySlot );
void DoTLBReadMiss(bool DelaySlot, uint32_t BadVaddr);
void DoTLBWriteMiss(bool DelaySlot, uint32_t BadVaddr);
void DoSysCallException ( bool DelaySlot);
void FixFpuLocations();
void Reset();