Merge branch 'master' into lool

Conflicts:
	Source/RSP/Interpreter Ops.c
This commit is contained in:
unknown 2015-06-21 21:03:42 -04:00
commit ee13bf0c82
13 changed files with 214 additions and 245 deletions

View File

@ -472,3 +472,18 @@ DWORD RunInterpreterCPU(DWORD Cycles) {
return Cycles; return Cycles;
} }
unsigned int RSP_branch_if(int condition)
{
unsigned int new_PC;
/* RSP_NextInstruction = DELAY_SLOT; */
if (condition)
{
new_PC = *PrgCount + 4 + ((short)RSPOpC.offset << 2);
}
else
{
new_PC = *PrgCount + 4 + 4;
}
return (new_PC & 0xFFC);
}

View File

@ -38,5 +38,11 @@
extern DWORD RSP_NextInstruction, RSP_JumpTo, RSP_MfStatusCount; extern DWORD RSP_NextInstruction, RSP_JumpTo, RSP_MfStatusCount;
/*
* standard MIPS PC-relative branch
* returns the new PC, based on whether the condition passes
*/
unsigned int RSP_branch_if(int condition);
void BuildInterpreterCPU(void); void BuildInterpreterCPU(void);
DWORD RunInterpreterCPU(DWORD Cycles); DWORD RunInterpreterCPU(DWORD Cycles);

View File

