Update the N64 System/Interpreter files to allman

This commit is contained in:
Ryan Collins 2015-03-29 11:02:27 -04:00
parent 2a3d1c09ff
commit 1b4d2d0cfb
3 changed files with 742 additions and 294 deletions

View File

@ -17,18 +17,22 @@ void ExecuteInterpreterOps (DWORD /*Cycles*/)
g_Notify->BreakPoint(__FILEW__,__LINE__); g_Notify->BreakPoint(__FILEW__,__LINE__);
} }
bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) { bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2)
{
OPCODE Command; OPCODE Command;
if (!g_MMU->LW_VAddr(PC + 4, Command.Hex)) { if (!g_MMU->LW_VAddr(PC + 4, Command.Hex))
{
//g_Notify->DisplayError(L"Failed to load word 2"); //g_Notify->DisplayError(L"Failed to load word 2");
//ExitThread(0); //ExitThread(0);
return TRUE; return TRUE;
} }
switch (Command.op) { switch (Command.op)
{
case R4300i_SPECIAL: case R4300i_SPECIAL:
switch (Command.funct) { switch (Command.funct)
{
case R4300i_SPECIAL_SLL: case R4300i_SPECIAL_SLL:
case R4300i_SPECIAL_SRL: case R4300i_SPECIAL_SRL:
case R4300i_SPECIAL_SRA: case R4300i_SPECIAL_SRA:
@ -62,9 +66,18 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSLL32:
case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRL32:
case R4300i_SPECIAL_DSRA32: case R4300i_SPECIAL_DSRA32:
if (Command.rd == 0) { return FALSE; } if (Command.rd == 0)
if (Command.rd == Reg1) { return TRUE; } {
if (Command.rd == Reg2) { return TRUE; } return FALSE;
}
if (Command.rd == Reg1)
{
return TRUE;
}
if (Command.rd == Reg2)
{
return TRUE;
}
break; break;
case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULT:
case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_MULTU:
@ -84,16 +97,28 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
} }
break; break;
case R4300i_CP0: case R4300i_CP0:
switch (Command.rs) { switch (Command.rs)
{
case R4300i_COP0_MT: break; case R4300i_COP0_MT: break;
case R4300i_COP0_MF: case R4300i_COP0_MF:
if (Command.rt == 0) { return FALSE; } if (Command.rt == 0)
if (Command.rt == Reg1) { return TRUE; } {
if (Command.rt == Reg2) { return TRUE; } return FALSE;
}
if (Command.rt == Reg1)
{
return TRUE;
}
if (Command.rt == Reg2)
{
return TRUE;
}
break; break;
default: default:
if ( (Command.rs & 0x10 ) != 0 ) { if ( (Command.rs & 0x10 ) != 0 )
switch( Command.funct ) { {
switch ( Command.funct )
{
case R4300i_COP0_CO_TLBR: break; case R4300i_COP0_CO_TLBR: break;
case R4300i_COP0_CO_TLBWI: break; case R4300i_COP0_CO_TLBWI: break;
case R4300i_COP0_CO_TLBWR: break; case R4300i_COP0_CO_TLBWR: break;
@ -105,7 +130,9 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
} }
return TRUE; return TRUE;
} }
} else { }
else
{
if (g_Settings->LoadBool(Debugger_Enabled)) if (g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(L"Does %s effect Delay slot at %X?\n7",R4300iOpcodeName(Command.Hex,PC+4), PC); g_Notify->DisplayError(L"Does %s effect Delay slot at %X?\n7",R4300iOpcodeName(Command.Hex,PC+4), PC);
@ -115,11 +142,21 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
} }
break; break;
case R4300i_CP1: case R4300i_CP1:
switch (Command.fmt) { switch (Command.fmt)
{
case R4300i_COP1_MF: case R4300i_COP1_MF:
if (Command.rt == 0) { return FALSE; } if (Command.rt == 0)
if (Command.rt == Reg1) { return TRUE; } {
if (Command.rt == Reg2) { return TRUE; } return FALSE;
}
if (Command.rt == Reg1)
{
return TRUE;
}
if (Command.rt == Reg2)
{
return TRUE;
}
break; break;
case R4300i_COP1_CF: break; case R4300i_COP1_CF: break;
case R4300i_COP1_MT: break; case R4300i_COP1_MT: break;
@ -158,9 +195,18 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
case R4300i_LD: case R4300i_LD:
case R4300i_LWC1: case R4300i_LWC1:
case R4300i_LDC1: case R4300i_LDC1:
if (Command.rt == 0) { return FALSE; } if (Command.rt == 0)
if (Command.rt == Reg1) { return TRUE; } {
if (Command.rt == Reg2) { return TRUE; } return FALSE;
}
if (Command.rt == Reg1)
{
return TRUE;
}
if (Command.rt == Reg2)
{
return TRUE;
}
break; break;
case R4300i_CACHE: break; case R4300i_CACHE: break;
case R4300i_SB: break; case R4300i_SB: break;
@ -181,7 +227,7 @@ bool DelaySlotEffectsCompare (DWORD PC, DWORD Reg1, DWORD Reg2) {
return FALSE; return FALSE;
} }
void CInterpreterCPU::BuildCPU (void ) void CInterpreterCPU::BuildCPU (void)
{ {
R4300iOp::m_TestTimer = FALSE; R4300iOp::m_TestTimer = FALSE;
R4300iOp::m_NextInstruction = NORMAL; R4300iOp::m_NextInstruction = NORMAL;
@ -190,14 +236,20 @@ void CInterpreterCPU::BuildCPU (void )
if (g_Settings->LoadBool(Game_32Bit)) if (g_Settings->LoadBool(Game_32Bit))
{ {
m_R4300i_Opcode = R4300iOp32::BuildInterpreter(); m_R4300i_Opcode = R4300iOp32::BuildInterpreter();
} else { }
else
{
m_R4300i_Opcode = R4300iOp::BuildInterpreter(); m_R4300i_Opcode = R4300iOp::BuildInterpreter();
} }
} }
void CInterpreterCPU::InPermLoop (void) { void CInterpreterCPU::InPermLoop (void)
{
// *** Changed ***/ // *** Changed ***/
//if (CPU_Type == CPU_SyncCores) { SyncRegisters.CP0[9] +=5; } //if (CPU_Type == CPU_SyncCores)
//{
// SyncRegisters.CP0[9] +=5;
//}
/* Interrupts enabled */ /* Interrupts enabled */
if (( g_Reg->STATUS_REGISTER & STATUS_IE ) == 0 || if (( g_Reg->STATUS_REGISTER & STATUS_IE ) == 0 ||
@ -205,21 +257,27 @@ void CInterpreterCPU::InPermLoop (void) {
( g_Reg->STATUS_REGISTER & STATUS_ERL ) != 0 || ( g_Reg->STATUS_REGISTER & STATUS_ERL ) != 0 ||
( g_Reg->STATUS_REGISTER & 0xFF00) == 0) ( g_Reg->STATUS_REGISTER & 0xFF00) == 0)
{ {
if (g_Plugins->Gfx()->UpdateScreen != NULL) { g_Plugins->Gfx()->UpdateScreen(); } if (g_Plugins->Gfx()->UpdateScreen != NULL)
{
_Plugins->Gfx()->UpdateScreen();
}
//CurrentFrame = 0; //CurrentFrame = 0;
//CurrentPercent = 0; //CurrentPercent = 0;
//DisplayFPS(); //DisplayFPS();
g_Notify->DisplayError(GS(MSG_PERM_LOOP)); g_Notify->DisplayError(GS(MSG_PERM_LOOP));
g_System->CloseCpu(); g_System->CloseCpu();
} else { }
if (*g_NextTimer > 0) { else
{
if (*g_NextTimer > 0)
{
*g_NextTimer = 0 - g_System->CountPerOp(); *g_NextTimer = 0 - g_System->CountPerOp();
g_SystemTimer->UpdateTimers(); g_SystemTimer->UpdateTimers();
} }
} }
} }
void CInterpreterCPU::ExecuteCPU (void ) void CInterpreterCPU::ExecuteCPU (void)
{ {
bool & Done = g_System->m_EndEmulation; bool & Done = g_System->m_EndEmulation;
DWORD & PROGRAM_COUNTER = *_PROGRAM_COUNTER; DWORD & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
@ -232,7 +290,7 @@ void CInterpreterCPU::ExecuteCPU (void )
__try __try
{ {
while(!Done) while (!Done)
{ {
if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex)) if (g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex))
{ {
@ -290,12 +348,15 @@ void CInterpreterCPU::ExecuteCPU (void )
default: default:
g_Notify->BreakPoint(__FILEW__,__LINE__); g_Notify->BreakPoint(__FILEW__,__LINE__);
} }
} else { }
else
{
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER); g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL; R4300iOp::m_NextInstruction = NORMAL;
} }
} }
} __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) { } __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
{
g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION)); g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION));
ExitThread(0); ExitThread(0);
} }
@ -314,7 +375,7 @@ void CInterpreterCPU::ExecuteOps ( int Cycles )
__try __try
{ {
while(!Done) while (!Done)
{ {
if (Cycles <= 0) if (Cycles <= 0)
{ {
@ -397,12 +458,15 @@ void CInterpreterCPU::ExecuteOps ( int Cycles )
default: default:
g_Notify->BreakPoint(__FILEW__,__LINE__); g_Notify->BreakPoint(__FILEW__,__LINE__);
} }
} else { }
else
{
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER); g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP,PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL; R4300iOp::m_NextInstruction = NORMAL;
} }
} }
} __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) ) { } __except( g_MMU->MemoryFilter( GetExceptionCode(), GetExceptionInformation()) )
{
g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION)); g_Notify->DisplayError(GS(MSG_UNKNOWN_MEM_ACTION));
ExitThread(0); ExitThread(0);
} }

