diff --git a/GPU/GLES/DisplayListInterpreter.cpp b/GPU/GLES/DisplayListInterpreter.cpp index fa7bfa20e0..273b2e91f6 100644 --- a/GPU/GLES/DisplayListInterpreter.cpp +++ b/GPU/GLES/DisplayListInterpreter.cpp @@ -314,17 +314,14 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { // Handle control and drawing commands here directly. The others we delegate. switch (cmd) { case GE_CMD_BASE: - //DEBUG_LOG(G3D,"DL BASE: %06x", data & 0xFFFFFF); break; case GE_CMD_VADDR: /// <<8???? gstate_c.vertexAddr = ((gstate.base & 0x00FF0000) << 8)|data; - //DEBUG_LOG(G3D,"DL VADDR: %06x", gstate_c.vertexAddr); break; case GE_CMD_IADDR: gstate_c.indexAddr = ((gstate.base & 0x00FF0000) << 8)|data; - //DEBUG_LOG(G3D,"DL IADDR: %06x", gstate_c.indexAddr); break; case GE_CMD_PRIM: @@ -388,23 +385,24 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { case GE_CMD_JUMP: { - u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF; + u32 target = gstate_c.getJumpAddress(data); if (Memory::IsValidAddress(target)) { currentList->pc = target - 4; // pc will be increased after we return, counteract that } else { - ERROR_LOG(G3D, "JUMP to illegal address %08x - ignoring??", target); + ERROR_LOG(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, data); } } break; case GE_CMD_CALL: { + // Saint Seiya needs correct support for relative calls. u32 retval = currentList->pc + 4; - u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF; + u32 target = gstate_c.getJumpAddress(data); if (stackptr == ARRAY_SIZE(stack)) { ERROR_LOG(G3D, "CALL: Stack full!"); } else if (!Memory::IsValidAddress(target)) { - ERROR_LOG(G3D, "CALL to illegal address %08x - ignoring??", target); + ERROR_LOG(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, data); } else { stack[stackptr++] = retval; currentList->pc = target - 4; // pc will be increased after we return, counteract that @@ -418,6 +416,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { ERROR_LOG(G3D, "RET: Stack empty!"); } else { u32 target = (currentList->pc & 0xF0000000) | (stack[--stackptr] & 0x0FFFFFFF); + //target = (target + gstate_c.originAddr) & 0xFFFFFFF; currentList->pc = target - 4; if (!Memory::IsValidAddress(currentList->pc)) { ERROR_LOG(G3D, "Invalid DL PC %08x on return", currentList->pc); @@ -427,6 +426,16 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { } break; + case GE_CMD_OFFSETADDR: + gstate_c.offsetAddr = data << 8; + // ??? + break; + + case GE_CMD_ORIGIN: + gstate_c.offsetAddr = currentList->pc; + break; + + case GE_CMD_SIGNAL: { // Processed in GE_END. Has data. @@ -495,10 +504,6 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { // bounding box test. Let's do nothing. break; - case GE_CMD_ORIGIN: - gstate.offsetAddr = currentList->pc & 0xFFFFFF; - break; - case GE_CMD_VERTEXTYPE: if (diff & GE_VTYPE_THROUGH) { // Throughmode changed, let's make the proj matrix dirty. @@ -507,10 +512,6 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) { // This sets through-mode or not, as well. break; - case GE_CMD_OFFSETADDR: - // offsetAddr = data<<8; - break; - case GE_CMD_REGION1: { int x1 = data & 0x3ff; diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp index cfd3f23fc7..75474fcb6f 100644 --- a/GPU/GPUState.cpp +++ b/GPU/GPUState.cpp @@ -31,6 +31,7 @@ GPUStatistics gpuStats; void InitGfxState() { memset(&gstate, 0, sizeof(gstate)); + memset(&gstate_c, 0, sizeof(gstate_c)); for (int i = 0; i < 256; i++) { gstate.cmdmem[i] = i << 24; } diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 19cda92bf0..e02979098a 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -231,6 +231,8 @@ struct GPUStateCache u32 vertexAddr; u32 indexAddr; + u32 offsetAddr; + bool textureChanged; float uScale,vScale,zScale; @@ -247,6 +249,9 @@ struct GPUStateCache float vpWidth; float vpHeight; + + + u32 getJumpAddress(u32 data) const; }; // TODO: Implement support for these. @@ -322,3 +327,8 @@ extern GPUgstate gstate; extern GPUStateCache gstate_c; extern GPUInterface *gpu; extern GPUStatistics gpuStats; + +inline u32 GPUStateCache::getJumpAddress(u32 data) const { + u32 baseExtended = ((gstate.base & 0x0F0000) << 8) | (data & 0xFFFFFF); + return (gstate_c.offsetAddr + baseExtended) & 0x0FFFFFFF; +} diff --git a/GPU/GeDisasm.cpp b/GPU/GeDisasm.cpp index 1ef05ca609..1a71f6807f 100644 --- a/GPU/GeDisasm.cpp +++ b/GPU/GeDisasm.cpp @@ -85,7 +85,7 @@ void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer) { case GE_CMD_CALL: { u32 retval = pc + 4; - u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF; + u32 target = gstate_c.getJumpAddress(op & 0xFFFFFF); sprintf(buffer, "CMD CALL - %08x to %08x, ret=%08x", pc, target, retval); } break; diff --git a/GPU/Null/NullGpu.cpp b/GPU/Null/NullGpu.cpp index ed9e56ac29..0413b9f92e 100644 --- a/GPU/Null/NullGpu.cpp +++ b/GPU/Null/NullGpu.cpp @@ -169,6 +169,7 @@ void NullGPU::ExecuteOp(u32 op, u32 diff) case GE_CMD_ORIGIN: gstate.offsetAddr = currentList->pc & 0xFFFFFF; + gstate_c.offsetAddr = currentList->pc; break; case GE_CMD_VERTEXTYPE: diff --git a/native b/native index c21e1ee2cc..f22ad17d40 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit c21e1ee2cced55bb68edefbb58ba4b30bde807ba +Subproject commit f22ad17d40c00d9a60bd21f53820012b302d7559 diff --git a/pspautotests b/pspautotests index 31e3915d4e..4f047eb8c7 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 31e3915d4e4302e5e7dc2f6c2a4f191c420f38f9 +Subproject commit 4f047eb8c76c6388a63a87ec72e98c64670152d5