diff --git a/Source/RSP/Interpreter CPU.c b/Source/RSP/Interpreter CPU.c index 0849ef90d..2a7d00365 100644 --- a/Source/RSP/Interpreter CPU.c +++ b/Source/RSP/Interpreter CPU.c @@ -472,3 +472,18 @@ DWORD RunInterpreterCPU(DWORD 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); +} diff --git a/Source/RSP/Interpreter CPU.h b/Source/RSP/Interpreter CPU.h index 861319ba3..17c33ec3a 100644 --- a/Source/RSP/Interpreter CPU.h +++ b/Source/RSP/Interpreter CPU.h @@ -38,5 +38,11 @@ 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); DWORD RunInterpreterCPU(DWORD Cycles); diff --git a/Source/RSP/Interpreter Ops.c b/Source/RSP/Interpreter Ops.c index 99f59db63..54acdabea 100644 --- a/Source/RSP/Interpreter Ops.c +++ b/Source/RSP/Interpreter Ops.c @@ -63,38 +63,22 @@ void RSP_Opcode_JAL ( void ) { void RSP_Opcode_BEQ ( void ) { RSP_NextInstruction = DELAY_SLOT; - 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; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W == RSP_GPR[RSPOpC.rt].W); } void RSP_Opcode_BNE ( void ) { RSP_NextInstruction = DELAY_SLOT; - 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; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W != RSP_GPR[RSPOpC.rt].W); } void RSP_Opcode_BLEZ ( void ) { RSP_NextInstruction = DELAY_SLOT; - if (RSP_GPR[RSPOpC.rs].W <= 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W <= 0); } void RSP_Opcode_BGTZ ( void ) { RSP_NextInstruction = DELAY_SLOT; - if (RSP_GPR[RSPOpC.rs].W > 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W > 0); } void RSP_Opcode_ADDI ( void ) { @@ -277,40 +261,24 @@ void RSP_Special_SLTU (void) { /********************** R4300i OpCodes: RegImm **********************/ void RSP_Opcode_BLTZ ( void ) { RSP_NextInstruction = DELAY_SLOT; - if (RSP_GPR[RSPOpC.rs].W < 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W < 0); } void RSP_Opcode_BGEZ ( void ) { RSP_NextInstruction = DELAY_SLOT; - if (RSP_GPR[RSPOpC.rs].W >= 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W >= 0); } void RSP_Opcode_BLTZAL ( void ) { RSP_NextInstruction = DELAY_SLOT; RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC; - if (RSP_GPR[RSPOpC.rs].W < 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W < 0); } void RSP_Opcode_BGEZAL ( void ) { RSP_NextInstruction = DELAY_SLOT; RSP_GPR[31].UW = ( *PrgCount + 8 ) & 0xFFC; - if (RSP_GPR[RSPOpC.rs].W >= 0) { - RSP_JumpTo = ( *PrgCount + ((short)RSPOpC.offset << 2) + 4 ) & 0xFFC; - } else { - RSP_JumpTo = ( *PrgCount + 8 ) & 0xFFC; - } + RSP_JumpTo = RSP_branch_if(RSP_GPR[RSPOpC.rs].W >= 0); } /************************** Cop0 functions *************************/