add remaining trap instructions, properly implement traps for the interpreter core

This commit is contained in:
KrimtonZ 2019-12-16 14:15:26 -06:00
parent b78a8d182d
commit b9be612ac5
5 changed files with 164 additions and 23 deletions

View File

@ -250,13 +250,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
Jump_Special[45] = SPECIAL_DADDU;
Jump_Special[46] = SPECIAL_DSUB;
Jump_Special[47] = SPECIAL_DSUBU;
Jump_Special[48] = UnknownOpcode;
Jump_Special[49] = UnknownOpcode;
Jump_Special[50] = UnknownOpcode;
Jump_Special[51] = UnknownOpcode;
Jump_Special[48] = SPECIAL_TGE;
Jump_Special[49] = SPECIAL_TGEU;
Jump_Special[50] = SPECIAL_TLT;
Jump_Special[51] = SPECIAL_TLTU;
Jump_Special[52] = SPECIAL_TEQ;
Jump_Special[53] = UnknownOpcode;
Jump_Special[54] = UnknownOpcode;
Jump_Special[54] = SPECIAL_TNE;
Jump_Special[55] = UnknownOpcode;
Jump_Special[56] = SPECIAL_DSLL;
Jump_Special[57] = UnknownOpcode;
@ -275,13 +275,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
Jump_Regimm[5] = UnknownOpcode;
Jump_Regimm[6] = UnknownOpcode;
Jump_Regimm[7] = UnknownOpcode;
Jump_Regimm[8] = UnknownOpcode;
Jump_Regimm[9] = UnknownOpcode;
Jump_Regimm[10] = UnknownOpcode;
Jump_Regimm[11] = UnknownOpcode;
Jump_Regimm[12] = UnknownOpcode;
Jump_Regimm[8] = REGIMM_TGEI;
Jump_Regimm[9] = REGIMM_TGEIU;
Jump_Regimm[10] = REGIMM_TLTI;
Jump_Regimm[11] = REGIMM_TLTIU;
Jump_Regimm[12] = REGIMM_TEQI;
Jump_Regimm[13] = UnknownOpcode;
Jump_Regimm[14] = UnknownOpcode;
Jump_Regimm[14] = REGIMM_TNEI;
Jump_Regimm[15] = UnknownOpcode;
Jump_Regimm[16] = REGIMM_BLTZAL;
Jump_Regimm[17] = REGIMM_BGEZAL;
@ -2050,7 +2050,59 @@ void R4300iOp::SPECIAL_TEQ()
{
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Notify->DisplayError("Should trap this ???");
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::SPECIAL_TGE()
{
if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::SPECIAL_TGEU()
{
if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::SPECIAL_TLT()
{
if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::SPECIAL_TLTU()
{
if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::SPECIAL_TNE()
{
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
@ -2220,6 +2272,67 @@ void R4300iOp::REGIMM_BGEZAL()
}
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
}
void R4300iOp::REGIMM_TEQI()
{
if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::REGIMM_TGEI()
{
if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::REGIMM_TGEIU()
{
if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::REGIMM_TLTI()
{
if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::REGIMM_TLTIU()
{
if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
void R4300iOp::REGIMM_TNEI()
{
if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate && HaveDebugger())
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER);
}
}
/************************** COP0 functions **************************/
void R4300iOp::COP0_MF()
{

View File

@ -110,7 +110,12 @@ public:
static void SPECIAL_DADDU();
static void SPECIAL_DSUB();
static void SPECIAL_DSUBU();
static void SPECIAL_TGE();
static void SPECIAL_TGEU();
static void SPECIAL_TLT();
static void SPECIAL_TLTU();
static void SPECIAL_TEQ();
static void SPECIAL_TNE();
static void SPECIAL_DSLL();
static void SPECIAL_DSRL();
static void SPECIAL_DSRA();
@ -125,6 +130,12 @@ public:
static void REGIMM_BGEZL();
static void REGIMM_BLTZAL();
static void REGIMM_BGEZAL();
static void REGIMM_TEQI();
static void REGIMM_TGEI();
static void REGIMM_TGEIU();
static void REGIMM_TLTI();
static void REGIMM_TLTIU();
static void REGIMM_TNEI();
/************************** COP0 functions **************************/
static void COP0_MF();

View File

@ -155,13 +155,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
Jump_Special[45] = R4300iOp::SPECIAL_DADDU;
Jump_Special[46] = R4300iOp::SPECIAL_DSUB;
Jump_Special[47] = R4300iOp::SPECIAL_DSUBU;
Jump_Special[48] = R4300iOp::UnknownOpcode;
Jump_Special[49] = R4300iOp::UnknownOpcode;
Jump_Special[50] = R4300iOp::UnknownOpcode;
Jump_Special[51] = R4300iOp::UnknownOpcode;
Jump_Special[48] = R4300iOp::SPECIAL_TGE;
Jump_Special[49] = R4300iOp::SPECIAL_TGEU;
Jump_Special[50] = R4300iOp::SPECIAL_TLT;
Jump_Special[51] = R4300iOp::SPECIAL_TLTU;
Jump_Special[52] = R4300iOp::SPECIAL_TEQ;
Jump_Special[53] = R4300iOp::UnknownOpcode;
Jump_Special[54] = R4300iOp::UnknownOpcode;
Jump_Special[54] = R4300iOp::SPECIAL_TNE;
Jump_Special[55] = R4300iOp::UnknownOpcode;
Jump_Special[56] = R4300iOp::SPECIAL_DSLL;
Jump_Special[57] = R4300iOp::UnknownOpcode;
@ -180,13 +180,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
Jump_Regimm[5] = R4300iOp::UnknownOpcode;
Jump_Regimm[6] = R4300iOp::UnknownOpcode;
Jump_Regimm[7] = R4300iOp::UnknownOpcode;
Jump_Regimm[8] = R4300iOp::UnknownOpcode;
Jump_Regimm[9] = R4300iOp::UnknownOpcode;
Jump_Regimm[10] = R4300iOp::UnknownOpcode;
Jump_Regimm[11] = R4300iOp::UnknownOpcode;
Jump_Regimm[12] = R4300iOp::UnknownOpcode;
Jump_Regimm[8] = R4300iOp::REGIMM_TGEI;
Jump_Regimm[9] = R4300iOp::REGIMM_TGEIU;
Jump_Regimm[10] = R4300iOp::REGIMM_TLTI;
Jump_Regimm[11] = R4300iOp::REGIMM_TLTIU;
Jump_Regimm[12] = R4300iOp::REGIMM_TEQI;
Jump_Regimm[13] = R4300iOp::UnknownOpcode;
Jump_Regimm[14] = R4300iOp::UnknownOpcode;
Jump_Regimm[14] = R4300iOp::REGIMM_TNEI;
Jump_Regimm[15] = R4300iOp::UnknownOpcode;
Jump_Regimm[16] = REGIMM_BLTZAL;
Jump_Regimm[17] = REGIMM_BGEZAL;

View File

@ -438,6 +438,22 @@ void CRegisters::DoBreakException(bool DelaySlot)
m_PROGRAM_COUNTER = 0x80000180;
}
void CRegisters::DoTrapException(bool DelaySlot)
{
CAUSE_REGISTER = EXC_TRAP;
if (DelaySlot)
{
EPC_REGISTER = m_PROGRAM_COUNTER - 4;
CAUSE_REGISTER |= CAUSE_BD;
}
else
{
EPC_REGISTER = m_PROGRAM_COUNTER;
}
m_PROGRAM_COUNTER = 0x80000180;
}
void CRegisters::DoCopUnusableException(bool DelaySlot, int Coprocessor)
{
if (HaveDebugger())

View File

@ -631,6 +631,7 @@ public:
void CheckInterrupts ();
void DoAddressError ( bool DelaySlot, uint32_t BadVaddr, bool FromRead );
void DoBreakException ( bool DelaySlot );
void DoTrapException ( bool DelaySlot );
void DoCopUnusableException ( bool DelaySlot, int32_t Coprocessor );
bool DoIntrException ( bool DelaySlot );
void DoTLBReadMiss ( bool DelaySlot, uint32_t BadVaddr );