From b1f5a6ce4d7b9156910078300bfdf4ff0fd8ccf0 Mon Sep 17 00:00:00 2001 From: iCatButler Date: Sat, 26 Mar 2016 10:07:46 +0000 Subject: - Move pgxp_gpu source files into correct folder. - Trace 16 bit reads and writes, invalidate register or memory (fixes UI glitches) --- libpcsxcore/ix86/iR3000A.c | 15 +- libpcsxcore/pgxp_gte.c | 867 ++++++++++++++++++++++++--------------------- libpcsxcore/pgxp_gte.h | 69 ++-- 3 files changed, 501 insertions(+), 450 deletions(-) (limited to 'libpcsxcore') diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c index d18c47ec..42800fb2 100755 --- a/libpcsxcore/ix86/iR3000A.c +++ b/libpcsxcore/ix86/iR3000A.c @@ -1373,15 +1373,16 @@ static void recLH() { // SysPrintf("unhandled r16 %x\n", addr); } + PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode iPushOfB(); - CALLFunc((u32)psxMemRead16); + CALLFunc((u32)PGXP_psxMemRead16Trace); if (_Rt_) { iRegs[_Rt_].state = ST_UNK; MOVSX32R16toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); } // ADD32ItoR(ESP, 4); - resp+= 4; + resp+= 8; } static void recLHU() { @@ -1467,15 +1468,16 @@ static void recLHU() { // SysPrintf("unhandled r16u %x\n", addr); } + PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode iPushOfB(); - CALLFunc((u32)psxMemRead16); + CALLFunc((u32)PGXP_psxMemRead16Trace); if (_Rt_) { iRegs[_Rt_].state = ST_UNK; MOVZX32R16toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); } // ADD32ItoR(ESP, 4); - resp+= 4; + resp+= 8; } static void recLW() { @@ -1891,15 +1893,16 @@ static void recSH() { // SysPrintf("unhandled w16 %x\n", addr); } + PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode if (IsConst(_Rt_)) { PUSH32I (iRegs[_Rt_].k); } else { PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); } iPushOfB(); - CALLFunc((u32)psxMemWrite16); + CALLFunc((u32)PGXP_psxMemWrite16Trace); // ADD32ItoR(ESP, 8); - resp+= 8; + resp+= 12; } static void recSW() { diff --git a/libpcsxcore/pgxp_gte.c b/libpcsxcore/pgxp_gte.c index 4b22c778..901eeb9d 100644 --- a/libpcsxcore/pgxp_gte.c +++ b/libpcsxcore/pgxp_gte.c @@ -23,415 +23,460 @@ * * Created on: 12 Mar 2016 * Author: iCatButler -***************************************************************************/ - -#include "pgxp_gte.h" -#include "psxmem.h" - -typedef struct -{ - float x; - float y; - float z; - unsigned int valid; - unsigned int count; -} precise_value; - -typedef union -{ - struct - { - s16 x; - s16 y; - }; - u32 word; -} low_value; - -#define tolerance 1.0f - -precise_value GTE_reg[32]; -precise_value CPU_reg[32]; - -precise_value Mem[2048 * 1024 / 4]; // mirror 2MB in 32-bit words -precise_value Scratch[2048 * 1024 / 4]; // mirror 2MB in 32-bit words - -void PGXP_Init() -{ - memset(Mem, 0, sizeof(Mem)); -} - -char* PGXP_GetMem() -{ - return (char*)(Mem); -} - -#define VRAM 0 -#define SCRATCH 1 - -precise_value* ReadMem(u32 addr) -{ - u32 memType; - uint32_t paddr = addr; - int* ip = NULL; - - switch (paddr >> 20) - { - case 0x800: - case 0x801: - case 0xa00: - case 0xa01: - case 0x000: - case 0x001: - memType = VRAM; - break; - case 0x1f8: - memType = SCRATCH; - break; - default: - return NULL; - } - -#ifdef GTE_LOG - //GTE_LOG("PGXP_Read %x [%x] |", addr, paddr); -#endif - if (memType == VRAM) - { - paddr = (paddr & 0x1FFFFF) >> 2; - return &Mem[paddr]; - } - else if (memType == SCRATCH) - { - paddr = (paddr & 0x1FFFFF) >> 2; - return &Scratch[paddr]; - } - - return NULL; -} - -void WriteMem(precise_value value, u32 addr) -{ - u32 memType; - uint32_t paddr = addr; - int* ip = NULL; - - switch (paddr >> 20) - { - case 0x800: - case 0x801: - case 0xa00: - case 0xa01: - case 0x000: - case 0x001: - memType = VRAM; - break; - case 0x1f8: - memType = SCRATCH; - break; - default: - if (value.valid) - *ip = 5; - return; - } - -#ifdef GTE_LOG - GTE_LOG("PGXP_Write %x [%x] |", addr, paddr); -#endif - - // Store to RAM - if (memType == VRAM) - { - paddr = (paddr & 0x1FFFFF) >> 2; - Mem[paddr] = value; - } - else if (memType == SCRATCH) - { - paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2; - Scratch[paddr] = value; - } -} - -#define SX0 (GTE_reg[ 12 ].x) -#define SY0 (GTE_reg[ 12 ].y) -#define SX1 (GTE_reg[ 13 ].x) -#define SY1 (GTE_reg[ 13 ].y) -#define SX2 (GTE_reg[ 14 ].x) -#define SY2 (GTE_reg[ 14 ].y) - -#define SXY0 (GTE_reg[ 12 ]) -#define SXY1 (GTE_reg[ 13 ]) -#define SXY2 (GTE_reg[ 14 ]) -#define SXYP (GTE_reg[ 15 ]) - -unsigned int PGXP_validate(float high, s16 low) -{ - if (fabs(high - (float)(low)) < tolerance) - return 1; - return 0; -} - -// Check that value is still within tolerance of low precision value and invalidate if not -precise_value PGXP_validateXY(precise_value *high, u32 low) -{ - low_value temp; - precise_value ret; - - ret.valid = 0; - temp.word = low; - - if (!high) - return ret; - - high->valid = (high->valid && PGXP_validate(high->x, temp.x) && PGXP_validate(high->y, temp.y)); - - // Cheat - //if (!high->valid) - //{ - // high->x = temp.x; - // high->y = temp.y; - // high->valid = 1; - //} - - return *high; -} - -u32 PGXP_compareXY(precise_value high, u32 low) -{ - low_value temp; - temp.word = low; - - if (PGXP_validate(high.x, temp.x) && PGXP_validate(high.y, temp.y)) - return 1; - return 0; -} - -precise_value PGXP_copyXY(u32 low) -{ - low_value temp; - precise_value ret; - - ret.valid = 0; - temp.word = low; - - ret.x = temp.x; - ret.y = temp.y; - ret.count = 0; - ret.valid = 1; - - return ret; -} - -void PGXP_pushSXYZ2f(float _x, float _y, float _z) -{ - static unsigned int uCount = 0; - // push values down FIFO - SXY0 = SXY1; - SXY1 = SXY2; - - SXY2.x = _x; - SXY2.y = _y; - SXY2.z = _z; - SXY2.valid = 1; - SXY2.count = uCount++; - -#ifdef GTE_LOG - GTE_LOG("PGPR_PUSH (%f, %f) %u %u|", SXY2.x, SXY2.y, SXY2.valid, SXY2.count); -#endif -} - -void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z) -{ - float fx = (float)(_x) / (float)(1 << 16); - float fy = (float)(_y) / (float)(1 << 16); - float fz = (float)(_z); - - PGXP_pushSXYZ2f(fx, fy, fz); -} - -int PGXP_NLCIP_valid() -{ - if (SXY0.valid && SXY1.valid && SXY2.valid) - return 1; - return 0; -} - -float PGXP_NCLIP() -{ - float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1)); - - // ensure fractional values are not incorrectly rounded to 0 - if (fabs(nclip) < 1.0f) - nclip += (nclip < 0.f ? -2 : 2); - - return nclip; -} - -static precise_value PGXP_MFC2_int(u32 reg) -{ - switch (reg) - { - case 15: - GTE_reg[reg] = SXYP = SXY2; - break; - } - - return GTE_reg[reg]; -} - - -static void PGXP_MTC2_int(precise_value value, u32 reg) -{ - switch(reg) - { - case 15: - // push FIFO - SXY0 = SXY1; - SXY1 = SXY2; - SXY2 = value; - SXYP = SXY2; - break; - - case 31: - return; - } - - GTE_reg[reg] = value; -} - -// copy GTE data reg to GPR reg (MFC2) -void PGXP_MFC2(u32 gpr, u32 gtr, u32 value) -{ - if (!gpr) return; -#ifdef GTE_LOG - GTE_LOG("PGXP_MFC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, GTE_reg[gtr].valid, GTE_reg[gtr].count); -#endif - - CPU_reg[gpr] = PGXP_validateXY(>E_reg[gtr], value); -} - -// copy GPR reg to GTE data reg (MTC2) -void PGXP_MTC2(u32 gpr, u32 gtr, u32 value) -{ -#ifdef GTE_LOG - GTE_LOG("PGXP_MTC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, CPU_reg[gtr].valid, CPU_reg[gtr].count); -#endif - PGXP_MTC2_int(PGXP_validateXY(&CPU_reg[gpr], value), gtr); -} - -// copy memory to GTE reg -void PGXP_LWC2(u32 addr, u32 gtr, u32 value) -{ -#ifdef GTE_LOG - precise_value* pp = ReadMem(addr); - precise_value p; - low_value temp; - temp.word = value; - - p.x = p.y = p.valid = 0; - - if (pp) - p = *pp; - - GTE_LOG("PGXP_LWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, p.x, p.y, p.valid, p.count); -#endif - PGXP_MTC2_int(PGXP_validateXY(ReadMem(addr), value), gtr); -} - -//copy GTE reg to memory -void PGXP_SWC2(u32 addr, u32 gtr, u32 value) -{ -#ifdef GTE_LOG - low_value temp; - temp.word = value; - - if (PGXP_compareXY(GTE_reg[gtr], value)) - GTE_LOG("PGPR_SWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, GTE_reg[gtr].x, GTE_reg[gtr].y, GTE_reg[gtr].valid, GTE_reg[gtr].count); -#endif - WriteMem(PGXP_validateXY(>E_reg[gtr], value), addr); -} - -// ltore 32bit word -void PGPR_L32(u32 addr, u32 code, u32 value) -{ - u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register - u32 op = ((code >> 26)); - precise_value p; - - low_value temp; - temp.word = value; - - p.x = p.y = p.valid = p.count = 0; - - switch (op) - { - case 34: //LWL - CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); - break; - case 35: //LW - CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); - break; - case 37: //LWR - CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); - break; - case 50: //LWC2 (GTE vertex reads) - GTE_reg[reg] = PGXP_validateXY(ReadMem(addr), value); - break; - default: - // invalidate register - // WriteMem(p, addr); - break; - } - -#ifdef GTE_LOG - GTE_LOG("PGPR_L32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count); -#endif -} - -// store 32bit word -void PGPR_S32(u32 addr, u32 code, u32 value) -{ - u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register - u32 op = ((code >> 26)); - precise_value p; - - low_value temp; - temp.word = value; - - p.x = p.y = p.valid = p.count = 0; - -#ifdef GTE_LOG - GTE_LOG("PGPR_S32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count); -#endif - - switch (op) - { - case 42: //SWL - WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); - break; - case 43: //SW - WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); - break; - case 46: //SWR - WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); - break; - case 58: //SWC2 (GTE vertex writes) - WriteMem(PGXP_validateXY(>E_reg[reg], value), addr); - break; - default: - // invalidate memory - // WriteMem(p, addr); - break; - } -} - -u32 PGXP_psxMemRead32Trace(u32 mem, u32 code) -{ - u32 value = psxMemRead32(mem); - PGPR_L32(mem, code, value); - return value; -} - -void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code) -{ - PGPR_S32(mem, code, value); - psxMemWrite32(mem, value); +***************************************************************************/ + +#include "pgxp_gte.h" +#include "psxmem.h" + +typedef struct +{ + float x; + float y; + float z; + unsigned int valid; + unsigned int count; +} precise_value; + +typedef union +{ + struct + { + s16 x; + s16 y; + }; + u32 word; +} low_value; + +#define tolerance 1.0f + +precise_value GTE_reg[32]; +precise_value CPU_reg[32]; + +precise_value Mem[2048 * 1024 / 4]; // mirror 2MB in 32-bit words +precise_value Scratch[2048 * 1024 / 4]; // mirror 2MB in 32-bit words + +void PGXP_Init() +{ + memset(Mem, 0, sizeof(Mem)); +} + +char* PGXP_GetMem() +{ + return (char*)(Mem); +} + +#define VRAM 0 +#define SCRATCH 1 + +precise_value* ReadMem(u32 addr) +{ + u32 memType; + uint32_t paddr = addr; + int* ip = NULL; + + switch (paddr >> 20) + { + case 0x800: + case 0x801: + case 0xa00: + case 0xa01: + case 0x000: + case 0x001: + memType = VRAM; + break; + case 0x1f8: + memType = SCRATCH; + break; + default: + return NULL; + } + +#ifdef GTE_LOG + //GTE_LOG("PGXP_Read %x [%x] |", addr, paddr); +#endif + if (memType == VRAM) + { + paddr = (paddr & 0x1FFFFF) >> 2; + return &Mem[paddr]; + } + else if (memType == SCRATCH) + { + paddr = (paddr & 0x1FFFFF) >> 2; + return &Scratch[paddr]; + } + + return NULL; +} + +void WriteMem(precise_value value, u32 addr) +{ + u32 memType; + uint32_t paddr = addr; + int* ip = NULL; + + switch (paddr >> 20) + { + case 0x800: + case 0x801: + case 0xa00: + case 0xa01: + case 0x000: + case 0x001: + memType = VRAM; + break; + case 0x1f8: + memType = SCRATCH; + break; + default: + if (value.valid) + *ip = 5; + return; + } + +#ifdef GTE_LOG + GTE_LOG("PGXP_Write %x [%x] |", addr, paddr); +#endif + + // Store to RAM + if (memType == VRAM) + { + paddr = (paddr & 0x1FFFFF) >> 2; + Mem[paddr] = value; + } + else if (memType == SCRATCH) + { + paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2; + Scratch[paddr] = value; + } +} + +#define SX0 (GTE_reg[ 12 ].x) +#define SY0 (GTE_reg[ 12 ].y) +#define SX1 (GTE_reg[ 13 ].x) +#define SY1 (GTE_reg[ 13 ].y) +#define SX2 (GTE_reg[ 14 ].x) +#define SY2 (GTE_reg[ 14 ].y) + +#define SXY0 (GTE_reg[ 12 ]) +#define SXY1 (GTE_reg[ 13 ]) +#define SXY2 (GTE_reg[ 14 ]) +#define SXYP (GTE_reg[ 15 ]) + +unsigned int PGXP_validate(float high, s16 low) +{ + if (fabs(high - (float)(low)) < tolerance) + return 1; + return 0; +} + +// Check that value is still within tolerance of low precision value and invalidate if not +precise_value PGXP_validateXY(precise_value *high, u32 low) +{ + low_value temp; + precise_value ret; + + ret.valid = 0; + temp.word = low; + + if (!high) + return ret; + + high->valid = (high->valid && PGXP_validate(high->x, temp.x) && PGXP_validate(high->y, temp.y)); + + // Cheat + //if (!high->valid) + //{ + // high->x = temp.x; + // high->y = temp.y; + // high->valid = 1; + //} + + return *high; +} + +u32 PGXP_compareXY(precise_value high, u32 low) +{ + low_value temp; + temp.word = low; + + if (PGXP_validate(high.x, temp.x) && PGXP_validate(high.y, temp.y)) + return 1; + return 0; +} + +precise_value PGXP_copyXY(u32 low) +{ + low_value temp; + precise_value ret; + + ret.valid = 0; + temp.word = low; + + ret.x = temp.x; + ret.y = temp.y; + ret.count = 0; + ret.valid = 1; + + return ret; +} + +void PGXP_pushSXYZ2f(float _x, float _y, float _z) +{ + static unsigned int uCount = 0; + // push values down FIFO + SXY0 = SXY1; + SXY1 = SXY2; + + SXY2.x = _x; + SXY2.y = _y; + SXY2.z = _z; + SXY2.valid = 1; + SXY2.count = uCount++; + +#ifdef GTE_LOG + GTE_LOG("PGPR_PUSH (%f, %f) %u %u|", SXY2.x, SXY2.y, SXY2.valid, SXY2.count); +#endif +} + +void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z) +{ + float fx = (float)(_x) / (float)(1 << 16); + float fy = (float)(_y) / (float)(1 << 16); + float fz = (float)(_z); + + PGXP_pushSXYZ2f(fx, fy, fz); +} + +int PGXP_NLCIP_valid() +{ + if (SXY0.valid && SXY1.valid && SXY2.valid) + return 1; + return 0; +} + +float PGXP_NCLIP() +{ + float nclip = ((SX0 * SY1) + (SX1 * SY2) + (SX2 * SY0) - (SX0 * SY2) - (SX1 * SY0) - (SX2 * SY1)); + + // ensure fractional values are not incorrectly rounded to 0 + if (fabs(nclip) < 1.0f) + nclip += (nclip < 0.f ? -1 : 1); + + return nclip; +} + +static precise_value PGXP_MFC2_int(u32 reg) +{ + switch (reg) + { + case 15: + GTE_reg[reg] = SXYP = SXY2; + break; + } + + return GTE_reg[reg]; +} + + +static void PGXP_MTC2_int(precise_value value, u32 reg) +{ + switch(reg) + { + case 15: + // push FIFO + SXY0 = SXY1; + SXY1 = SXY2; + SXY2 = value; + SXYP = SXY2; + break; + + case 31: + return; + } + + GTE_reg[reg] = value; +} + +// copy GTE data reg to GPR reg (MFC2) +void PGXP_MFC2(u32 gpr, u32 gtr, u32 value) +{ + if (!gpr) return; +#ifdef GTE_LOG + GTE_LOG("PGXP_MFC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, GTE_reg[gtr].valid, GTE_reg[gtr].count); +#endif + + CPU_reg[gpr] = PGXP_validateXY(>E_reg[gtr], value); +} + +// copy GPR reg to GTE data reg (MTC2) +void PGXP_MTC2(u32 gpr, u32 gtr, u32 value) +{ +#ifdef GTE_LOG + GTE_LOG("PGXP_MTC2 [%x] [%x] %x (%u %u)|", gpr, gtr, value, CPU_reg[gtr].valid, CPU_reg[gtr].count); +#endif + PGXP_MTC2_int(PGXP_validateXY(&CPU_reg[gpr], value), gtr); +} + +// copy memory to GTE reg +void PGXP_LWC2(u32 addr, u32 gtr, u32 value) +{ +#ifdef GTE_LOG + precise_value* pp = ReadMem(addr); + precise_value p; + low_value temp; + temp.word = value; + + p.x = p.y = p.valid = 0; + + if (pp) + p = *pp; + + GTE_LOG("PGXP_LWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, p.x, p.y, p.valid, p.count); +#endif + PGXP_MTC2_int(PGXP_validateXY(ReadMem(addr), value), gtr); +} + +//copy GTE reg to memory +void PGXP_SWC2(u32 addr, u32 gtr, u32 value) +{ +#ifdef GTE_LOG + low_value temp; + temp.word = value; + + if (PGXP_compareXY(GTE_reg[gtr], value)) + GTE_LOG("PGPR_SWC2 %x [%x] %x (%d, %d) (%f, %f) %u %u|", addr, gtr, value, temp.x, temp.y, GTE_reg[gtr].x, GTE_reg[gtr].y, GTE_reg[gtr].valid, GTE_reg[gtr].count); +#endif + WriteMem(PGXP_validateXY(>E_reg[gtr], value), addr); +} + +// load 32bit word +void PGPR_L32(u32 addr, u32 code, u32 value) +{ + u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + u32 op = ((code >> 26)); + precise_value p; + + low_value temp; + temp.word = value; + + p.x = p.y = p.valid = p.count = 0; + + switch (op) + { + case 34: //LWL + CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); + break; + case 35: //LW + CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); + break; + case 37: //LWR + CPU_reg[reg] = PGXP_validateXY(ReadMem(addr), value); + break; + case 50: //LWC2 (GTE vertex reads) + GTE_reg[reg] = PGXP_validateXY(ReadMem(addr), value); + break; + default: + // invalidate register + // CPU_reg[reg] = p; + break; + } + +#ifdef GTE_LOG + GTE_LOG("PGPR_L32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count); +#endif +} + +// store 16bit word +void PGPR_S32(u32 addr, u32 code, u32 value) +{ + u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + u32 op = ((code >> 26)); + precise_value p; + + low_value temp; + temp.word = value; + + p.x = p.y = p.valid = p.count = 0; + +#ifdef GTE_LOG + GTE_LOG("PGPR_S32 %u: %x %x[%x %x] (%d, %d) (%f, %f) %x %u|", op, addr, value, code, reg, temp.x, temp.y, CPU_reg[reg].x, CPU_reg[reg].y, CPU_reg[reg].valid, CPU_reg[reg].count); +#endif + + switch (op) + { + case 42: //SWL + WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); + break; + case 43: //SW + WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); + break; + case 46: //SWR + WriteMem(PGXP_validateXY(&CPU_reg[reg], value), addr); + break; + case 58: //SWC2 (GTE vertex writes) + WriteMem(PGXP_validateXY(>E_reg[reg], value), addr); + break; + default: + // invalidate memory + // WriteMem(p, addr); + break; + } +} + +// load 16bit word +void PGPR_L16(u32 addr, u32 code, u16 value) +{ + u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + u32 op = ((code >> 26)); + precise_value p; + + low_value temp; + temp.word = value; + + p.x = p.y = p.valid = p.count = 0; + + // invalidate register + CPU_reg[reg] = p; +} + +// store 32bit word +void PGPR_S16(u32 addr, u32 code, u32 value) +{ + u32 reg = ((code >> 16) & 0x1F); // The rt part of the instruction register + u32 op = ((code >> 26)); + precise_value p; + + low_value temp; + temp.word = value; + + p.x = p.y = p.valid = p.count = 0; + + // invalidate memory + WriteMem(p, addr); +} + +u32 PGXP_psxMemRead32Trace(u32 mem, u32 code) +{ + u32 value = psxMemRead32(mem); + PGPR_L32(mem, code, value); + return value; +} + +void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code) +{ + PGPR_S32(mem, code, value); + psxMemWrite32(mem, value); +} + +u16 PGXP_psxMemRead16Trace(u32 mem, u32 code) +{ + u16 value = psxMemRead16(mem); + PGPR_L16(mem, code, value); + return value; +} + +void PGXP_psxMemWrite16Trace(u32 mem, u16 value, u32 code) +{ + PGPR_S16(mem, code, value); + psxMemWrite16(mem, value); } \ No newline at end of file diff --git a/libpcsxcore/pgxp_gte.h b/libpcsxcore/pgxp_gte.h index c97c5b29..7ad20823 100644 --- a/libpcsxcore/pgxp_gte.h +++ b/libpcsxcore/pgxp_gte.h @@ -23,36 +23,39 @@ * * Created on: 12 Mar 2016 * Author: iCatButler -***************************************************************************/ - -#ifndef _PGXP_GTE_H_ -#define _PGXP_GTE_H_ - -#include "psxcommon.h" - -void PGXP_Init(); // initialise memory -char* PGXP_GetMem(); // return pointer to precision memory - -// -- GTE functions -// Transforms -void PGXP_pushSXYZ2f(float _x, float _y, float _z); -void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z); -int PGXP_NLCIP_valid(); -float PGXP_NCLIP(); - -// Data transfer tracking -void PGXP_MFC2(u32 gpr, u32 gtr, u32 value); // copy GTE reg to GPR reg (MFC2) -void PGXP_MTC2(u32 gpr, u32 gtr, u32 value); // copy GPR reg to GTR reg (MTC2) -void PGXP_LWC2(u32 addr, u32 gtr, u32 value); // copy memory to GTE reg -void PGXP_SWC2(u32 addr, u32 gtr, u32 value); // copy GTE reg to memory - -// -- CPU functions -// Data transfer tracking -void PGPR_L32(u32 addr, u32 code, u32 value); // load 32bit word -void PGPR_S32(u32 addr, u32 code, u32 value); // store 32bit word - -// Memory Read/Write hooks -u32 PGXP_psxMemRead32Trace(u32 mem, u32 code); -void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code); - -#endif /* _PGXP_GTE_H_ */ +***************************************************************************/ + +#ifndef _PGXP_GTE_H_ +#define _PGXP_GTE_H_ + +#include "psxcommon.h" + +void PGXP_Init(); // initialise memory +char* PGXP_GetMem(); // return pointer to precision memory + +// -- GTE functions +// Transforms +void PGXP_pushSXYZ2f(float _x, float _y, float _z); +void PGXP_pushSXYZ2s(s64 _x, s64 _y, s64 _z); +int PGXP_NLCIP_valid(); +float PGXP_NCLIP(); + +// Data transfer tracking +void PGXP_MFC2(u32 gpr, u32 gtr, u32 value); // copy GTE reg to GPR reg (MFC2) +void PGXP_MTC2(u32 gpr, u32 gtr, u32 value); // copy GPR reg to GTR reg (MTC2) +void PGXP_LWC2(u32 addr, u32 gtr, u32 value); // copy memory to GTE reg +void PGXP_SWC2(u32 addr, u32 gtr, u32 value); // copy GTE reg to memory + +// -- CPU functions +// Data transfer tracking +void PGPR_L32(u32 addr, u32 code, u32 value); // load 32bit word +void PGPR_S32(u32 addr, u32 code, u32 value); // store 32bit word + +// Memory Read/Write hooks +u32 PGXP_psxMemRead32Trace(u32 mem, u32 code); +void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code); + +u16 PGXP_psxMemRead16Trace(u32 mem, u32 code); +void PGXP_psxMemWrite16Trace(u32 mem, u16 value, u32 code); + +#endif /* _PGXP_GTE_H_ */ -- cgit v1.2.3