I think I finally understood how origin-relative GE jumps are supposed to work.

This commit is contained in:
Henrik Rydgard committed 2013-02-02 13:38:34 +01:00
1 parent 78906531f9
commit 0769a1d3e8
7 files changed
+31 -18

No files matched your search

+16 -15
View File
@@ -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;
+1
View File
@@ -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;
}
+10
View File
@@ -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;
}
+1 -1
View File
@@ -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;
+1
View File
@@ -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:
+1 -1
Submodule native updated: c21e1ee2cc...f22ad17d40.