View File

@ -628,7 +628,8 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter (void )
/************************* Opcode functions *************************/ /************************* Opcode functions *************************/
void R4300iOp32::JAL (void) { void R4300iOp32::JAL (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2); m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
_GPR[31].UW[0] = (*_PROGRAM_COUNTER) + 8; _GPR[31].UW[0] = (*_PROGRAM_COUNTER) + 8;
@ -639,9 +640,11 @@ void R4300iOp32::JAL (void) {
} }
} }
void R4300iOp32::BEQ (void) { void R4300iOp32::BEQ (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) { if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0])
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -650,14 +653,18 @@ void R4300iOp32::BEQ (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BNE (void) { void R4300iOp32::BNE (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) { if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0])
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -666,14 +673,17 @@ void R4300iOp32::BNE (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BLEZ (void) { void R4300iOp32::BLEZ (void) {
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] <= 0) { if (_GPR[m_Opcode.rs].W[0] <= 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -682,14 +692,18 @@ void R4300iOp32::BLEZ (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BGTZ (void) { void R4300iOp32::BGTZ (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] > 0) { if (_GPR[m_Opcode.rs].W[0] > 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -698,48 +712,61 @@ void R4300iOp32::BGTZ (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::ADDI (void) { void R4300iOp32::ADDI (void)
{
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rs == 29 && m_Opcode.rt == 29) { if (m_Opcode.rs == 29 && m_Opcode.rt == 29)
{
StackValue += (short)m_Opcode.immediate; StackValue += (short)m_Opcode.immediate;
} }
#endif #endif
_GPR[m_Opcode.rt].W[0] = (_GPR[m_Opcode.rs].W[0] + ((short)m_Opcode.immediate)); _GPR[m_Opcode.rt].W[0] = (_GPR[m_Opcode.rs].W[0] + ((short)m_Opcode.immediate));
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rt == 29 && m_Opcode.rs != 29) { if (m_Opcode.rt == 29 && m_Opcode.rs != 29)
{
StackValue = _GPR[m_Opcode.rt].W[0]; StackValue = _GPR[m_Opcode.rt].W[0];
} }
#endif #endif
} }
void R4300iOp32::ADDIU (void) { void R4300iOp32::ADDIU (void)
{
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rs == 29 && m_Opcode.rt == 29) { if (m_Opcode.rs == 29 && m_Opcode.rt == 29)
{
StackValue += (short)m_Opcode.immediate; StackValue += (short)m_Opcode.immediate;
} }
#endif #endif
_GPR[m_Opcode.rt].W[0] = (_GPR[m_Opcode.rs].W[0] + ((short)m_Opcode.immediate)); _GPR[m_Opcode.rt].W[0] = (_GPR[m_Opcode.rs].W[0] + ((short)m_Opcode.immediate));
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rt == 29 && m_Opcode.rs != 29) { if (m_Opcode.rt == 29 && m_Opcode.rs != 29)
{
StackValue = _GPR[m_Opcode.rt].W[0]; StackValue = _GPR[m_Opcode.rt].W[0];
} }
#endif #endif
} }
void R4300iOp32::SLTI (void) { void R4300iOp32::SLTI (void)
if (_GPR[m_Opcode.rs].W[0] < (__int64)((short)m_Opcode.immediate)) { {
if (_GPR[m_Opcode.rs].W[0] < (__int64)((short)m_Opcode.immediate))
{
_GPR[m_Opcode.rt].W[0] = 1; _GPR[m_Opcode.rt].W[0] = 1;
} else { }
else
{
_GPR[m_Opcode.rt].W[0] = 0; _GPR[m_Opcode.rt].W[0] = 0;
} }
} }
void R4300iOp32::SLTIU (void) { void R4300iOp32::SLTIU (void)
{
int imm32 = (short)m_Opcode.immediate; int imm32 = (short)m_Opcode.immediate;
__int64 imm64; __int64 imm64;
@ -747,29 +774,36 @@ void R4300iOp32::SLTIU (void) {
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].UW[0] < (unsigned __int64)imm64?1:0; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].UW[0] < (unsigned __int64)imm64?1:0;
} }
void R4300iOp32::ANDI (void) { void R4300iOp32::ANDI (void)
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] & m_Opcode.immediate; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] & m_Opcode.immediate;
} }
void R4300iOp32::ORI (void) { void R4300iOp32::ORI (void)
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] | m_Opcode.immediate; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] | m_Opcode.immediate;
} }
void R4300iOp32::XORI (void) { void R4300iOp32::XORI (void)
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] ^ m_Opcode.immediate; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rs].W[0] ^ m_Opcode.immediate;
} }
void R4300iOp32::LUI (void) { void R4300iOp32::LUI (void)
{
_GPR[m_Opcode.rt].W[0] = (long)((short)m_Opcode.offset << 16); _GPR[m_Opcode.rt].W[0] = (long)((short)m_Opcode.offset << 16);
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rt == 29) { if (m_Opcode.rt == 29)
{
StackValue = _GPR[m_Opcode.rt].W[0]; StackValue = _GPR[m_Opcode.rt].W[0];
} }
#endif #endif
} }
void R4300iOp32::BEQL (void) { void R4300iOp32::BEQL (void)
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) { {
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0])
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -779,14 +813,18 @@ void R4300iOp32::BEQL (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BNEL (void) { void R4300iOp32::BNEL (void)
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) { {
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0])
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -796,14 +834,18 @@ void R4300iOp32::BNEL (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BLEZL (void) { void R4300iOp32::BLEZL (void)
if (_GPR[m_Opcode.rs].W[0] <= 0) { {
if (_GPR[m_Opcode.rs].W[0] <= 0)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -813,14 +855,18 @@ void R4300iOp32::BLEZL (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BGTZL (void) { void R4300iOp32::BGTZL (void)
if (_GPR[m_Opcode.rs].W[0] > 0) { {
if (_GPR[m_Opcode.rs].W[0] > 0)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -830,38 +876,54 @@ void R4300iOp32::BGTZL (void) {
m_NextInstruction = PERMLOOP_DO_DELAY; m_NextInstruction = PERMLOOP_DO_DELAY;
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::LB (void) { void R4300iOp32::LB (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if (!g_MMU->LB_VAddr(Address,_GPR[m_Opcode.rt].UB[0])) { if (!g_MMU->LB_VAddr(Address,_GPR[m_Opcode.rt].UB[0]))
if (bShowTLBMisses()) { {
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LB TLB: %X",Address); g_Notify->DisplayError(L"LB TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].B[0]; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].B[0];
} }
} }
void R4300iOp32::LH (void) { void R4300iOp32::LH (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 1) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); } if ((Address & 1) != 0)
if (!g_MMU->LH_VAddr(Address,_GPR[m_Opcode.rt].UHW[0])) { {
if (bShowTLBMisses()) { ADDRESS_ERROR_EXCEPTION(Address,TRUE);
}
if (!g_MMU->LH_VAddr(Address,_GPR[m_Opcode.rt].UHW[0]))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LH TLB: %X",Address); g_Notify->DisplayError(L"LH TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].HW[0]; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].HW[0];
} }
} }
void R4300iOp32::LWL (void) { void R4300iOp32::LWL (void)
{
DWORD Offset, Address, Value; DWORD Offset, Address, Value;
Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
@ -869,7 +931,8 @@ void R4300iOp32::LWL (void) {
if (!g_MMU->LW_VAddr((Address & ~3),Value)) if (!g_MMU->LW_VAddr((Address & ~3),Value))
{ {
if (bShowTLBMisses()) { if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LWL TLB: %X",Address); g_Notify->DisplayError(L"LWL TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
@ -880,51 +943,73 @@ void R4300iOp32::LWL (void) {
_GPR[m_Opcode.rt].W[0] += (int)(Value << LWL_SHIFT[Offset]); _GPR[m_Opcode.rt].W[0] += (int)(Value << LWL_SHIFT[Offset]);
} }
void R4300iOp32::LW (void) { void R4300iOp32::LW (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); } if ((Address & 3) != 0)
{
ADDRESS_ERROR_EXCEPTION(Address,TRUE);
}
if (LogOptions.GenerateLog) if (LogOptions.GenerateLog)
{ {
Log_LW((*_PROGRAM_COUNTER),Address); Log_LW((*_PROGRAM_COUNTER),Address);
} }
if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0])) { if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0]))
if (bShowTLBMisses()) { {
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LW TLB: %X",Address); g_Notify->DisplayError(L"LW TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0];
} }
} }
void R4300iOp32::LBU (void) { void R4300iOp32::LBU (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if (!g_MMU->LB_VAddr(Address,_GPR[m_Opcode.rt].UB[0])) { if (!g_MMU->LB_VAddr(Address,_GPR[m_Opcode.rt].UB[0]))
if (bShowTLBMisses()) { {
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LBU TLB: %X",Address); g_Notify->DisplayError(L"LBU TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UB[0]; _GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UB[0];
} }
} }
void R4300iOp32::LHU (void) { void R4300iOp32::LHU (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 1) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); } if ((Address & 1) != 0)
if (!g_MMU->LH_VAddr(Address,_GPR[m_Opcode.rt].UHW[0])) { {
if (bShowTLBMisses()) { ADDRESS_ERROR_EXCEPTION(Address,TRUE);
}
if (!g_MMU->LH_VAddr(Address,_GPR[m_Opcode.rt].UHW[0]))
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LHU TLB: %X",Address); g_Notify->DisplayError(L"LHU TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UHW[0]; _GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UHW[0];
} }
} }
void R4300iOp32::LWR (void) { void R4300iOp32::LWR (void)
{
DWORD Offset, Address, Value; DWORD Offset, Address, Value;
Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
@ -944,118 +1029,158 @@ void R4300iOp32::LWR (void) {
_GPR[m_Opcode.rt].W[0] += (int)(Value >> LWR_SHIFT[Offset]); _GPR[m_Opcode.rt].W[0] += (int)(Value >> LWR_SHIFT[Offset]);
} }
void R4300iOp32::LWU (void) { void R4300iOp32::LWU (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); } if ((Address & 3) != 0)
{
ADDRESS_ERROR_EXCEPTION(Address,TRUE);
}
if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0])) { if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0]))
if (bShowTLBMisses()) { {
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LWU TLB: %X",Address); g_Notify->DisplayError(L"LWU TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UW[0]; _GPR[m_Opcode.rt].UW[0] = _GPR[m_Opcode.rt].UW[0];
} }
} }
void R4300iOp32::LL (void) { void R4300iOp32::LL (void)
{
DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset; DWORD Address = _GPR[m_Opcode.base].UW[0] + (short)m_Opcode.offset;
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,TRUE); } if ((Address & 3) != 0)
{
ADDRESS_ERROR_EXCEPTION(Address,TRUE);
}
if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0])) { if (!g_MMU->LW_VAddr(Address,_GPR[m_Opcode.rt].UW[0]))
if (bShowTLBMisses()) { {
if (bShowTLBMisses())
{
g_Notify->DisplayError(L"LL TLB: %X",Address); g_Notify->DisplayError(L"LL TLB: %X",Address);
} }
TLB_READ_EXCEPTION(Address); TLB_READ_EXCEPTION(Address);
} else { }
else
{
_GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rt].W[0] = _GPR[m_Opcode.rt].W[0];
(*_LLBit) = 1; (*_LLBit) = 1;
} }
} }
/********************** R4300i OpCodes: Special **********************/ /********************** R4300i OpCodes: Special **********************/
void R4300iOp32::SPECIAL_SLL (void) { void R4300iOp32::SPECIAL_SLL (void)
{
_GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] << m_Opcode.sa); _GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] << m_Opcode.sa);
} }
void R4300iOp32::SPECIAL_SRL (void) { void R4300iOp32::SPECIAL_SRL (void)
{
_GPR[m_Opcode.rd].W[0] = (int)(_GPR[m_Opcode.rt].UW[0] >> m_Opcode.sa); _GPR[m_Opcode.rd].W[0] = (int)(_GPR[m_Opcode.rt].UW[0] >> m_Opcode.sa);
} }
void R4300iOp32::SPECIAL_SRA (void) { void R4300iOp32::SPECIAL_SRA (void)
{
_GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] >> m_Opcode.sa); _GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] >> m_Opcode.sa);
} }
void R4300iOp32::SPECIAL_SLLV (void) { void R4300iOp32::SPECIAL_SLLV (void)
{
_GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] << (_GPR[m_Opcode.rs].UW[0] & 0x1F)); _GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] << (_GPR[m_Opcode.rs].UW[0] & 0x1F));
} }
void R4300iOp32::SPECIAL_SRLV (void) { void R4300iOp32::SPECIAL_SRLV (void)
{
_GPR[m_Opcode.rd].W[0] = (int)(_GPR[m_Opcode.rt].UW[0] >> (_GPR[m_Opcode.rs].UW[0] & 0x1F)); _GPR[m_Opcode.rd].W[0] = (int)(_GPR[m_Opcode.rt].UW[0] >> (_GPR[m_Opcode.rs].UW[0] & 0x1F));
} }
void R4300iOp32::SPECIAL_SRAV (void) { void R4300iOp32::SPECIAL_SRAV (void)
{
_GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] >> (_GPR[m_Opcode.rs].UW[0] & 0x1F)); _GPR[m_Opcode.rd].W[0] = (_GPR[m_Opcode.rt].W[0] >> (_GPR[m_Opcode.rs].UW[0] & 0x1F));
} }
void R4300iOp32::SPECIAL_JALR (void) { void R4300iOp32::SPECIAL_JALR (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = _GPR[m_Opcode.rs].UW[0]; m_JumpToLocation = _GPR[m_Opcode.rs].UW[0];
_GPR[m_Opcode.rd].W[0] = (long)((*_PROGRAM_COUNTER) + 8); _GPR[m_Opcode.rd].W[0] = (long)((*_PROGRAM_COUNTER) + 8);
m_TestTimer = TRUE; m_TestTimer = TRUE;
} }
void R4300iOp32::SPECIAL_ADD (void) { void R4300iOp32::SPECIAL_ADD (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] + _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] + _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp32::SPECIAL_ADDU (void) { void R4300iOp32::SPECIAL_ADDU (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] + _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] + _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp32::SPECIAL_SUB (void) { void R4300iOp32::SPECIAL_SUB (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] - _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] - _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp32::SPECIAL_SUBU (void) { void R4300iOp32::SPECIAL_SUBU (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] - _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] - _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp32::SPECIAL_AND (void) { void R4300iOp32::SPECIAL_AND (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] & _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] & _GPR[m_Opcode.rt].W[0];
} }
void R4300iOp32::SPECIAL_OR (void) { void R4300iOp32::SPECIAL_OR (void)
{
_GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] | _GPR[m_Opcode.rt].W[0]; _GPR[m_Opcode.rd].W[0] = _GPR[m_Opcode.rs].W[0] | _GPR[m_Opcode.rt].W[0];
#ifdef Interpreter_StackTest #ifdef Interpreter_StackTest
if (m_Opcode.rd == 29) { if (m_Opcode.rd == 29)
{
StackValue = _GPR[m_Opcode.rd].W[0]; StackValue = _GPR[m_Opcode.rd].W[0];
} }
#endif #endif
} }
void R4300iOp32::SPECIAL_NOR (void) { void R4300iOp32::SPECIAL_NOR (void)
{
_GPR[m_Opcode.rd].W[0] = ~(_GPR[m_Opcode.rs].W[0] | _GPR[m_Opcode.rt].W[0]); _GPR[m_Opcode.rd].W[0] = ~(_GPR[m_Opcode.rs].W[0] | _GPR[m_Opcode.rt].W[0]);
} }
void R4300iOp32::SPECIAL_SLT (void) { void R4300iOp32::SPECIAL_SLT (void)
if (_GPR[m_Opcode.rs].W[0] < _GPR[m_Opcode.rt].W[0]) { {
if (_GPR[m_Opcode.rs].W[0] < _GPR[m_Opcode.rt].W[0])
{
_GPR[m_Opcode.rd].W[0] = 1; _GPR[m_Opcode.rd].W[0] = 1;
} else { }
else
{
_GPR[m_Opcode.rd].W[0] = 0; _GPR[m_Opcode.rd].W[0] = 0;
} }
} }
void R4300iOp32::SPECIAL_SLTU (void) { void R4300iOp32::SPECIAL_SLTU (void)
if (_GPR[m_Opcode.rs].UW[0] < _GPR[m_Opcode.rt].UW[0]) { {
if (_GPR[m_Opcode.rs].UW[0] < _GPR[m_Opcode.rt].UW[0])
{
_GPR[m_Opcode.rd].W[0] = 1; _GPR[m_Opcode.rd].W[0] = 1;
} else { }
else
{
_GPR[m_Opcode.rd].W[0] = 0; _GPR[m_Opcode.rd].W[0] = 0;
} }
} }
void R4300iOp32::SPECIAL_TEQ (void) { void R4300iOp32::SPECIAL_TEQ (void)
{
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0] && g_Settings->LoadBool(Debugger_Enabled)) if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0] && g_Settings->LoadBool(Debugger_Enabled))
{ {
g_Notify->DisplayError(L"Should trap this ???"); g_Notify->DisplayError(L"Should trap this ???");
@ -1073,9 +1198,11 @@ void R4300iOp32::SPECIAL_DSRA32 (void)
} }
/********************** R4300i OpCodes: RegImm **********************/ /********************** R4300i OpCodes: RegImm **********************/
void R4300iOp32::REGIMM_BLTZ (void) { void R4300iOp32::REGIMM_BLTZ (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) { if (_GPR[m_Opcode.rs].W[0] < 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -1084,14 +1211,18 @@ void R4300iOp32::REGIMM_BLTZ (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BGEZ (void) { void R4300iOp32::REGIMM_BGEZ (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) { if (_GPR[m_Opcode.rs].W[0] >= 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -1100,13 +1231,17 @@ void R4300iOp32::REGIMM_BGEZ (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BLTZL (void) { void R4300iOp32::REGIMM_BLTZL (void)
if (_GPR[m_Opcode.rs].W[0] < 0) { {
if (_GPR[m_Opcode.rs].W[0] < 0)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -1116,14 +1251,18 @@ void R4300iOp32::REGIMM_BLTZL (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BGEZL (void) { void R4300iOp32::REGIMM_BGEZL (void)
if (_GPR[m_Opcode.rs].W[0] >= 0) { {
if (_GPR[m_Opcode.rs].W[0] >= 0)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
@ -1133,15 +1272,19 @@ void R4300iOp32::REGIMM_BGEZL (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_NextInstruction = JUMP; m_NextInstruction = JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BLTZAL (void) { void R4300iOp32::REGIMM_BLTZAL (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) { if (_GPR[m_Opcode.rs].W[0] < 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -1150,15 +1293,19 @@ void R4300iOp32::REGIMM_BLTZAL (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].W[0]= (long)((*_PROGRAM_COUNTER) + 8); _GPR[31].W[0]= (long)((*_PROGRAM_COUNTER) + 8);
} }
void R4300iOp32::REGIMM_BGEZAL (void) { void R4300iOp32::REGIMM_BGEZAL (void)
{
m_NextInstruction = DELAY_SLOT; m_NextInstruction = DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) { if (_GPR[m_Opcode.rs].W[0] >= 0)
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4; m_JumpToLocation = (*_PROGRAM_COUNTER) + ((short)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == m_JumpToLocation)
{ {
@ -1167,7 +1314,9 @@ void R4300iOp32::REGIMM_BGEZAL (void) {
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
} }
} }
} else { }
else
{
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].W[0] = (long)((*_PROGRAM_COUNTER) + 8); _GPR[31].W[0] = (long)((*_PROGRAM_COUNTER) + 8);
@ -1186,16 +1335,19 @@ void R4300iOp32::COP0_MF (void) {
_GPR[m_Opcode.rt].W[0] = (int)_CP0[m_Opcode.rd]; _GPR[m_Opcode.rt].W[0] = (int)_CP0[m_Opcode.rd];
} }
void R4300iOp32::COP0_MT (void) { void R4300iOp32::COP0_MT (void)
{
if (LogOptions.LogCP0changes) if (LogOptions.LogCP0changes)
{ {
LogMessage("%08X: Writing 0x%X to %s register (Originally: 0x%08X)",(*_PROGRAM_COUNTER), _GPR[m_Opcode.rt].UW[0],CRegName::Cop0[m_Opcode.rd], _CP0[m_Opcode.rd]); LogMessage("%08X: Writing 0x%X to %s register (Originally: 0x%08X)",(*_PROGRAM_COUNTER), _GPR[m_Opcode.rt].UW[0],CRegName::Cop0[m_Opcode.rd], _CP0[m_Opcode.rd]);
if (m_Opcode.rd == 11) { //Compare if (m_Opcode.rd == 11) //Compare
{
LogMessage("%08X: Cause register changed from %08X to %08X",(*_PROGRAM_COUNTER), g_Reg->CAUSE_REGISTER, (g_Reg->CAUSE_REGISTER & ~CAUSE_IP7)); LogMessage("%08X: Cause register changed from %08X to %08X",(*_PROGRAM_COUNTER), g_Reg->CAUSE_REGISTER, (g_Reg->CAUSE_REGISTER & ~CAUSE_IP7));
} }
} }
switch (m_Opcode.rd) { switch (m_Opcode.rd)
{
case 0: //Index case 0: //Index
case 2: //EntryLo0 case 2: //EntryLo0
case 3: //EntryLo1 case 3: //EntryLo1
@ -1229,10 +1381,13 @@ void R4300iOp32::COP0_MT (void) {
g_SystemTimer->UpdateCompareTimer(); g_SystemTimer->UpdateCompareTimer();
break; break;
case 12: //Status case 12: //Status
if ((_CP0[m_Opcode.rd] & STATUS_FR) != (_GPR[m_Opcode.rt].UW[0] & STATUS_FR)) { if ((_CP0[m_Opcode.rd] & STATUS_FR) != (_GPR[m_Opcode.rt].UW[0] & STATUS_FR))
{
_CP0[m_Opcode.rd] = _GPR[m_Opcode.rt].UW[0]; _CP0[m_Opcode.rd] = _GPR[m_Opcode.rt].UW[0];
g_Reg->FixFpuLocations(); g_Reg->FixFpuLocations();
} else { }
else
{
_CP0[m_Opcode.rd] = _GPR[m_Opcode.rt].UW[0]; _CP0[m_Opcode.rd] = _GPR[m_Opcode.rt].UW[0];
} }
if ((_CP0[m_Opcode.rd] & 0x18) != 0 && g_Settings->LoadBool(Debugger_Enabled)) if ((_CP0[m_Opcode.rd] & 0x18) != 0 && g_Settings->LoadBool(Debugger_Enabled))
@ -1254,12 +1409,14 @@ void R4300iOp32::COP0_MT (void) {
} }
/************************** COP1 functions **************************/ /************************** COP1 functions **************************/
void R4300iOp32::COP1_MF (void) { void R4300iOp32::COP1_MF (void)
{
TEST_COP1_USABLE_EXCEPTION TEST_COP1_USABLE_EXCEPTION
_GPR[m_Opcode.rt].W[0] = *(int *)_FPR_S[m_Opcode.fs]; _GPR[m_Opcode.rt].W[0] = *(int *)_FPR_S[m_Opcode.fs];
} }
void R4300iOp32::COP1_CF (void) { void R4300iOp32::COP1_CF (void)
{
TEST_COP1_USABLE_EXCEPTION TEST_COP1_USABLE_EXCEPTION
if (m_Opcode.fs != 31 && m_Opcode.fs != 0) if (m_Opcode.fs != 31 && m_Opcode.fs != 0)
{ {
@ -1269,8 +1426,8 @@ void R4300iOp32::COP1_CF (void) {
_GPR[m_Opcode.rt].W[0] = (int)_FPCR[m_Opcode.fs]; _GPR[m_Opcode.rt].W[0] = (int)_FPCR[m_Opcode.fs];
} }
void R4300iOp32::COP1_DMT (void) { void R4300iOp32::COP1_DMT (void)
{
TEST_COP1_USABLE_EXCEPTION TEST_COP1_USABLE_EXCEPTION
*(__int64 *)_FPR_D[m_Opcode.fs] = _GPR[m_Opcode.rt].W[0]; *(__int64 *)_FPR_D[m_Opcode.fs] = _GPR[m_Opcode.rt].W[0];
} }

File diff suppressed because it is too large Load Diff