From e3df273095a5800e3dcdcb63bd66e269c0c2d3a8 Mon Sep 17 00:00:00 2001 From: iCatButler Date: Mon, 28 Mar 2016 13:01:50 +0100 Subject: - Fix memory addresses as each mirrored address range is further mirrored 4 times... :( - Catch 8bit reads/writes and invalidate registers and memory as needed - Prevent reading over the end of stride and count arrays when decoding primitive commands --- libpcsxcore/ix86/iR3000A.c | 15 ++++---- libpcsxcore/pgxp_gte.c | 88 +++++++++++++++++++++++++-------------------- libpcsxcore/pgxp_gte.h | 3 ++ plugins/peopsxgl/pgxp_gpu.c | 2 +- 4 files changed, 62 insertions(+), 46 deletions(-) diff --git a/libpcsxcore/ix86/iR3000A.c b/libpcsxcore/ix86/iR3000A.c index 42800fb2..2ba1cd18 100755 --- a/libpcsxcore/ix86/iR3000A.c +++ b/libpcsxcore/ix86/iR3000A.c @@ -1283,15 +1283,16 @@ static void recLB() { // SysPrintf("unhandled r8 %x\n", addr); } + PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode iPushOfB(); - CALLFunc((u32)psxMemRead8); + CALLFunc((u32)PGXP_psxMemRead8Trace); if (_Rt_) { iRegs[_Rt_].state = ST_UNK; MOVSX32R8toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); } // ADD32ItoR(ESP, 4); - resp+= 4; + resp+= 8; } static void recLBU() { @@ -1328,15 +1329,16 @@ static void recLBU() { // SysPrintf("unhandled r8u %x\n", addr); } + PUSH32I(psxRegs.code); // iCB: Needed to extract reg and opcode iPushOfB(); - CALLFunc((u32)psxMemRead8); + CALLFunc((u32)PGXP_psxMemRead8Trace); if (_Rt_) { iRegs[_Rt_].state = ST_UNK; MOVZX32R8toR(EAX, EAX); MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); } // ADD32ItoR(ESP, 4); - resp+= 4; + resp+= 8; } static void recLH() { @@ -1831,15 +1833,16 @@ static void recSB() { // SysPrintf("unhandled w8 %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)psxMemWrite8); + CALLFunc((u32)PGXP_psxMemWrite8Trace); // ADD32ItoR(ESP, 8); - resp+= 8; + resp+= 12; } static void recSH() { diff --git a/libpcsxcore/pgxp_gte.c b/libpcsxcore/pgxp_gte.c index 901eeb9d..de3797d6 100644 --- a/libpcsxcore/pgxp_gte.c +++ b/libpcsxcore/pgxp_gte.c @@ -74,20 +74,21 @@ precise_value* ReadMem(u32 addr) uint32_t paddr = addr; int* ip = NULL; - switch (paddr >> 20) + switch (paddr >> 24) { - case 0x800: - case 0x801: - case 0xa00: - case 0xa01: - case 0x000: - case 0x001: + case 0x80: + case 0xa0: + case 0x00: memType = VRAM; break; - case 0x1f8: - memType = SCRATCH; - break; default: + if ((paddr >> 20) == 0x1f8) + { + memType = SCRATCH; + break; + } + // if (value.valid) //FAILED @ 0x807FFEE8 + // *ip = 5; return NULL; } @@ -96,12 +97,14 @@ precise_value* ReadMem(u32 addr) #endif if (memType == VRAM) { - paddr = (paddr & 0x1FFFFF) >> 2; + // RAM furher mirrored over 8MB + //paddr = (paddr & 0x1FFFFF) >> 2; + paddr = ((paddr & 0x7FFFFF) % 0x200000) >> 2; return &Mem[paddr]; } else if (memType == SCRATCH) { - paddr = (paddr & 0x1FFFFF) >> 2; + paddr = (paddr & 0x1FFFFF) >> 2;// (paddr & 0x3FFF) >> 2; return &Scratch[paddr]; } @@ -114,22 +117,22 @@ void WriteMem(precise_value value, u32 addr) uint32_t paddr = addr; int* ip = NULL; - switch (paddr >> 20) + switch (paddr >> 24) { - case 0x800: - case 0x801: - case 0xa00: - case 0xa01: - case 0x000: - case 0x001: + case 0x80: + case 0xa0: + case 0x00: memType = VRAM; break; - case 0x1f8: - memType = SCRATCH; - break; default: - if (value.valid) - *ip = 5; + if ((paddr >> 20) == 0x1f8) + { + memType = SCRATCH; + break; + } + else + if (value.valid) //FAILED @ 0x807FFEE8 + *ip = 5; return; } @@ -140,7 +143,9 @@ void WriteMem(precise_value value, u32 addr) // Store to RAM if (memType == VRAM) { - paddr = (paddr & 0x1FFFFF) >> 2; + // RAM furher mirrored over 8MB + //paddr = (paddr & 0x1FFFFF) >> 2; + paddr = ((paddr & 0x7FFFFF) % 0x200000) >> 2;// (paddr & 0x3FFF) >> 2; Mem[paddr] = value; } else if (memType == SCRATCH) @@ -423,32 +428,24 @@ void PGPR_S32(u32 addr, u32 code, u32 value) } } -// load 16bit word -void PGPR_L16(u32 addr, u32 code, u16 value) +// invalidate register (invalid 8/16 bit read) +void PGPR_InvalidLoad(u32 addr, u32 code) { 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) +// invalidate memory address (invalid 8/16 bit write) +void PGPR_InvalidStore(u32 addr, u32 code) { 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 @@ -471,12 +468,25 @@ void PGXP_psxMemWrite32Trace(u32 mem, u32 value, u32 code) u16 PGXP_psxMemRead16Trace(u32 mem, u32 code) { u16 value = psxMemRead16(mem); - PGPR_L16(mem, code, value); + PGPR_InvalidLoad(mem, code); return value; } void PGXP_psxMemWrite16Trace(u32 mem, u16 value, u32 code) { - PGPR_S16(mem, code, value); + PGPR_InvalidStore(mem, code); psxMemWrite16(mem, value); +} + +u8 PGXP_psxMemRead8Trace(u32 mem, u32 code) +{ + u8 value = psxMemRead8(mem); + PGPR_InvalidLoad(mem, code); + return value; +} + +void PGXP_psxMemWrite8Trace(u32 mem, u8 value, u32 code) +{ + PGPR_InvalidStore(mem, code); + psxMemWrite8(mem, value); } \ No newline at end of file diff --git a/libpcsxcore/pgxp_gte.h b/libpcsxcore/pgxp_gte.h index 7ad20823..50c8859b 100644 --- a/libpcsxcore/pgxp_gte.h +++ b/libpcsxcore/pgxp_gte.h @@ -58,4 +58,7 @@ 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); +u8 PGXP_psxMemRead8Trace(u32 mem, u32 code); +void PGXP_psxMemWrite8Trace(u32 mem, u8 value, u32 code); + #endif /* _PGXP_GTE_H_ */ diff --git a/plugins/peopsxgl/pgxp_gpu.c b/plugins/peopsxgl/pgxp_gpu.c index 5b64382a..1ce67bf8 100644 --- a/plugins/peopsxgl/pgxp_gpu.c +++ b/plugins/peopsxgl/pgxp_gpu.c @@ -64,7 +64,7 @@ void PGXP_SetAddress(unsigned int addr) int PGXP_GetVertices(unsigned int* addr, void* pOutput) { unsigned int primCmd = ((*addr >> 24) & 0xff); // primitive command - unsigned int primIdx = (primCmd - 0x20) >> 2; // index to primitive lookup + unsigned int primIdx = min((primCmd - 0x20) >> 2, 8); // index to primitive lookup OGLVertex* pVertex = (OGLVertex*)pOutput; // pointer to output vertices unsigned int stride = primStrideTable[primIdx]; // stride between vertices unsigned int count = primCountTable[primIdx]; // number of vertices -- cgit v1.2.3