Additional checks

- Change processor transfer functions to use take both source and destination values
- Add enum values to all debug functions to double check instructions are correct
- Temporarily store instruction codes in interpreter wrappers as these are sometimes changed by branching
- Change recompiler wrapper functions to store register values in global variables in case they're changed by the original function
This commit is contained in:
iCatButler 2016-07-02 16:52:21 +01:00
parent e634f60589
commit 03cfe9e6c2
8 changed files with 387 additions and 162 deletions

View File

@ -11,8 +11,10 @@ pgxpRecNULL() {}
// Choose between debug and direct function
#ifdef PGXP_CPU_DEBUG
#define PGXP_REC_FUNC_OP(pu, op, nReg) PGXP_psxTraceOp##nReg
#define PGXP_DBG_OP_E(op) PUSH32I(DBG_E_##op); resp+=4;
#else
#define PGXP_REC_FUNC_OP(pu, op, nReg) PGXP_##pu##_##op
#define PGXP_DBG_OP_E(op)
#endif
#define PGXP_REC_FUNC_PASS(pu, op) \
@ -23,6 +25,7 @@ static void pgxpRec##op() { \
#define PGXP_REC_FUNC(pu, op) \
static void pgxpRec##op() { \
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, )); \
resp += 4; \
rec##op();\
@ -32,6 +35,7 @@ static void pgxpRec##op() { \
static void pgxpRec##op() { \
reg1;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 1)); \
resp += 8; \
rec##op();\
@ -46,6 +50,7 @@ static void pgxpRec##op() { \
reg3;\
reg4;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, nReg)); \
resp += (4 * nReg) + 4; \
}
@ -55,69 +60,158 @@ static void pgxpRec##op() { \
reg1;\
reg2;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
resp += 12; \
rec##op();\
}
static u32 gTempAddr = 0;
#define PGXP_REC_FUNC_ADDR_1(pu, op, reg1) \
static void pgxpRec##op() \
{ \
if (IsConst(_Rs_)) \
{ \
MOV32ItoR(EBX, iRegs[_Rs_].k + _Imm_); \
MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_); \
} \
else\
{\
MOV32MtoR(EBX, (u32)&psxRegs.GPR.r[_Rs_]);\
MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);\
if (_Imm_)\
{\
ADD32ItoR(EBX, _Imm_);\
ADD32ItoR(EAX, _Imm_);\
}\
}\
MOV32RtoM((u32)&gTempAddr, EAX);\
rec##op();\
PUSH32R(EBX);\
PUSH32M((u32)&gTempAddr);\
reg1;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
resp += 12; \
}
#define CPU_REG_NC(idx) MOV32MtoR(EAX,(u32)&psxRegs.GPR.r[idx])
#define CPU_REG(idx) \
if (IsConst(idx)) \
MOV32ItoR(EAX, iRegs[idx].k); \
else\
MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[idx]);
#define CP0_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP0.r[idx])
#define GTE_DATA_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP2D.r[idx])
#define GTE_CTRL_REG(idx) MOV32MtoR(EAX,(u32)&psxRegs.CP2C.r[idx])
static u32 gTempInstr = 0;
static u32 gTempReg1 = 0;
static u32 gTempReg2 = 0;
#define PGXP_REC_FUNC_R1_1(pu, op, test, reg1, reg2) \
static void pgxpRec##op() \
{ \
if(test) { rec##op(); return; }\
reg1;\
MOV32RtoM((u32)&gTempReg1, EAX);\
rec##op();\
PUSH32M((u32)&gTempReg1);\
reg2;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
resp += 12; \
}
#define PGXP_REC_FUNC_R2_1(pu, op, test, reg1, reg2, reg3) \
static void pgxpRec##op() \
{ \
if(test) { rec##op(); return; }\
reg1;\
MOV32RtoM((u32)&gTempReg1, EAX);\
reg2;\
MOV32RtoM((u32)&gTempReg2, EAX);\
rec##op();\
PUSH32M((u32)&gTempReg1);\
PUSH32M((u32)&gTempReg2);\
reg3;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 3)); \
resp += 16; \
}
#define PGXP_REC_FUNC_R2_2(pu, op, test, reg1, reg2, reg3, reg4) \
static void pgxpRec##op() \
{ \
if(test) { rec##op(); return; }\
reg1;\
MOV32RtoM((u32)&gTempReg1, EAX);\
reg2;\
MOV32RtoM((u32)&gTempReg2, EAX);\
rec##op();\
PUSH32M((u32)&gTempReg1);\
PUSH32M((u32)&gTempReg2);\
reg3;\
reg4;\
PUSH32I(psxRegs.code); \
PGXP_DBG_OP_E(op) \
CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 4)); \
resp += 20; \
}
//#define PGXP_REC_FUNC_R1i_1(pu, op, test, reg1, reg2) \
//static void pgxpRec##op() \
//{ \
// if(test) { rec##op(); return; }\
// if (IsConst(reg1)) \
// MOV32ItoR(EAX, iRegs[reg1].k); \
// else\
// MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[reg1]);\
// MOV32RtoM((u32)&gTempReg, EAX);\
// rec##op();\
// PUSH32M((u32)&gTempReg);\
// reg2;\
// PUSH32I(psxRegs.code); \
// CALLFunc((u32)PGXP_REC_FUNC_OP(pu, op, 2)); \
// resp += 12; \
//}
// Rt = Rs op imm
PGXP_REC_FUNC_2_2(CPU, ADDI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, ADDIU, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, ANDI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, ORI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, XORI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, SLTI, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_2_2(CPU, SLTIU, !_Rt_, 2, iPushReg(_Rs_), , iPushReg(_Rt_), )
PGXP_REC_FUNC_R1_1(CPU, ADDI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, ADDIU, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, ANDI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, ORI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, XORI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, SLTI, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CPU, SLTIU, !_Rt_, CPU_REG(_Rs_), iPushReg(_Rt_))
// Rt = imm
PGXP_REC_FUNC_2_2(CPU, LUI, !_Rt_, 1, , , iPushReg(_Rt_), )
// Rd = Rs op Rt
PGXP_REC_FUNC_2_2(CPU, ADD, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, ADDU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SUB, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SUBU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, AND, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, OR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, XOR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, NOR, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SLT, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SLTU, !_Rd_, 3, iPushReg(_Rt_), iPushReg(_Rs_), iPushReg(_Rd_), )
PGXP_REC_FUNC_R2_1(CPU, ADD, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, ADDU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SUB, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SUBU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, AND, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, OR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, XOR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, NOR, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SLT, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SLTU, !_Rd_, CPU_REG(_Rt_), CPU_REG(_Rs_), iPushReg(_Rd_))
// Hi/Lo = Rs op Rt
PGXP_REC_FUNC_2_2(CPU, MULT, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_2_2(CPU, MULTU, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_2_2(CPU, DIV, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_2_2(CPU, DIVU, 0, 4, iPushReg(_Rt_), iPushReg(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_R2_2(CPU, MULT, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_R2_2(CPU, MULTU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_R2_2(CPU, DIV, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_R2_2(CPU, DIVU, 0, CPU_REG(_Rt_), CPU_REG(_Rs_), PUSH32M((u32)&psxRegs.GPR.n.lo), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_2(CPU, SB, iPushOfB(), iPushReg(_Rt_))
PGXP_REC_FUNC_2(CPU, SH, iPushOfB(), iPushReg(_Rt_))
PGXP_REC_FUNC_2(CPU, SW, iPushOfB(), iPushReg(_Rt_))
PGXP_REC_FUNC_2(CPU, SWL, iPushOfB(), iPushReg(_Rt_))
PGXP_REC_FUNC_2(CPU, SWR, iPushOfB(), iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, SB, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, SH, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, SW, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, SWL, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, SWR, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, LWL, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, LW, iPushReg(_Rt_))
@ -128,34 +222,34 @@ PGXP_REC_FUNC_ADDR_1(CPU, LB, iPushReg(_Rt_))
PGXP_REC_FUNC_ADDR_1(CPU, LBU, iPushReg(_Rt_))
//Rd = Rt op Sa
PGXP_REC_FUNC_2_2(CPU, SLL, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SRL, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SRA, !_Rd_, 2, iPushReg(_Rt_), , iPushReg(_Rd_), )
PGXP_REC_FUNC_R1_1(CPU, SLL, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
PGXP_REC_FUNC_R1_1(CPU, SRL, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
PGXP_REC_FUNC_R1_1(CPU, SRA, !_Rd_, CPU_REG(_Rt_), iPushReg(_Rd_))
// Rd = Rt op Rs
PGXP_REC_FUNC_2_2(CPU, SLLV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SRLV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, SRAV, !_Rd_, 3, iPushReg(_Rs_), iPushReg(_Rt_), iPushReg(_Rd_), )
PGXP_REC_FUNC_R2_1(CPU, SLLV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SRLV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
PGXP_REC_FUNC_R2_1(CPU, SRAV, !_Rd_, CPU_REG(_Rs_), CPU_REG(_Rt_), iPushReg(_Rd_))
PGXP_REC_FUNC_2_2(CPU, MFHI, !_Rd_, 2, PUSH32M((u32)&psxRegs.GPR.n.hi), , iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, MTHI, 0, 2, iPushReg(_Rd_), , PUSH32M((u32)&psxRegs.GPR.n.hi), )
PGXP_REC_FUNC_2_2(CPU, MFLO, !_Rd_, 2, PUSH32M((u32)&psxRegs.GPR.n.lo), , iPushReg(_Rd_), )
PGXP_REC_FUNC_2_2(CPU, MTLO, 0, 2, iPushReg(_Rd_), , PUSH32M((u32)&psxRegs.GPR.n.lo), )
PGXP_REC_FUNC_R1_1(CPU, MFHI, !_Rd_, CPU_REG_NC(33), iPushReg(_Rd_))
PGXP_REC_FUNC_R1_1(CPU, MTHI, 0, CPU_REG(_Rd_), PUSH32M((u32)&psxRegs.GPR.n.hi))
PGXP_REC_FUNC_R1_1(CPU, MFLO, !_Rd_, CPU_REG_NC(32), iPushReg(_Rd_))
PGXP_REC_FUNC_R1_1(CPU, MTLO, 0, CPU_REG(_Rd_), PUSH32M((u32)&psxRegs.GPR.n.lo))
// COP2 (GTE)
PGXP_REC_FUNC_2_2(GTE, MFC2, !_Rt_, 1, , , , PUSH32M((u32)&psxRegs.CP2D.r[_Rd_]))
PGXP_REC_FUNC_2_2(GTE, CFC2, !_Rt_, 1, , , , PUSH32M((u32)&psxRegs.CP2C.r[_Rd_]))
PGXP_REC_FUNC_2_2(GTE, MTC2, 0, 1, , , , iPushReg(_Rt_))
PGXP_REC_FUNC_2_2(GTE, CTC2, 0, 1, , , , iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(GTE, MFC2, !_Rt_, GTE_DATA_REG(_Rd_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(GTE, CFC2, !_Rt_, GTE_CTRL_REG(_Rd_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(GTE, MTC2, 0, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP2D.r[_Rd_]))
PGXP_REC_FUNC_R1_1(GTE, CTC2, 0, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP2C.r[_Rd_]))
PGXP_REC_FUNC_ADDR_1(GTE, LWC2, PUSH32M((u32)&psxRegs.CP2D.r[_Rt_]))
PGXP_REC_FUNC_ADDR_1(GTE, SWC2, PUSH32M((u32)&psxRegs.CP2D.r[_Rt_]))
// COP0
PGXP_REC_FUNC_2_2(CP0, MFC0, !_Rd_, 1, , , , PUSH32M((u32)&psxRegs.CP0.r[_Rd_]))
PGXP_REC_FUNC_2_2(CP0, CFC0, !_Rd_, 1, , , , PUSH32M((u32)&psxRegs.CP0.r[_Rd_]))
PGXP_REC_FUNC_2_2(CP0, MTC0, !_Rt_, 1, , , , iPushReg(_Rt_))
PGXP_REC_FUNC_2_2(CP0, CTC0, !_Rt_, 1, , , , iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CP0, MFC0, !_Rd_, CP0_REG(_Rd_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CP0, CFC0, !_Rd_, CP0_REG(_Rd_), iPushReg(_Rt_))
PGXP_REC_FUNC_R1_1(CP0, MTC0, !_Rt_, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP0.r[_Rd_]))
PGXP_REC_FUNC_R1_1(CP0, CTC0, !_Rt_, CPU_REG(_Rt_), PUSH32M((u32)&psxRegs.CP0.r[_Rd_]))
PGXP_REC_FUNC(CP0, RFE)
#endif//_I_PGXP_H_

View File

@ -773,32 +773,36 @@ void PGXP_CPU_SB(u32 instr, u8 rtVal, u32 addr)
////////////////////////////////////
// Data transfer tracking
////////////////////////////////////
void PGXP_CP0_MFC0(u32 instr, u32 rdVal)
void PGXP_CP0_MFC0(u32 instr, u32 rtVal, u32 rdVal)
{
// CPU[Rt] = CP0[Rd]
Validate(&CP0_reg[rd(instr)], rdVal);
CPU_reg[rt(instr)] = CP0_reg[rd(instr)];
CPU_reg[rt(instr)].value = rtVal;
}
void PGXP_CP0_MTC0(u32 instr, u32 rtVal)
void PGXP_CP0_MTC0(u32 instr, u32 rdVal, u32 rtVal)
{
// CP0[Rd] = CPU[Rt]
Validate(&CPU_reg[rt(instr)], rtVal);
CP0_reg[rd(instr)] = CPU_reg[rt(instr)];
CP0_reg[rd(instr)].value = rdVal;
}
void PGXP_CP0_CFC0(u32 instr, u32 rdVal)
void PGXP_CP0_CFC0(u32 instr, u32 rtVal, u32 rdVal)
{
// CPU[Rt] = CP0[Rd]
Validate(&CP0_reg[rd(instr)], rdVal);
CPU_reg[rt(instr)] = CP0_reg[rd(instr)];
CPU_reg[rt(instr)].value = rtVal;
}
void PGXP_CP0_CTC0(u32 instr, u32 rtVal)
void PGXP_CP0_CTC0(u32 instr, u32 rdVal, u32 rtVal)
{
// CP0[Rd] = CPU[Rt]
Validate(&CPU_reg[rt(instr)], rtVal);
CP0_reg[rd(instr)] = CPU_reg[rt(instr)];
CP0_reg[rd(instr)].value = rdVal;
}
void PGXP_CP0_RFE(u32 instr)

View File

@ -114,10 +114,10 @@ void PGXP_CPU_MFLO(u32 instr, u32 rdVal, u32 loVal);
void PGXP_CPU_MTLO(u32 instr, u32 loVal, u32 rdVal);
// CP0 Data transfer tracking
void PGXP_CP0_MFC0(u32 instr, u32 rdVal);
void PGXP_CP0_MTC0(u32 instr, u32 rtVal);
void PGXP_CP0_CFC0(u32 instr, u32 rdVal);
void PGXP_CP0_CTC0(u32 instr, u32 rtVal);
void PGXP_CP0_MFC0(u32 instr, u32 rtVal, u32 rdVal);
void PGXP_CP0_MTC0(u32 instr, u32 rdVal, u32 rtVal);
void PGXP_CP0_CFC0(u32 instr, u32 rtVal, u32 rdVal);
void PGXP_CP0_CTC0(u32 instr, u32 rdVal, u32 rtVal);
void PGXP_CP0_RFE(u32 instr);
#endif //_PGXP_CPU_H_

View File

@ -39,6 +39,7 @@ typedef enum
typedef struct
{
unsigned int eOp;
unsigned short OutputFlags;
unsigned short InputFlags;
unsigned char numRegisters;
@ -52,41 +53,41 @@ void PGXP_CPU_EMPTY() {}
void PGXP_CPU_NULL() { int* pi = NULL; *pi = 5; }
void PGXP_CPU_ERROR() { int* pi = NULL; *pi = 5; }
#define PGXP_Data_ERROR { 0, 0, 0, 0, "", "ERROR", (void(*)())PGXP_CPU_ERROR }
#define PGXP_Data_NULL { 0, 0, 0, 0, "", "NULL", (void(*)())PGXP_CPU_NULL }
#define PGXP_Data_SPECIAL { 0, 0, 0, 0, "", "SPECIAL", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_COP0 { 0, 0, 0, 0, "", "COP0", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_COP2 { 0, 0, 0, 0, "", "COP2", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_HLE { 0, 0, 0, 0, "", "HLE", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_ERROR { DBG_E_ERROR, 0, 0, 0, 0, "", "ERROR", (void(*)())PGXP_CPU_ERROR }
#define PGXP_Data_NULL { DBG_E_NULL, 0, 0, 0, 0, "", "NULL", (void(*)())PGXP_CPU_NULL }
#define PGXP_Data_SPECIAL { DBG_E_SPECIAL, 0, 0, 0, 0, "", "SPECIAL", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_COP0 { DBG_E_COP0, 0, 0, 0, 0, "", "COP0", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_COP2 { DBG_E_COP2, 0, 0, 0, 0, "", "COP2", (void(*)())PGXP_CPU_EMPTY }
#define PGXP_Data_HLE { DBG_E_HLE, 0, 0, 0, 0, "", "HLE", (void(*)())PGXP_CPU_EMPTY }
// Arithmetic with immediate value
#define PGXP_Data_ADDI { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "+", "ADDI", (void(*)())PGXP_CPU_ADDI }
#define PGXP_Data_ADDIU { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "+", "ADDIU", (void(*)())PGXP_CPU_ADDIU }
#define PGXP_Data_ANDI { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "&", "ANDI", (void(*)())PGXP_CPU_ANDI }
#define PGXP_Data_ORI { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "|", "ORI", (void(*)())PGXP_CPU_ORI }
#define PGXP_Data_XORI { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "^", "XORI", (void(*)())PGXP_CPU_XORI }
#define PGXP_Data_SLTI { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "<", "SLTI", (void(*)())PGXP_CPU_SLTI }
#define PGXP_Data_SLTIU { fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "<", "SLTIU", (void(*)())PGXP_CPU_SLTIU }
#define PGXP_Data_ADDI { DBG_E_ADDI, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "+", "ADDI", (void(*)())PGXP_CPU_ADDI }
#define PGXP_Data_ADDIU { DBG_E_ADDIU, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "+", "ADDIU", (void(*)())PGXP_CPU_ADDIU }
#define PGXP_Data_ANDI { DBG_E_ANDI, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "&", "ANDI", (void(*)())PGXP_CPU_ANDI }
#define PGXP_Data_ORI { DBG_E_ORI, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "|", "ORI", (void(*)())PGXP_CPU_ORI }
#define PGXP_Data_XORI { DBG_E_XORI, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "^", "XORI", (void(*)())PGXP_CPU_XORI }
#define PGXP_Data_SLTI { DBG_E_SLTI, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "<", "SLTI", (void(*)())PGXP_CPU_SLTI }
#define PGXP_Data_SLTIU { DBG_E_SLTIU, fOp_CPU_Rt, fOp_CPU_Rs | fOp_Im, 2, 2, "<", "SLTIU", (void(*)())PGXP_CPU_SLTIU }
// Load Upper
#define PGXP_Data_LUI { fOp_CPU_Rt, fOp_Im, 1, 1, "<<", "LUI", (void(*)())PGXP_CPU_LUI }
#define PGXP_Data_LUI { DBG_E_LUI, fOp_CPU_Rt, fOp_Im, 1, 1, "<<", "LUI", (void(*)())PGXP_CPU_LUI }
// Load/Store
#define PGXP_Data_LWL { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LWL", (void(*)())PGXP_CPU_LWL } // 32-bit Loads
#define PGXP_Data_LW { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LW", (void(*)())PGXP_CPU_LW }
#define PGXP_Data_LWR { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LWR", (void(*)())PGXP_CPU_LWR }
#define PGXP_Data_LH { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LH", (void(*)())PGXP_CPU_LH } // 16-bit Loads
#define PGXP_Data_LHU { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LHU", (void(*)())PGXP_CPU_LHU }
#define PGXP_Data_LB { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LB", (void(*)())PGXP_CPU_LB } // 8-bit Loads
#define PGXP_Data_LBU { fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LBU", (void(*)())PGXP_CPU_LBU }
#define PGXP_Data_SWL { fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SWL", (void(*)())PGXP_CPU_SWL } // 32-bit Store
#define PGXP_Data_SW { fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SW", (void(*)())PGXP_CPU_SW }
#define PGXP_Data_SWR { fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SWR", (void(*)())PGXP_CPU_SWR }
#define PGXP_Data_SH { fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SH", (void(*)())PGXP_CPU_SH } // 16-bit Store
#define PGXP_Data_SB { fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SB", (void(*)())PGXP_CPU_SB } // 8-bit Store
#define PGXP_Data_LWL { DBG_E_LWL, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LWL", (void(*)())PGXP_CPU_LWL } // 32-bit Loads
#define PGXP_Data_LW { DBG_E_LW, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LW", (void(*)())PGXP_CPU_LW }
#define PGXP_Data_LWR { DBG_E_LWR, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LWR", (void(*)())PGXP_CPU_LWR }
#define PGXP_Data_LH { DBG_E_LH, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LH", (void(*)())PGXP_CPU_LH } // 16-bit Loads
#define PGXP_Data_LHU { DBG_E_LHU, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LHU", (void(*)())PGXP_CPU_LHU }
#define PGXP_Data_LB { DBG_E_LB, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LB", (void(*)())PGXP_CPU_LB } // 8-bit Loads
#define PGXP_Data_LBU { DBG_E_LBU, fOp_CPU_Rt, fOp_Ad, 1, 2, "", "LBU", (void(*)())PGXP_CPU_LBU }
#define PGXP_Data_SWL { DBG_E_SWL, fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SWL", (void(*)())PGXP_CPU_SWL } // 32-bit Store
#define PGXP_Data_SW { DBG_E_SW, fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SW", (void(*)())PGXP_CPU_SW }
#define PGXP_Data_SWR { DBG_E_SWR, fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SWR", (void(*)())PGXP_CPU_SWR }
#define PGXP_Data_SH { DBG_E_SH, fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SH", (void(*)())PGXP_CPU_SH } // 16-bit Store
#define PGXP_Data_SB { DBG_E_SB, fOp_Ad, fOp_CPU_Rt, 1, 2, "", "SB", (void(*)())PGXP_CPU_SB } // 8-bit Store
// Load/Store GTE
#define PGXP_Data_LWC2 { fOp_GTE_Dt, fOp_Ad, 1, 2, "", "LWC2", (void(*)())PGXP_GTE_LWC2 } // 32-bit Loads
#define PGXP_Data_SWC2 { fOp_Ad, fOp_GTE_Dt, 1, 2, "", "SWC2", (void(*)())PGXP_GTE_SWC2 } // 32-bit Store
#define PGXP_Data_LWC2 { DBG_E_LWC2, fOp_GTE_Dt, fOp_Ad, 1, 2, "", "LWC2", (void(*)())PGXP_GTE_LWC2 } // 32-bit Loads
#define PGXP_Data_SWC2 { DBG_E_SWC2, fOp_Ad, fOp_GTE_Dt, 1, 2, "", "SWC2", (void(*)())PGXP_GTE_SWC2 } // 32-bit Store
static PGXP_CPU_OpData PGXP_BSC_LUT[64] = {
PGXP_Data_SPECIAL, PGXP_Data_NULL , PGXP_Data_NULL, PGXP_Data_NULL , PGXP_Data_NULL, PGXP_Data_NULL, PGXP_Data_NULL, PGXP_Data_NULL,
@ -100,38 +101,38 @@ static PGXP_CPU_OpData PGXP_BSC_LUT[64] = {
};
// Register Arithmetic
#define PGXP_Data_ADD { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "+", "ADD", (void(*)())PGXP_CPU_ADD }
#define PGXP_Data_ADDU { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "+", "ADDU", (void(*)())PGXP_CPU_ADDU }
#define PGXP_Data_SUB { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "-", "SUB", (void(*)())PGXP_CPU_SUB }
#define PGXP_Data_SUBU { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "-", "SUBU", (void(*)())PGXP_CPU_SUBU }
#define PGXP_Data_AND { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "&", "AND", (void(*)())PGXP_CPU_AND }
#define PGXP_Data_OR { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "|", "OR", (void(*)())PGXP_CPU_OR }
#define PGXP_Data_XOR { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "^", "XOR", (void(*)())PGXP_CPU_XOR }
#define PGXP_Data_NOR { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "^", "NOR", (void(*)())PGXP_CPU_NOR }
#define PGXP_Data_SLT { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "<", "SLT", (void(*)())PGXP_CPU_SLT }
#define PGXP_Data_SLTU { fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "<", "SLTU", (void(*)())PGXP_CPU_SLTU }
#define PGXP_Data_ADD { DBG_E_ADD, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "+", "ADD", (void(*)())PGXP_CPU_ADD }
#define PGXP_Data_ADDU { DBG_E_ADDU, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "+", "ADDU", (void(*)())PGXP_CPU_ADDU }
#define PGXP_Data_SUB { DBG_E_SUB, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "-", "SUB", (void(*)())PGXP_CPU_SUB }
#define PGXP_Data_SUBU { DBG_E_SUBU, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "-", "SUBU", (void(*)())PGXP_CPU_SUBU }
#define PGXP_Data_AND { DBG_E_AND, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "&", "AND", (void(*)())PGXP_CPU_AND }
#define PGXP_Data_OR { DBG_E_OR, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "|", "OR", (void(*)())PGXP_CPU_OR }
#define PGXP_Data_XOR { DBG_E_XOR, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "^", "XOR", (void(*)())PGXP_CPU_XOR }
#define PGXP_Data_NOR { DBG_E_NOR, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "^", "NOR", (void(*)())PGXP_CPU_NOR }
#define PGXP_Data_SLT { DBG_E_SLT, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "<", "SLT", (void(*)())PGXP_CPU_SLT }
#define PGXP_Data_SLTU { DBG_E_SLTU, fOp_CPU_Rd, fOp_CPU_Rs | fOp_CPU_Rt, 3, 3, "<", "SLTU", (void(*)())PGXP_CPU_SLTU }
// Register mult/div
#define PGXP_Data_MULT { fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "*", "MULT", (void(*)())PGXP_CPU_MULT }
#define PGXP_Data_MULTU { fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "*", "MULTU", (void(*)())PGXP_CPU_MULTU }
#define PGXP_Data_DIV { fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "/", "DIV", (void(*)())PGXP_CPU_DIV }
#define PGXP_Data_DIVU { fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "/", "DIVU", (void(*)())PGXP_CPU_DIVU }
#define PGXP_Data_MULT { DBG_E_MULT, fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "*", "MULT", (void(*)())PGXP_CPU_MULT }
#define PGXP_Data_MULTU { DBG_E_MULTU, fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "*", "MULTU", (void(*)())PGXP_CPU_MULTU }
#define PGXP_Data_DIV { DBG_E_DIV, fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "/", "DIV", (void(*)())PGXP_CPU_DIV }
#define PGXP_Data_DIVU { DBG_E_DIVU, fOp_CPU_Hi | fOp_CPU_Lo, fOp_CPU_Rs | fOp_CPU_Rt, 4, 4, "/", "DIVU", (void(*)())PGXP_CPU_DIVU }
// Shift operations (sa)
#define PGXP_Data_SLL { fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, ">>", "SLL", (void(*)())PGXP_CPU_SLL }
#define PGXP_Data_SRL { fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRL", (void(*)())PGXP_CPU_SRL }
#define PGXP_Data_SRA { fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRA", (void(*)())PGXP_CPU_SRA }
#define PGXP_Data_SLL { DBG_E_SLL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, ">>", "SLL", (void(*)())PGXP_CPU_SLL }
#define PGXP_Data_SRL { DBG_E_SRL, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRL", (void(*)())PGXP_CPU_SRL }
#define PGXP_Data_SRA { DBG_E_SRA, fOp_CPU_Rd, fOp_CPU_Rt | fOp_Sa, 2, 2, "<<", "SRA", (void(*)())PGXP_CPU_SRA }
// Shift operations variable
#define PGXP_Data_SLLV { fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, ">>", "SLLV", (void(*)())PGXP_CPU_SLLV }
#define PGXP_Data_SRLV { fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRLV", (void(*)())PGXP_CPU_SRLV }
#define PGXP_Data_SRAV { fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRAV", (void(*)())PGXP_CPU_SRAV }
#define PGXP_Data_SLLV { DBG_E_SLLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, ">>", "SLLV", (void(*)())PGXP_CPU_SLLV }
#define PGXP_Data_SRLV { DBG_E_SRLV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRLV", (void(*)())PGXP_CPU_SRLV }
#define PGXP_Data_SRAV { DBG_E_SRAV, fOp_CPU_Rd, fOp_CPU_Rt | fOp_CPU_Rs, 3, 3, "<<", "SRAV", (void(*)())PGXP_CPU_SRAV }
// Move registers
#define PGXP_Data_MFHI { fOp_CPU_Rd, fOp_CPU_Hi, 2, 2, "<-", "MFHI", (void(*)())PGXP_CPU_MFHI }
#define PGXP_Data_MTHI { fOp_CPU_Hi, fOp_CPU_Rd, 2, 2, "<-", "MTHI", (void(*)())PGXP_CPU_MTHI }
#define PGXP_Data_MFLO { fOp_CPU_Rd, fOp_CPU_Lo, 2, 2, "<-", "MFLO", (void(*)())PGXP_CPU_MFLO }
#define PGXP_Data_MTLO { fOp_CPU_Lo, fOp_CPU_Rd, 2, 2, "<-", "MFHI", (void(*)())PGXP_CPU_MTLO }
#define PGXP_Data_MFHI { DBG_E_MFHI, fOp_CPU_Rd, fOp_CPU_Hi, 2, 2, "<-", "MFHI", (void(*)())PGXP_CPU_MFHI }
#define PGXP_Data_MTHI { DBG_E_MTHI, fOp_CPU_Hi, fOp_CPU_Rd, 2, 2, "<-", "MTHI", (void(*)())PGXP_CPU_MTHI }
#define PGXP_Data_MFLO { DBG_E_MFLO, fOp_CPU_Rd, fOp_CPU_Lo, 2, 2, "<-", "MFLO", (void(*)())PGXP_CPU_MFLO }
#define PGXP_Data_MTLO { DBG_E_MTLO, fOp_CPU_Lo, fOp_CPU_Rd, 2, 2, "<-", "MFHI", (void(*)())PGXP_CPU_MTLO }
static PGXP_CPU_OpData PGXP_SPC_LUT[64] = {
PGXP_Data_SLL , PGXP_Data_NULL, PGXP_Data_SRL , PGXP_Data_SRA , PGXP_Data_SLLV , PGXP_Data_NULL , PGXP_Data_SRLV, PGXP_Data_SRAV,
@ -145,10 +146,10 @@ static PGXP_CPU_OpData PGXP_SPC_LUT[64] = {
};
// GTE transfer registers
#define PGXP_Data_MFC2 { fOp_CPU_Rt, fOp_GTE_Dd, 2, 1, "<-", "MFC2", (void(*)())PGXP_GTE_MFC2 }
#define PGXP_Data_MTC2 { fOp_GTE_Dd, fOp_CPU_Rt, 2, 1, "<-", "MTC2", (void(*)())PGXP_GTE_MTC2 }
#define PGXP_Data_CFC2 { fOp_CPU_Rt, fOp_GTE_Cd, 2, 1, "<-", "CFC2", (void(*)())PGXP_GTE_CFC2 }
#define PGXP_Data_CTC2 { fOp_GTE_Cd, fOp_CPU_Rt, 2, 1, "<-", "CTC2", (void(*)())PGXP_GTE_CTC2 }
#define PGXP_Data_MFC2 { DBG_E_MFC2, fOp_CPU_Rt, fOp_GTE_Dd, 2, 2, "<-", "MFC2", (void(*)())PGXP_GTE_MFC2 }
#define PGXP_Data_MTC2 { DBG_E_MTC2, fOp_GTE_Dd, fOp_CPU_Rt, 2, 2, "<-", "MTC2", (void(*)())PGXP_GTE_MTC2 }
#define PGXP_Data_CFC2 { DBG_E_CFC2, fOp_CPU_Rt, fOp_GTE_Cd, 2, 2, "<-", "CFC2", (void(*)())PGXP_GTE_CFC2 }
#define PGXP_Data_CTC2 { DBG_E_CTC2, fOp_GTE_Cd, fOp_CPU_Rt, 2, 2, "<-", "CTC2", (void(*)())PGXP_GTE_CTC2 }
static PGXP_CPU_OpData PGXP_CO2BSC_LUT[32] = {
PGXP_Data_MFC2, PGXP_Data_NULL, PGXP_Data_CFC2, PGXP_Data_NULL, PGXP_Data_MTC2, PGXP_Data_NULL, PGXP_Data_CTC2, PGXP_Data_NULL,
@ -158,11 +159,11 @@ static PGXP_CPU_OpData PGXP_CO2BSC_LUT[32] = {
};
// CP0 transfer registers
#define PGXP_Data_MFC0 { fOp_CPU_Rt, fOp_CP0_Dd, 2, 1, "<-", "MFC0", (void(*)())PGXP_CP0_MFC0 }
#define PGXP_Data_MTC0 { fOp_CP0_Dd, fOp_CPU_Rt, 2, 1, "<-", "MTC0", (void(*)())PGXP_CP0_MTC0 }
#define PGXP_Data_CFC0 { fOp_CPU_Rt, fOp_CP0_Cd, 2, 1, "<-", "CFC0", (void(*)())PGXP_CP0_CFC0 }
#define PGXP_Data_CTC0 { fOp_CP0_Cd, fOp_CPU_Rt, 2, 1, "<-", "CTC0", (void(*)())PGXP_CP0_CTC0 }
#define PGXP_Data_RFE { 0, 0, 0, 0,"", "RFE", PGXP_CPU_EMPTY }
#define PGXP_Data_MFC0 { DBG_E_MFC0, fOp_CPU_Rt, fOp_CP0_Dd, 2, 2, "<-", "MFC0", (void(*)())PGXP_CP0_MFC0 }
#define PGXP_Data_MTC0 { DBG_E_MTC0, fOp_CP0_Dd, fOp_CPU_Rt, 2, 2, "<-", "MTC0", (void(*)())PGXP_CP0_MTC0 }
#define PGXP_Data_CFC0 { DBG_E_CFC0, fOp_CPU_Rt, fOp_CP0_Cd, 2, 2, "<-", "CFC0", (void(*)())PGXP_CP0_CFC0 }
#define PGXP_Data_CTC0 { DBG_E_CTC0, fOp_CP0_Cd, fOp_CPU_Rt, 2, 2, "<-", "CTC0", (void(*)())PGXP_CP0_CTC0 }
#define PGXP_Data_RFE { DBG_E_RFE, 0, 0, 0, 0,"", "RFE", PGXP_CPU_EMPTY }
static PGXP_CPU_OpData PGXP_COP0_LUT[32] = {
PGXP_Data_MFC0, PGXP_Data_NULL, PGXP_Data_CFC0, PGXP_Data_NULL, PGXP_Data_MTC0, PGXP_Data_NULL, PGXP_Data_CTC0, PGXP_Data_NULL,
@ -305,8 +306,14 @@ void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, ps
}
else if(flag == fOp_Ad)
{
sprintf(szTempBuffer, "%s %s [%x(%d, %d) (%x)] ", szPre, szOpdName,
psx_reg.d, psx_reg.sw.l, psx_reg.sw.h, PGXP_ConvertAddress(psx_reg.d));
pReg = GetPtr(psx_reg.d);
if(pReg)
sprintf(szTempBuffer, "%s %s [%x(%d, %d) (%x) %x(%.2f, %.2f, %.2f)%x : %x] ", szPre, szOpdName,
psx_reg.d, psx_reg.sw.l, psx_reg.sw.h, PGXP_ConvertAddress(psx_reg.d),
pReg->value, pReg->x, pReg->y, pReg->z, pReg->count, pReg->valid);
else
sprintf(szTempBuffer, "%s %s [%x(%d, %d) INVALID_ADDRESS!] ", szPre, szOpdName,
psx_reg.d, psx_reg.sw.l, psx_reg.sw.h, PGXP_ConvertAddress(psx_reg.d));
strcat(szBuffer, szTempBuffer);
}
else
@ -321,7 +328,7 @@ void PrintOperands(char* szBuffer, u32 instr, u32 flags, const char* szDelim, ps
}
}
void PGXP_CPU_DebugOutput(u32 instr, u32 numOps, u32 op1, u32 op2, u32 op3, u32 op4)
void PGXP_CPU_DebugOutput(u32 eOp, u32 instr, u32 numOps, u32 op1, u32 op2, u32 op3, u32 op4)
{
char szOutputBuffer[256];
char szInputBuffer[512];
@ -341,8 +348,8 @@ void PGXP_CPU_DebugOutput(u32 instr, u32 numOps, u32 op1, u32 op2, u32 op3, u32
}
// Hack: duplicate psx register data for GTE register movement funcs
if ((op(instr) == 18) && (func(instr) == 0))
psx_regs[1] = psx_regs[0];
//if ((op(instr) == 18) && (func(instr) == 0))
// psx_regs[1] = psx_regs[0];
// /iCB Hack
@ -367,6 +374,9 @@ void PGXP_CPU_DebugOutput(u32 instr, u32 numOps, u32 op1, u32 op2, u32 op3, u32
if (numOps != opData.numArgs)
PGXP_CPU_ERROR();
if (eOp != opData.eOp)
PGXP_CPU_ERROR();
switch (numOps)
{
case 0:
@ -401,42 +411,42 @@ void PGXP_CPU_DebugOutput(u32 instr, u32 numOps, u32 op1, u32 op2, u32 op3, u32
}
}
void PGXP_psxTraceOp(u32 instr)
void PGXP_psxTraceOp(u32 eOp, u32 instr)
{
//PGXP_CPU_OpData opData = GetOpData(instr);
//if (opData.funcPtr && (opData.numArgs == 0))
// ((void(*)(u32))opData.funcPtr)(instr);
PGXP_CPU_DebugOutput(instr, 0, 0, 0, 0, 0);
PGXP_CPU_DebugOutput(eOp, instr, 0, 0, 0, 0, 0);
}
void PGXP_psxTraceOp1(u32 instr, u32 op1)
void PGXP_psxTraceOp1(u32 eOp, u32 instr, u32 op1)
{
//PGXP_CPU_OpData opData = GetOpData(instr);
//if (opData.funcPtr && (opData.numArgs == 1))
// ((void(*)(u32, u32))opData.funcPtr)(instr, op1);
PGXP_CPU_DebugOutput(instr, 1, op1, 0, 0, 0);
PGXP_CPU_DebugOutput(eOp, instr, 1, op1, 0, 0, 0);
}
void PGXP_psxTraceOp2(u32 instr, u32 op1, u32 op2)
void PGXP_psxTraceOp2(u32 eOp, u32 instr, u32 op1, u32 op2)
{
//PGXP_CPU_OpData opData = GetOpData(instr);
//if (opData.funcPtr && (opData.numArgs == 2))
// ((void(*)(u32, u32, u32))opData.funcPtr)(instr, op1, op2);
PGXP_CPU_DebugOutput(instr, 2, op1, op2, 0, 0);
PGXP_CPU_DebugOutput(eOp, instr, 2, op1, op2, 0, 0);
}
void PGXP_psxTraceOp3(u32 instr, u32 op1, u32 op2, u32 op3)
void PGXP_psxTraceOp3(u32 eOp, u32 instr, u32 op1, u32 op2, u32 op3)
{
//PGXP_CPU_OpData opData = GetOpData(instr);
//if (opData.funcPtr && (opData.numArgs == 3))
// ((void(*)(u32, u32, u32, u32))opData.funcPtr)(instr, op1, op2, op3);
PGXP_CPU_DebugOutput(instr, 3, op1, op2, op3, 0);
PGXP_CPU_DebugOutput(eOp, instr, 3, op1, op2, op3, 0);
}
void PGXP_psxTraceOp4(u32 instr, u32 op1, u32 op2, u32 op3, u32 op4)
void PGXP_psxTraceOp4(u32 eOp, u32 instr, u32 op1, u32 op2, u32 op3, u32 op4)
{
//PGXP_CPU_OpData opData = GetOpData(instr);
//if (opData.funcPtr && (opData.numArgs == 4))
// ((void(*)(u32, u32, u32, u32, u32))opData.funcPtr)(instr, op1, op2, op3, op4);
PGXP_CPU_DebugOutput(instr, 4, op1, op2, op3, op4);
PGXP_CPU_DebugOutput(eOp, instr, 4, op1, op2, op3, op4);
}

View File

@ -30,15 +30,120 @@
#include "psxcommon.h"
//#define PGXP_CPU_DEBUG
#define PGXP_CPU_DEBUG
// Debug wrappers
void PGXP_psxTraceOp(u32 code);
void PGXP_psxTraceOp1(u32 code, u32 op1);
void PGXP_psxTraceOp2(u32 code, u32 op1, u32 op2);
void PGXP_psxTraceOp3(u32 code, u32 op1, u32 op2, u32 op3);
void PGXP_psxTraceOp4(u32 code, u32 op1, u32 op2, u32 op3, u32 op4);
void PGXP_psxTraceOp(u32 eOp, u32 code);
void PGXP_psxTraceOp1(u32 eOp, u32 code, u32 op1);
void PGXP_psxTraceOp2(u32 eOp, u32 code, u32 op1, u32 op2);
void PGXP_psxTraceOp3(u32 eOp, u32 code, u32 op1, u32 op2, u32 op3);
void PGXP_psxTraceOp4(u32 eOp, u32 code, u32 op1, u32 op2, u32 op3, u32 op4);
extern unsigned int pgxp_debug;
// Op flags
enum PGXP_DBG_Enum
{
DBG_E_SPECIAL,
DBG_E_REGIMM,
DBG_E_J,
DBG_E_JAL,
DBG_E_BEQ,
DBG_E_BNE,
DBG_E_BLEZ,
DBG_E_BGTZ,
DBG_E_ADDI,
DBG_E_ADDIU,
DBG_E_SLTI,
DBG_E_SLTIU,
DBG_E_ANDI,
DBG_E_ORI,
DBG_E_XORI,
DBG_E_LUI,
DBG_E_COP0,
DBG_E_COP2,
DBG_E_LB,
DBG_E_LH,
DBG_E_LWL,
DBG_E_LW,
DBG_E_LBU,
DBG_E_LHU,
DBG_E_LWR,
DBG_E_SB,
DBG_E_SH,
DBG_E_SWL,
DBG_E_SW,
DBG_E_SWR,
DBG_E_LWC2,
DBG_E_SWC2,
DBG_E_HLE,
DBG_E_SLL,
DBG_E_SRL,
DBG_E_SRA,
DBG_E_SLLV,
DBG_E_SRLV,
DBG_E_SRAV,
DBG_E_JR,
DBG_E_JALR,
DBG_E_SYSCALL,
DBG_E_BREAK,
DBG_E_MFHI,
DBG_E_MTHI,
DBG_E_MFLO,
DBG_E_MTLO,
DBG_E_MULT,
DBG_E_MULTU,
DBG_E_DIV,
DBG_E_DIVU,
DBG_E_ADD,
DBG_E_ADDU,
DBG_E_SUB,
DBG_E_SUBU,
DBG_E_AND,
DBG_E_OR,
DBG_E_XOR,
DBG_E_NOR,
DBG_E_SLT,
DBG_E_SLTU,
DBG_E_BLTZ,
DBG_E_BGEZ,
DBG_E_BLTZAL,
DBG_E_BGEZAL,
DBG_E_MFC0,
DBG_E_CFC0,
DBG_E_MTC0,
DBG_E_CTC0,
DBG_E_RFE,
DBG_E_BASIC,
DBG_E_RTPS,
DBG_E_NCLIP,
DBG_E_OP,
DBG_E_DPCS,
DBG_E_INTPL,
DBG_E_MVMVA,
DBG_E_NCDS,
DBG_E_CDP,
DBG_E_NCDT,
DBG_E_NCCS,
DBG_E_CC,
DBG_E_NCS,
DBG_E_NCT,
DBG_E_SQR,
DBG_E_DCPL,
DBG_E_DPCT,
DBG_E_AVSZ3,
DBG_E_AVSZ4,
DBG_E_RTPT,
DBG_E_GPF,
DBG_E_GPL,
DBG_E_NCCT,
DBG_E_MFC2,
DBG_E_CFC2,
DBG_E_MTC2,
DBG_E_CTC2,
DBG_E_NULL,
DBG_E_ERROR
};
#endif//_PGXP_DEBUG_H_

View File

@ -279,33 +279,37 @@ void MFC2(int reg) {
}
}
void PGXP_GTE_MFC2(u32 instr, u32 rdVal)
void PGXP_GTE_MFC2(u32 instr, u32 rtVal, u32 rdVal)
{
// CPU[Rt] = GTE_D[Rd]
Validate(&GTE_data_reg[rd(instr)], rdVal);
//MFC2(rd(instr));
CPU_reg[rt(instr)] = GTE_data_reg[rd(instr)];
CPU_reg[rt(instr)].value = rtVal;
}
void PGXP_GTE_MTC2(u32 instr, u32 rtVal)
void PGXP_GTE_MTC2(u32 instr, u32 rdVal, u32 rtVal)
{
// GTE_D[Rd] = CPU[Rt]
Validate(&CPU_reg[rt(instr)], rtVal);
PGXP_MTC2_int(CPU_reg[rt(instr)], rd(instr));
GTE_data_reg[rd(instr)].value = rdVal;
}
void PGXP_GTE_CFC2(u32 instr, u32 rdVal)
void PGXP_GTE_CFC2(u32 instr, u32 rtVal, u32 rdVal)
{
// CPU[Rt] = GTE_C[Rd]
Validate(&GTE_ctrl_reg[rd(instr)], rdVal);
CPU_reg[rt(instr)] = GTE_ctrl_reg[rd(instr)];
CPU_reg[rt(instr)].value = rtVal;
}
void PGXP_GTE_CTC2(u32 instr, u32 rtVal)
void PGXP_GTE_CTC2(u32 instr, u32 rdVal, u32 rtVal)
{
// GTE_C[Rd] = CPU[Rt]
Validate(&CPU_reg[rt(instr)], rtVal);
GTE_ctrl_reg[rd(instr)] = CPU_reg[rt(instr)];
GTE_ctrl_reg[rd(instr)].value = rdVal;
}
////////////////////////////////////

View File

@ -49,10 +49,10 @@ int PGXP_NLCIP_valid();
float PGXP_NCLIP();
// Data transfer tracking
void PGXP_GTE_MFC2(u32 instr, u32 rdVal); // copy GTE data reg to GPR reg (MFC2)
void PGXP_GTE_MTC2(u32 instr, u32 rtVal); // copy GPR reg to GTE data reg (MTC2)
void PGXP_GTE_CFC2(u32 instr, u32 rdVal); // copy GTE ctrl reg to GPR reg (CFC2)
void PGXP_GTE_CTC2(u32 instr, u32 rtVal); // copy GPR reg to GTE ctrl reg (CTC2)
void PGXP_GTE_MFC2(u32 instr, u32 rtVal, u32 rdVal); // copy GTE data reg to GPR reg (MFC2)
void PGXP_GTE_MTC2(u32 instr, u32 rdVal, u32 rtVal); // copy GPR reg to GTE data reg (MTC2)
void PGXP_GTE_CFC2(u32 instr, u32 rtVal, u32 rdVal); // copy GTE ctrl reg to GPR reg (CFC2)
void PGXP_GTE_CTC2(u32 instr, u32 rdVal, u32 rtVal); // copy GPR reg to GTE ctrl reg (CTC2)
// Memory Access
void PGXP_GTE_LWC2(u32 instr, u32 rtVal, u32 addr); // copy memory to GTE reg
void PGXP_GTE_SWC2(u32 instr, u32 rtVal, u32 addr); // copy GTE reg to memory

View File

@ -16,13 +16,15 @@ pgxpPsxNULL() {}
// Choose between debug and direct function
#ifdef PGXP_CPU_DEBUG
#define PGXP_PSX_FUNC_OP(pu, op, nReg) PGXP_psxTraceOp##nReg
#define PGXP_DBG_OP_E(op) DBG_E_##op,
#else
#define PGXP_PSX_FUNC_OP(pu, op, nReg) PGXP_##pu##_##op
#define PGXP_DBG_OP_E(op)
#endif
#define PGXP_INT_FUNC(pu, op) \
static void pgxpPsx##op() { \
PGXP_PSX_FUNC_OP(pu, op, )(psxRegs.code); \
PGXP_PSX_FUNC_OP(pu, op, )(PGXP_DBG_OP_E(op) psxRegs.code); \
psx##op(); \
}
@ -30,15 +32,16 @@ static void pgxpPsx##op() { \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, reg1); \
}
#define PGXP_INT_FUNC_1_0(pu, op, test, nReg, reg1)\
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) psxRegs.code, reg1); \
psx##op(); \
}
@ -46,47 +49,52 @@ static void pgxpPsx##op() \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
u32 temp2 = reg2; \
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1, temp2); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, reg1, temp2); \
}
#define PGXP_INT_FUNC_0_2(pu, op, test, nReg, reg1, reg2) \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1, reg2); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, reg1, reg2); \
}
#define PGXP_INT_FUNC_2_0(pu, op, test, nReg, reg1, reg2) \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
u32 temp1 = reg1; \
u32 temp2 = reg2; \
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, temp1, temp2); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, temp1, temp2); \
}
#define PGXP_INT_FUNC_2_1(pu, op, test, nReg, reg1, reg2, reg3) \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
u32 temp2 = reg2; \
u32 temp3 = reg3; \
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1, temp2, temp3); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, reg1, temp2, temp3); \
}
#define PGXP_INT_FUNC_2_2(pu, op, test, nReg, reg1, reg2, reg3, reg4) \
static void pgxpPsx##op() \
{ \
if (test) {psx##op(); return;} \
u32 tempInstr = psxRegs.code;\
u32 temp3 = reg3; \
u32 temp4 = reg4; \
psx##op(); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(psxRegs.code, reg1, reg2, temp3, temp4); \
PGXP_PSX_FUNC_OP(pu, op, nReg)(PGXP_DBG_OP_E(op) tempInstr, reg1, reg2, temp3, temp4); \
}
// Rt = Rs op imm
@ -152,19 +160,19 @@ PGXP_INT_FUNC_1_1(CPU, MTLO, 0 , 2, psxRegs.GPR.n.lo, psxRegs.GPR.r[_Rd_])
// COP2 (GTE)
PGXP_INT_FUNC_0_1(GTE, MFC2, !_Rt_, 1, psxRegs.CP2D.r[_Rd_])
PGXP_INT_FUNC_0_1(GTE, CFC2, !_Rt_, 1, psxRegs.CP2C.r[_Rd_])
PGXP_INT_FUNC_1_0(GTE, MTC2, 0, 1, psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC_1_0(GTE, CTC2, 0, 1, psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC_1_1(GTE, MFC2, !_Rt_, 2, psxRegs.GPR.r[_Rt_], psxRegs.CP2D.r[_Rd_])
PGXP_INT_FUNC_1_1(GTE, CFC2, !_Rt_, 2, psxRegs.GPR.r[_Rt_], psxRegs.CP2C.r[_Rd_])
PGXP_INT_FUNC_1_1(GTE, MTC2, 0, 2, psxRegs.CP2D.r[_Rd_], psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC_1_1(GTE, CTC2, 0, 2, psxRegs.CP2C.r[_Rd_], psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC_1_1(GTE, LWC2, 0, 2, psxRegs.CP2D.r[_Rt_], _oB_)
PGXP_INT_FUNC_1_1(GTE, SWC2, 0, 2, psxRegs.CP2D.r[_Rt_], _oB_)
// COP0
PGXP_INT_FUNC_0_1(CP0, MFC0, !_Rd_, 1, psxRegs.CP0.r[_Rd_])
PGXP_INT_FUNC_0_1(CP0, CFC0, !_Rd_, 1, psxRegs.CP0.r[_Rd_])
PGXP_INT_FUNC_1_0(CP0, MTC0, !_Rt_, 1, psxRegs.CP2D.r[_Rt_])
PGXP_INT_FUNC_1_0(CP0, CTC0, !_Rt_, 1, psxRegs.CP2D.r[_Rt_])
PGXP_INT_FUNC_1_1(CP0, MFC0, !_Rd_, 2, psxRegs.GPR.r[_Rt_], psxRegs.CP0.r[_Rd_])
PGXP_INT_FUNC_1_1(CP0, CFC0, !_Rd_, 2, psxRegs.GPR.r[_Rt_], psxRegs.CP0.r[_Rd_])
PGXP_INT_FUNC_1_1(CP0, MTC0, !_Rt_, 2, psxRegs.CP0.r[_Rd_], psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC_1_1(CP0, CTC0, !_Rt_, 2, psxRegs.CP0.r[_Rd_], psxRegs.GPR.r[_Rt_])
PGXP_INT_FUNC(CP0, RFE)
#endif//_PSX_INTERPRETER_PGXP_H_