From 256e98b84198116d662366e6633cf9b401a02191 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 16 Apr 2014 08:12:21 -0700 Subject: [PATCH] Add the common funcs to the direct exec calls. --- GPU/GLES/GLES_GPU.cpp | 14 +- GPU/GPUCommon.cpp | 478 ++++++++++++++++++++++-------------------- GPU/GPUCommon.h | 8 + 3 files changed, 265 insertions(+), 235 deletions(-) diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp index aaf966ecf7..fd62883075 100644 --- a/GPU/GLES/GLES_GPU.cpp +++ b/GPU/GLES/GLES_GPU.cpp @@ -303,16 +303,16 @@ static const CommandTableEntry commandTable[] = { {GE_CMD_TRANSFERSIZE, 0}, // From Common. No flushing but definitely need execute. - {GE_CMD_OFFSETADDR, FLAG_EXECUTE}, - {GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC}, // Really? + {GE_CMD_OFFSETADDR, FLAG_EXECUTE, &GPUCommon::Execute_OffsetAddr}, + {GE_CMD_ORIGIN, FLAG_EXECUTE | FLAG_READS_PC, &GPUCommon::Execute_Origin}, // Really? {GE_CMD_PRIM, FLAG_EXECUTE, &GLES_GPU::Execute_Prim}, - {GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC}, - {GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC}, - {GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC}, - {GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC}, // Flush? + {GE_CMD_JUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, &GPUCommon::Execute_Jump}, + {GE_CMD_CALL, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, &GPUCommon::Execute_Call}, + {GE_CMD_RET, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, &GPUCommon::Execute_Ret}, + {GE_CMD_END, FLAG_FLUSHBEFORE | FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, &GPUCommon::Execute_End}, // Flush? {GE_CMD_VADDR, FLAG_EXECUTE, &GLES_GPU::Execute_Vaddr}, {GE_CMD_IADDR, FLAG_EXECUTE, &GLES_GPU::Execute_Iaddr}, - {GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC}, // EXECUTE + {GE_CMD_BJUMP, FLAG_EXECUTE | FLAG_READS_PC | FLAG_WRITES_PC, &GPUCommon::Execute_BJump}, // EXECUTE {GE_CMD_BOUNDINGBOX, FLAG_EXECUTE}, // + FLUSHBEFORE when we implement... or not, do we need to? // Changing the vertex type requires us to flush. diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b591a5d9f1..6e89500603 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -683,9 +683,249 @@ void GPUCommon::PreExecuteOp(u32 op, u32 diff) { // Nothing to do } +void GPUCommon::Execute_OffsetAddr(u32 op, u32 diff) { + gstate_c.offsetAddr = op << 8; +} + +void GPUCommon::Execute_Origin(u32 op, u32 diff) { + easy_guard guard(listLock); + gstate_c.offsetAddr = currentList->pc; +} + +void GPUCommon::Execute_Jump(u32 op, u32 diff) { + easy_guard guard(listLock); + const u32 data = op & 0x00FFFFFF; + const u32 target = gstate_c.getRelativeAddress(data); + if (Memory::IsValidAddress(target)) { + UpdatePC(currentList->pc, target - 4); + currentList->pc = target - 4; // pc will be increased after we return, counteract that + } else { + ERROR_LOG_REPORT(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, data); + } +} + +void GPUCommon::Execute_BJump(u32 op, u32 diff) { + if (!currentList->bboxResult) { + // bounding box jump. + easy_guard guard(listLock); + const u32 data = op & 0x00FFFFFF; + const u32 target = gstate_c.getRelativeAddress(data); + if (Memory::IsValidAddress(target)) { + UpdatePC(currentList->pc, target - 4); + currentList->pc = target - 4; // pc will be increased after we return, counteract that + } else { + ERROR_LOG_REPORT(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, data); + } + } +} + +void GPUCommon::Execute_Call(u32 op, u32 diff) { + easy_guard guard(listLock); + + // Saint Seiya needs correct support for relative calls. + const u32 retval = currentList->pc + 4; + const u32 data = op & 0x00FFFFFF; + const u32 target = gstate_c.getRelativeAddress(data); + + // Bone matrix optimization - many games will CALL a bone matrix (!). + if ((Memory::ReadUnchecked_U32(target) >> 24) == GE_CMD_BONEMATRIXDATA) { + // Check for the end + if ((Memory::ReadUnchecked_U32(target + 11 * 4) >> 24) == GE_CMD_BONEMATRIXDATA && + (Memory::ReadUnchecked_U32(target + 12 * 4) >> 24) == GE_CMD_RET) { + // Yep, pretty sure this is a bone matrix call. + FastLoadBoneMatrix(target); + return; + } + } + + if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { + ERROR_LOG_REPORT(G3D, "CALL: Stack full!"); + } else if (!Memory::IsValidAddress(target)) { + ERROR_LOG_REPORT(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, data); + } else { + auto &stackEntry = currentList->stack[currentList->stackptr++]; + stackEntry.pc = retval; + stackEntry.offsetAddr = gstate_c.offsetAddr; + // The base address is NOT saved/restored for a regular call. + UpdatePC(currentList->pc, target - 4); + currentList->pc = target - 4; // pc will be increased after we return, counteract that + } +} + +void GPUCommon::Execute_Ret(u32 op, u32 diff) { + easy_guard guard(listLock); + if (currentList->stackptr == 0) { + DEBUG_LOG_REPORT(G3D, "RET: Stack empty!"); + } else { + auto &stackEntry = currentList->stack[--currentList->stackptr]; + gstate_c.offsetAddr = stackEntry.offsetAddr; + u32 target = (currentList->pc & 0xF0000000) | (stackEntry.pc & 0x0FFFFFFF); + UpdatePC(currentList->pc, target - 4); + currentList->pc = target - 4; + if (!Memory::IsValidAddress(currentList->pc)) { + ERROR_LOG_REPORT(G3D, "Invalid DL PC %08x on return", currentList->pc); + UpdateState(GPUSTATE_ERROR); + } + } +} + +void GPUCommon::Execute_End(u32 op, u32 diff) { + easy_guard guard(listLock); + const u32 data = op & 0x00FFFFFF; + const u32 prev = Memory::ReadUnchecked_U32(currentList->pc - 4); + UpdatePC(currentList->pc); + switch (prev >> 24) { + case GE_CMD_SIGNAL: + { + // TODO: see http://code.google.com/p/jpcsp/source/detail?r=2935# + SignalBehavior behaviour = static_cast((prev >> 16) & 0xFF); + int signal = prev & 0xFFFF; + int enddata = data & 0xFFFF; + bool trigger = true; + currentList->subIntrToken = signal; + + switch (behaviour) { + case PSP_GE_SIGNAL_HANDLER_SUSPEND: + // Suspend the list, and call the signal handler. When it's done, resume. + // Before sdkver 0x02000010, listsync should return paused. + if (sceKernelGetCompiledSdkVersion() <= 0x02000010) + currentList->state = PSP_GE_DL_STATE_PAUSED; + currentList->signal = behaviour; + DEBUG_LOG(G3D, "Signal with wait. signal/end: %04x %04x", signal, enddata); + break; + case PSP_GE_SIGNAL_HANDLER_CONTINUE: + // Resume the list right away, then call the handler. + currentList->signal = behaviour; + DEBUG_LOG(G3D, "Signal without wait. signal/end: %04x %04x", signal, enddata); + break; + case PSP_GE_SIGNAL_HANDLER_PAUSE: + // Pause the list instead of ending at the next FINISH. + // Call the handler with the PAUSE signal value at that FINISH. + // Technically, this ought to trigger an interrupt, but it won't do anything. + // But right now, signal is always reset by interrupts, so that causes pause to not work. + trigger = false; + currentList->signal = behaviour; + DEBUG_LOG(G3D, "Signal with Pause. signal/end: %04x %04x", signal, enddata); + break; + case PSP_GE_SIGNAL_SYNC: + // Acts as a memory barrier, never calls any user code. + // Technically, this ought to trigger an interrupt, but it won't do anything. + // Triggering here can cause incorrect rescheduling, which breaks 3rd Birthday. + // However, this is likely a bug in how GE signal interrupts are handled. + trigger = false; + currentList->signal = behaviour; + DEBUG_LOG(G3D, "Signal with Sync. signal/end: %04x %04x", signal, enddata); + break; + case PSP_GE_SIGNAL_JUMP: + { + trigger = false; + currentList->signal = behaviour; + // pc will be increased after we return, counteract that. + u32 target = ((signal << 16) | enddata) - 4; + if (!Memory::IsValidAddress(target)) { + ERROR_LOG_REPORT(G3D, "Signal with Jump: bad address. signal/end: %04x %04x", signal, enddata); + } else { + UpdatePC(currentList->pc, target); + currentList->pc = target; + DEBUG_LOG(G3D, "Signal with Jump. signal/end: %04x %04x", signal, enddata); + } + } + break; + case PSP_GE_SIGNAL_CALL: + { + trigger = false; + currentList->signal = behaviour; + // pc will be increased after we return, counteract that. + u32 target = ((signal << 16) | enddata) - 4; + if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { + ERROR_LOG_REPORT(G3D, "Signal with Call: stack full. signal/end: %04x %04x", signal, enddata); + } else if (!Memory::IsValidAddress(target)) { + ERROR_LOG_REPORT(G3D, "Signal with Call: bad address. signal/end: %04x %04x", signal, enddata); + } else { + // TODO: This might save/restore other state... + auto &stackEntry = currentList->stack[currentList->stackptr++]; + stackEntry.pc = currentList->pc; + stackEntry.offsetAddr = gstate_c.offsetAddr; + stackEntry.baseAddr = gstate.base; + UpdatePC(currentList->pc, target); + currentList->pc = target; + DEBUG_LOG(G3D, "Signal with Call. signal/end: %04x %04x", signal, enddata); + } + } + break; + case PSP_GE_SIGNAL_RET: + { + trigger = false; + currentList->signal = behaviour; + if (currentList->stackptr == 0) { + ERROR_LOG_REPORT(G3D, "Signal with Return: stack empty. signal/end: %04x %04x", signal, enddata); + } else { + // TODO: This might save/restore other state... + auto &stackEntry = currentList->stack[--currentList->stackptr]; + gstate_c.offsetAddr = stackEntry.offsetAddr; + gstate.base = stackEntry.baseAddr; + UpdatePC(currentList->pc, stackEntry.pc); + currentList->pc = stackEntry.pc; + DEBUG_LOG(G3D, "Signal with Return. signal/end: %04x %04x", signal, enddata); + } + } + break; + default: + ERROR_LOG_REPORT(G3D, "UNKNOWN Signal UNIMPLEMENTED %i ! signal/end: %04x %04x", behaviour, signal, enddata); + break; + } + // TODO: Technically, jump/call/ret should generate an interrupt, but before the pc change maybe? + if (currentList->interruptsEnabled && trigger) { + if (__GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { + currentList->pendingInterrupt = true; + UpdateState(GPUSTATE_INTERRUPT); + } + } + } + break; + case GE_CMD_FINISH: + switch (currentList->signal) { + case PSP_GE_SIGNAL_HANDLER_PAUSE: + currentList->state = PSP_GE_DL_STATE_PAUSED; + if (currentList->interruptsEnabled) { + if (__GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { + currentList->pendingInterrupt = true; + UpdateState(GPUSTATE_INTERRUPT); + } + } + break; + + case PSP_GE_SIGNAL_SYNC: + currentList->signal = PSP_GE_SIGNAL_NONE; + // TODO: Technically this should still cause an interrupt. Probably for memory sync. + break; + + default: + currentList->subIntrToken = prev & 0xFFFF; + UpdateState(GPUSTATE_DONE); + if (currentList->interruptsEnabled && __GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { + currentList->pendingInterrupt = true; + } else { + currentList->state = PSP_GE_DL_STATE_COMPLETED; + currentList->waitTicks = startingTicks + cyclesExecuted; + busyTicks = std::max(busyTicks, currentList->waitTicks); + __GeTriggerSync(GPU_SYNC_LIST, currentList->id, currentList->waitTicks); + if (currentList->started && currentList->context.IsValid()) { + gstate.Restore(currentList->context); + ReapplyGfxStateInternal(); + } + } + break; + } + break; + default: + DEBUG_LOG(G3D,"Ah, not finished: %06x", prev & 0xFFFFFF); + break; + } +} + void GPUCommon::ExecuteOp(u32 op, u32 diff) { - u32 cmd = op >> 24; - u32 data = op & 0xFFFFFF; + const u32 cmd = op >> 24; // Handle control and drawing commands here directly. The others we delegate. switch (cmd) { @@ -693,94 +933,27 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) { break; case GE_CMD_OFFSETADDR: - gstate_c.offsetAddr = data << 8; + Execute_OffsetAddr(op, diff); break; case GE_CMD_ORIGIN: - { - easy_guard guard(listLock); - gstate_c.offsetAddr = currentList->pc; - } + Execute_Origin(op, diff); break; case GE_CMD_JUMP: - { - easy_guard guard(listLock); - u32 target = gstate_c.getRelativeAddress(data); - if (Memory::IsValidAddress(target)) { - UpdatePC(currentList->pc, target - 4); - currentList->pc = target - 4; // pc will be increased after we return, counteract that - } else { - ERROR_LOG_REPORT(G3D, "JUMP to illegal address %08x - ignoring! data=%06x", target, data); - } - } + Execute_Jump(op, diff); break; case GE_CMD_BJUMP: - if (!currentList->bboxResult) { - // bounding box jump. - easy_guard guard(listLock); - u32 target = gstate_c.getRelativeAddress(data); - if (Memory::IsValidAddress(target)) { - UpdatePC(currentList->pc, target - 4); - currentList->pc = target - 4; // pc will be increased after we return, counteract that - } else { - ERROR_LOG_REPORT(G3D, "BJUMP to illegal address %08x - ignoring! data=%06x", target, data); - } - } + Execute_BJump(op, diff); break; case GE_CMD_CALL: - { - easy_guard guard(listLock); - - // Saint Seiya needs correct support for relative calls. - u32 retval = currentList->pc + 4; - u32 target = gstate_c.getRelativeAddress(data); - - // Bone matrix optimization - many games will CALL a bone matrix (!). - if ((Memory::ReadUnchecked_U32(target) >> 24) == GE_CMD_BONEMATRIXDATA) { - // Check for the end - if ((Memory::ReadUnchecked_U32(target + 11 * 4) >> 24) == GE_CMD_BONEMATRIXDATA && - (Memory::ReadUnchecked_U32(target + 12 * 4) >> 24) == GE_CMD_RET) { - // Yep, pretty sure this is a bone matrix call. - FastLoadBoneMatrix(target); - break; - } - } - - if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { - ERROR_LOG_REPORT(G3D, "CALL: Stack full!"); - } else if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "CALL to illegal address %08x - ignoring! data=%06x", target, data); - } else { - auto &stackEntry = currentList->stack[currentList->stackptr++]; - stackEntry.pc = retval; - stackEntry.offsetAddr = gstate_c.offsetAddr; - // The base address is NOT saved/restored for a regular call. - UpdatePC(currentList->pc, target - 4); - currentList->pc = target - 4; // pc will be increased after we return, counteract that - } - } + Execute_Call(op, diff); break; case GE_CMD_RET: - { - easy_guard guard(listLock); - if (currentList->stackptr == 0) { - DEBUG_LOG_REPORT(G3D, "RET: Stack empty!"); - } else { - auto &stackEntry = currentList->stack[--currentList->stackptr]; - gstate_c.offsetAddr = stackEntry.offsetAddr; - u32 target = (currentList->pc & 0xF0000000) | (stackEntry.pc & 0x0FFFFFFF); - UpdatePC(currentList->pc, target - 4); - currentList->pc = target - 4; - if (!Memory::IsValidAddress(currentList->pc)) { - ERROR_LOG_REPORT(G3D, "Invalid DL PC %08x on return", currentList->pc); - UpdateState(GPUSTATE_ERROR); - } - } - } + Execute_Ret(op, diff); break; case GE_CMD_SIGNAL: @@ -788,160 +961,9 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) { // Processed in GE_END. break; - case GE_CMD_END: { - easy_guard guard(listLock); - u32 prev = Memory::ReadUnchecked_U32(currentList->pc - 4); - UpdatePC(currentList->pc); - switch (prev >> 24) { - case GE_CMD_SIGNAL: - { - // TODO: see http://code.google.com/p/jpcsp/source/detail?r=2935# - SignalBehavior behaviour = static_cast((prev >> 16) & 0xFF); - int signal = prev & 0xFFFF; - int enddata = data & 0xFFFF; - bool trigger = true; - currentList->subIntrToken = signal; - - switch (behaviour) { - case PSP_GE_SIGNAL_HANDLER_SUSPEND: - // Suspend the list, and call the signal handler. When it's done, resume. - // Before sdkver 0x02000010, listsync should return paused. - if (sceKernelGetCompiledSdkVersion() <= 0x02000010) - currentList->state = PSP_GE_DL_STATE_PAUSED; - currentList->signal = behaviour; - DEBUG_LOG(G3D, "Signal with wait. signal/end: %04x %04x", signal, enddata); - break; - case PSP_GE_SIGNAL_HANDLER_CONTINUE: - // Resume the list right away, then call the handler. - currentList->signal = behaviour; - DEBUG_LOG(G3D, "Signal without wait. signal/end: %04x %04x", signal, enddata); - break; - case PSP_GE_SIGNAL_HANDLER_PAUSE: - // Pause the list instead of ending at the next FINISH. - // Call the handler with the PAUSE signal value at that FINISH. - // Technically, this ought to trigger an interrupt, but it won't do anything. - // But right now, signal is always reset by interrupts, so that causes pause to not work. - trigger = false; - currentList->signal = behaviour; - DEBUG_LOG(G3D, "Signal with Pause. signal/end: %04x %04x", signal, enddata); - break; - case PSP_GE_SIGNAL_SYNC: - // Acts as a memory barrier, never calls any user code. - // Technically, this ought to trigger an interrupt, but it won't do anything. - // Triggering here can cause incorrect rescheduling, which breaks 3rd Birthday. - // However, this is likely a bug in how GE signal interrupts are handled. - trigger = false; - currentList->signal = behaviour; - DEBUG_LOG(G3D, "Signal with Sync. signal/end: %04x %04x", signal, enddata); - break; - case PSP_GE_SIGNAL_JUMP: - { - trigger = false; - currentList->signal = behaviour; - // pc will be increased after we return, counteract that. - u32 target = ((signal << 16) | enddata) - 4; - if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "Signal with Jump: bad address. signal/end: %04x %04x", signal, enddata); - } else { - UpdatePC(currentList->pc, target); - currentList->pc = target; - DEBUG_LOG(G3D, "Signal with Jump. signal/end: %04x %04x", signal, enddata); - } - } - break; - case PSP_GE_SIGNAL_CALL: - { - trigger = false; - currentList->signal = behaviour; - // pc will be increased after we return, counteract that. - u32 target = ((signal << 16) | enddata) - 4; - if (currentList->stackptr == ARRAY_SIZE(currentList->stack)) { - ERROR_LOG_REPORT(G3D, "Signal with Call: stack full. signal/end: %04x %04x", signal, enddata); - } else if (!Memory::IsValidAddress(target)) { - ERROR_LOG_REPORT(G3D, "Signal with Call: bad address. signal/end: %04x %04x", signal, enddata); - } else { - // TODO: This might save/restore other state... - auto &stackEntry = currentList->stack[currentList->stackptr++]; - stackEntry.pc = currentList->pc; - stackEntry.offsetAddr = gstate_c.offsetAddr; - stackEntry.baseAddr = gstate.base; - UpdatePC(currentList->pc, target); - currentList->pc = target; - DEBUG_LOG(G3D, "Signal with Call. signal/end: %04x %04x", signal, enddata); - } - } - break; - case PSP_GE_SIGNAL_RET: - { - trigger = false; - currentList->signal = behaviour; - if (currentList->stackptr == 0) { - ERROR_LOG_REPORT(G3D, "Signal with Return: stack empty. signal/end: %04x %04x", signal, enddata); - } else { - // TODO: This might save/restore other state... - auto &stackEntry = currentList->stack[--currentList->stackptr]; - gstate_c.offsetAddr = stackEntry.offsetAddr; - gstate.base = stackEntry.baseAddr; - UpdatePC(currentList->pc, stackEntry.pc); - currentList->pc = stackEntry.pc; - DEBUG_LOG(G3D, "Signal with Return. signal/end: %04x %04x", signal, enddata); - } - } - break; - default: - ERROR_LOG_REPORT(G3D, "UNKNOWN Signal UNIMPLEMENTED %i ! signal/end: %04x %04x", behaviour, signal, enddata); - break; - } - // TODO: Technically, jump/call/ret should generate an interrupt, but before the pc change maybe? - if (currentList->interruptsEnabled && trigger) { - if (__GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { - currentList->pendingInterrupt = true; - UpdateState(GPUSTATE_INTERRUPT); - } - } - } - break; - case GE_CMD_FINISH: - switch (currentList->signal) { - case PSP_GE_SIGNAL_HANDLER_PAUSE: - currentList->state = PSP_GE_DL_STATE_PAUSED; - if (currentList->interruptsEnabled) { - if (__GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { - currentList->pendingInterrupt = true; - UpdateState(GPUSTATE_INTERRUPT); - } - } - break; - - case PSP_GE_SIGNAL_SYNC: - currentList->signal = PSP_GE_SIGNAL_NONE; - // TODO: Technically this should still cause an interrupt. Probably for memory sync. - break; - - default: - currentList->subIntrToken = prev & 0xFFFF; - UpdateState(GPUSTATE_DONE); - if (currentList->interruptsEnabled && __GeTriggerInterrupt(currentList->id, currentList->pc, startingTicks + cyclesExecuted)) { - currentList->pendingInterrupt = true; - } else { - currentList->state = PSP_GE_DL_STATE_COMPLETED; - currentList->waitTicks = startingTicks + cyclesExecuted; - busyTicks = std::max(busyTicks, currentList->waitTicks); - __GeTriggerSync(GPU_SYNC_LIST, currentList->id, currentList->waitTicks); - if (currentList->started && currentList->context.IsValid()) { - gstate.Restore(currentList->context); - ReapplyGfxStateInternal(); - } - } - break; - } - break; - default: - DEBUG_LOG(G3D,"Ah, not finished: %06x", prev & 0xFFFFFF); - break; - } + case GE_CMD_END: + Execute_End(op, diff); break; - } default: DEBUG_LOG(G3D,"DL Unknown: %08x @ %08x", op, currentList == NULL ? 0 : currentList->pc); diff --git a/GPU/GPUCommon.h b/GPU/GPUCommon.h index c25e98e8db..ec6c43c2a7 100644 --- a/GPU/GPUCommon.h +++ b/GPU/GPUCommon.h @@ -52,6 +52,14 @@ public: virtual u32 Break(int mode); virtual void ReapplyGfxState(); + void Execute_OffsetAddr(u32 op, u32 diff); + void Execute_Origin(u32 op, u32 diff); + void Execute_Jump(u32 op, u32 diff); + void Execute_BJump(u32 op, u32 diff); + void Execute_Call(u32 op, u32 diff); + void Execute_Ret(u32 op, u32 diff); + void Execute_End(u32 op, u32 diff); + virtual u64 GetTickEstimate() { #if defined(_M_X64) || defined(ANDROID) return curTickEst_;