@ -63,38 +63,22 @@ void RSP_Opcode_JAL ( void ) {
void RSP_Opcode_BEQ ( void ) { void RSP_Opcode_BEQ ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W == RSP_GPR[RSPOpC.rt].W) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W == RSP_GPR[RSPOpC.rt].W);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BNE ( void ) { void RSP_Opcode_BNE ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W != RSP_GPR[RSPOpC.rt].W) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W != RSP_GPR[RSPOpC.rt].W);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BLEZ ( void ) { void RSP_Opcode_BLEZ ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W <= 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W <= 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BGTZ ( void ) { void RSP_Opcode_BGTZ ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W > 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W > 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_ADDI ( void ) { void RSP_Opcode_ADDI ( void ) {
@ -106,19 +90,11 @@ void RSP_Opcode_ADDIU ( void ) {
} }
void RSP_Opcode_SLTI (void) { void RSP_Opcode_SLTI (void) {
if (RSP_GPR[RSPOpC.rs].W < (int16_t)RSPOpC.immediate) { RSP_GPR[RSPOpC.rt].W = (RSP_GPR[RSPOpC.rs].W < (int16_t)RSPOpC.immediate) ? 1 : 0;
RSP_GPR[RSPOpC.rt].W = 1;
} else {
RSP_GPR[RSPOpC.rt].W = 0;
}
} }
void RSP_Opcode_SLTIU (void) { void RSP_Opcode_SLTIU (void) {
if (RSP_GPR[RSPOpC.rs].UW < (uint32_t)(int16_t)RSPOpC.immediate) { RSP_GPR[RSPOpC.rt].W = (RSP_GPR[RSPOpC.rs].UW < (uint32_t)(int16_t)RSPOpC.immediate) ? 1 : 0;
RSP_GPR[RSPOpC.rt].W = 1;
} else {
RSP_GPR[RSPOpC.rt].W = 0;
}
} }
void RSP_Opcode_ANDI ( void ) { void RSP_Opcode_ANDI ( void ) {
@ -275,58 +251,34 @@ void RSP_Special_NOR (void) {
} }
void RSP_Special_SLT (void) { void RSP_Special_SLT (void) {
if (RSP_GPR[RSPOpC.rs].W < RSP_GPR[RSPOpC.rt].W) { RSP_GPR[RSPOpC.rd].UW = (RSP_GPR[RSPOpC.rs].W < RSP_GPR[RSPOpC.rt].W) ? 1 : 0;
RSP_GPR[RSPOpC.rd].UW = 1;
} else {
RSP_GPR[RSPOpC.rd].UW = 0;
}
} }
void RSP_Special_SLTU (void) { void RSP_Special_SLTU (void) {
if (RSP_GPR[RSPOpC.rs].UW < RSP_GPR[RSPOpC.rt].UW) { RSP_GPR[RSPOpC.rd].UW = (RSP_GPR[RSPOpC.rs].UW < RSP_GPR[RSPOpC.rt].UW) ? 1 : 0;
RSP_GPR[RSPOpC.rd].UW = 1;
} else {
RSP_GPR[RSPOpC.rd].UW = 0;
}
} }
/********************** R4300i OpCodes: RegImm **********************/ /********************** R4300i OpCodes: RegImm **********************/
void RSP_Opcode_BLTZ ( void ) { void RSP_Opcode_BLTZ ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W < 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W < 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BGEZ ( void ) { void RSP_Opcode_BGEZ ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
if (RSP_GPR[RSPOpC.rs].W >= 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W >= 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BLTZAL ( void ) { void RSP_Opcode_BLTZAL ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC; RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC;
if (RSP_GPR[RSPOpC.rs].W < 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W < 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
void RSP_Opcode_BGEZAL ( void ) { void RSP_Opcode_BGEZAL ( void ) {
RSP_NextInstruction = DELAY_SLOT; RSP_NextInstruction = DELAY_SLOT;
RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC; RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC;
if (RSP_GPR[RSPOpC.rs].W >= 0) { RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W >= 0);
RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC;
} else {
RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC;
}
} }
/************************** Cop0 functions *************************/ /************************** Cop0 functions *************************/
@ -499,15 +451,11 @@ void RSP_Vector_VMULF (void) {
del = EleSpec[RSPOpC.rs].B[el]; del = EleSpec[RSPOpC.rs].B[el];
if (RSP_Vect[RSPOpC.rd].UHW[el] != 0x8000 || RSP_Vect[RSPOpC.rt].UHW[del] != 0x8000) { if (RSP_Vect[RSPOpC.rd].UHW[el] != 0x8000 || RSP_Vect[RSPOpC.rt].UHW[del] != 0x8000) {
temp.W = ((int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del]) << 1; temp.W = ((int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del]) << 1;
temp.UW += 0x8000; temp.UW += 0x8000;
RSP_ACCUM[el].HW[2] = temp.HW[1]; RSP_ACCUM[el].HW[2] = temp.HW[1];
RSP_ACCUM[el].HW[1] = temp.HW[0]; RSP_ACCUM[el].HW[1] = temp.HW[0];
if ( RSP_ACCUM[el].HW[2] < 0 ) { RSP_ACCUM[el].HW[3] = (RSP_ACCUM[el].HW[2] < 0) ? -1 : 0;
RSP_ACCUM[el].HW[3] = -1;
} else {
RSP_ACCUM[el].HW[3] = 0;
}
result.HW[el] = RSP_ACCUM[el].HW[2]; result.HW[el] = RSP_ACCUM[el].HW[2];
} else { } else {
temp.W = 0x80000000; temp.W = 0x80000000;
@ -604,14 +552,14 @@ void RSP_Vector_VMUDH (void) {
for (el = 0; el < 8; el ++ ) { for (el = 0; el < 8; el ++ ) {
del = EleSpec[RSPOpC.rs].B[el]; del = EleSpec[RSPOpC.rs].B[el];
RSP_ACCUM[el].W[1] = (int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del]; RSP_ACCUM[el].W[1] = (int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del];
RSP_ACCUM[el].HW[1] = 0; RSP_ACCUM[el].HW[1] = 0;
if (RSP_ACCUM[el].HW[3] < 0) { if (RSP_ACCUM[el].HW[3] < 0) {
if (RSP_ACCUM[el].UHW[3] != 0xFFFF) { if (RSP_ACCUM[el].UHW[3] != 0xFFFF) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
if (RSP_ACCUM[el].HW[2] >= 0) { if (RSP_ACCUM[el].HW[2] >= 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = RSP_ACCUM[el].HW[2]; result.HW[el] = RSP_ACCUM[el].HW[2];
} }
@ -651,10 +599,10 @@ void RSP_Vector_VMACF (void) {
RSP_ACCUM[el].DW += ((int64_t)temp.W) << 17; RSP_ACCUM[el].DW += ((int64_t)temp.W) << 17;
if (RSP_ACCUM[el].HW[3] < 0) { if (RSP_ACCUM[el].HW[3] < 0) {
if (RSP_ACCUM[el].UHW[3] != 0xFFFF) { if (RSP_ACCUM[el].UHW[3] != 0xFFFF) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
if (RSP_ACCUM[el].HW[2] >= 0) { if (RSP_ACCUM[el].HW[2] >= 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = RSP_ACCUM[el].HW[2]; result.HW[el] = RSP_ACCUM[el].HW[2];
} }
@ -808,10 +756,10 @@ void RSP_Vector_VMADM (void) {
} }
if (RSP_ACCUM[el].HW[3] < 0) { if (RSP_ACCUM[el].HW[3] < 0) {
if (RSP_ACCUM[el].UHW[3] != 0xFFFF) { if (RSP_ACCUM[el].UHW[3] != 0xFFFF) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
if (RSP_ACCUM[el].HW[2] >= 0) { if (RSP_ACCUM[el].HW[2] >= 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = RSP_ACCUM[el].HW[2]; result.HW[el] = RSP_ACCUM[el].HW[2];
} }
@ -884,10 +832,10 @@ void RSP_Vector_VMADH (void) {
RSP_ACCUM[el].W[1] += (int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del]; RSP_ACCUM[el].W[1] += (int32_t)RSP_Vect[RSPOpC.rd].HW[el] * (int32_t)RSP_Vect[RSPOpC.rt].HW[del];
if (RSP_ACCUM[el].HW[3] < 0) { if (RSP_ACCUM[el].HW[3] < 0) {
if (RSP_ACCUM[el].UHW[3] != 0xFFFF) { if (RSP_ACCUM[el].UHW[3] != 0xFFFF) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
if (RSP_ACCUM[el].HW[2] >= 0) { if (RSP_ACCUM[el].HW[2] >= 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = RSP_ACCUM[el].HW[2]; result.HW[el] = RSP_ACCUM[el].HW[2];
} }
@ -920,7 +868,7 @@ void RSP_Vector_VADD (void) {
RSP_ACCUM[el].HW[1] = temp.HW[0]; RSP_ACCUM[el].HW[1] = temp.HW[0];
if ((temp.HW[0] & 0x8000) == 0) { if ((temp.HW[0] & 0x8000) == 0) {
if (temp.HW[1] != 0) { if (temp.HW[1] != 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = temp.HW[0]; result.HW[el] = temp.HW[0];
} }
@ -949,7 +897,7 @@ void RSP_Vector_VSUB (void) {
RSP_ACCUM[el].HW[1] = temp.HW[0]; RSP_ACCUM[el].HW[1] = temp.HW[0];
if ((temp.HW[0] & 0x8000) == 0) { if ((temp.HW[0] & 0x8000) == 0) {
if (temp.HW[1] != 0) { if (temp.HW[1] != 0) {
result.HW[el] = (WORD)0x8000; result.HW[el] = 0x8000;
} else { } else {
result.HW[el] = temp.HW[0]; result.HW[el] = temp.HW[0];
} }
@ -1500,10 +1448,10 @@ void RSP_Vector_VRCPH (void) {
void RSP_Vector_VMOV (void) { void RSP_Vector_VMOV (void) {
int count; int count;
for ( count = 0; count < 8; count++ ) { for ( count = 0; count < 8; count++ ) {
RSP_ACCUM[count].HW[1] = RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[count]]; RSP_ACCUM[count].HW[1] = RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[count]];
} }
RSP_Vect[RSPOpC.sa].UHW[7 - (RSPOpC.rd & 0x7)] = RSP_Vect[RSPOpC.sa].UHW[7 - (RSPOpC.rd & 0x7)] =
RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[(RSPOpC.rd & 0x7)]]; RSP_Vect[RSPOpC.rt].UHW[EleSpec[RSPOpC.rs].B[(RSPOpC.rd & 0x7)]];
} }
@ -1738,7 +1686,7 @@ void rsp_UnknownOpcode (void) {
} else { } else {
sprintf(Message,"Unhandled Opcode\n%s\n\nStoping Emulation!\n\nDo you wish to enter the debugger ?", sprintf(Message,"Unhandled Opcode\n%s\n\nStoping Emulation!\n\nDo you wish to enter the debugger ?",
RSPOpcodeName(RSPOpC.Hex,*PrgCount)); RSPOpcodeName(RSPOpC.Hex,*PrgCount));
response = MessageBox(NULL,Message,"Error", MB_YESNO | MB_ICONERROR ); response = MessageBox(NULL,Message,"Error", MB_YESNO | MB_ICONERROR);
if (response == IDYES) { if (response == IDYES) {
Enter_RSP_Commands_Window (); Enter_RSP_Commands_Window ();
} }

View File

@ -4878,9 +4878,9 @@ void Compile_Opcode_LRV ( void ) {
MoveN64MemToX86regHalf(x86_EDX, x86_ESI); MoveN64MemToX86regHalf(x86_EDX, x86_ESI);
MoveX86regHalfToX86regPointer(x86_EDX, x86_EAX); MoveX86regHalfToX86regPointer(x86_EDX, x86_EAX);
AddConstToX86Reg(x86_EBX, 2); /* Dmem pointer */ AddConstToX86Reg(x86_EBX, 2); /* Dmem pointer */
SubConstFromX86Reg(x86_EAX, 2); /* Vector pointer */ SubConstFromX86Reg(x86_EAX, 2); /* Vector pointer */
DecX86reg(x86_ECX); /* Loop counter */ DecX86reg(x86_ECX); /* Loop counter */
JneLabel8("Loop", 0); JneLabel8("Loop", 0);
x86_SetBranch8b(RecompPos - 1, Loop); x86_SetBranch8b(RecompPos - 1, Loop);

View File

@ -748,7 +748,7 @@ void RSP_Sections_VMACF ( OPCODE RspOp, DWORD AccumStyle ) {
/******************** Microcode Sections *********************/ /******************** Microcode Sections *********************/
static DWORD Section_000_VMADN; /* Yah i know, but leave it */ static DWORD Section_000_VMADN; /* Yah i know, but leave it */
BOOL Check_Section_000(void) { BOOL Check_Section_000(void) {
DWORD i; DWORD i;