Move the pc-management cmds to GPUCommon.

This commit is contained in:
Unknown W. Brackets 2013-03-31 23:02:46 -07:00
parent 417ce893dc
commit 0f15a5eae6
6 changed files with 145 additions and 222 deletions

View File

@ -164,8 +164,7 @@ static const u8 flushBeforeCommandList[] = {
};
GLES_GPU::GLES_GPU()
: interruptsEnabled_(true),
resized_(false)
: resized_(false)
{
shaderManager_ = new ShaderManager();
transformDraw_.SetShaderManager(shaderManager_);
@ -386,121 +385,6 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
}
break;
case GE_CMD_JUMP:
{
u32 target = gstate_c.getRelativeAddress(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! 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_c.getRelativeAddress(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! data=%06x", target, data);
} else {
stack[stackptr++] = retval;
currentList->pc = target - 4; // pc will be increased after we return, counteract that
}
}
break;
case GE_CMD_RET:
{
if (stackptr == 0) {
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);
finished = true;
}
}
}
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.
currentList->subIntrToken = data & 0xFFFF;
}
break;
case GE_CMD_FINISH:
currentList->subIntrToken = data & 0xFFFF;
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
break;
case GE_CMD_END:
switch (prev >> 24) {
case GE_CMD_SIGNAL:
{
currentList->status = PSP_GE_LIST_END_REACHED;
// TODO: see http://code.google.com/p/jpcsp/source/detail?r=2935#
int behaviour = (prev >> 16) & 0xFF;
int signal = prev & 0xFFFF;
int enddata = data & 0xFFFF;
// We should probably defer to sceGe here, no sense in implementing this stuff in every GPU
switch (behaviour) {
case 1: // Signal with Wait
ERROR_LOG(G3D, "Signal with Wait UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 2:
ERROR_LOG(G3D, "Signal without wait. signal/end: %04x %04x", signal, enddata);
break;
case 3:
ERROR_LOG(G3D, "Signal with Pause UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x10:
ERROR_LOG(G3D, "Signal with Jump UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x11:
ERROR_LOG(G3D, "Signal with Call UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x12:
ERROR_LOG(G3D, "Signal with Return UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
default:
ERROR_LOG(G3D, "UNKNOWN Signal UNIMPLEMENTED %i ! signal/end: %04x %04x", behaviour, signal, enddata);
break;
}
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
}
break;
case GE_CMD_FINISH:
currentList->status = PSP_GE_LIST_DONE;
finished = true;
break;
default:
DEBUG_LOG(G3D,"Ah, not finished: %06x", prev & 0xFFFFFF);
break;
}
break;
case GE_CMD_BJUMP:
// bounding box jump. Let's just not jump, for now.
break;
@ -974,7 +858,7 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
break;
default:
DEBUG_LOG(G3D,"DL Unknown: %08x @ %08x", op, currentList == NULL ? 0 : currentList->pc);
GPUCommon::ExecuteOp(op, diff);
break;
}
}

View File

@ -41,9 +41,6 @@ public:
virtual void DrawSync(int mode);
virtual void Continue();
virtual void Break();
virtual void EnableInterrupts(bool enable) {
interruptsEnabled_ = enable;
}
virtual void SetDisplayFramebuffer(u32 framebuf, u32 stride, int format);
virtual void CopyDisplayToOutput();
@ -81,6 +78,5 @@ private:
ShaderManager *shaderManager_;
u8 *flushBeforeCommand_;
bool interruptsEnabled_;
bool resized_;
};

View File

@ -1,12 +1,13 @@
#include "base/timeutil.h"
#include "../Core/MemMap.h"
#include "GeDisasm.h"
#include "GPUCommon.h"
#include "GPUState.h"
#include "ChunkFile.h"
#if defined(USING_QT_UI)
#include "Core/MemMap.h"
#include "Core/Host.h"
#endif
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceGe.h"
static int dlIdGenerator = 1;
@ -147,6 +148,135 @@ void GPUCommon::PreExecuteOp(u32 op, u32 diff) {
// Nothing to do
}
void GPUCommon::ExecuteOp(u32 op, u32 diff) {
u32 cmd = op >> 24;
u32 data = op & 0xFFFFFF;
// Handle control and drawing commands here directly. The others we delegate.
switch (cmd) {
case GE_CMD_NOP:
break;
case GE_CMD_OFFSETADDR:
gstate_c.offsetAddr = data << 8;
// ???
break;
case GE_CMD_ORIGIN:
gstate_c.offsetAddr = currentList->pc;
break;
case GE_CMD_JUMP:
{
u32 target = gstate_c.getRelativeAddress(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! 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_c.getRelativeAddress(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! data=%06x", target, data);
} else {
stack[stackptr++] = retval;
currentList->pc = target - 4; // pc will be increased after we return, counteract that
}
}
break;
case GE_CMD_RET:
{
if (stackptr == 0) {
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);
finished = true;
}
}
}
break;
case GE_CMD_SIGNAL:
{
// Processed in GE_END. Has data.
currentList->subIntrToken = data & 0xFFFF;
}
break;
case GE_CMD_FINISH:
currentList->subIntrToken = data & 0xFFFF;
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
break;
case GE_CMD_END:
switch (prev >> 24) {
case GE_CMD_SIGNAL:
{
currentList->status = PSP_GE_LIST_END_REACHED;
// TODO: see http://code.google.com/p/jpcsp/source/detail?r=2935#
int behaviour = (prev >> 16) & 0xFF;
int signal = prev & 0xFFFF;
int enddata = data & 0xFFFF;
// We should probably defer to sceGe here, no sense in implementing this stuff in every GPU
switch (behaviour) {
case 1: // Signal with Wait
ERROR_LOG(G3D, "Signal with Wait UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 2:
ERROR_LOG(G3D, "Signal without wait. signal/end: %04x %04x", signal, enddata);
break;
case 3:
ERROR_LOG(G3D, "Signal with Pause UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x10:
ERROR_LOG(G3D, "Signal with Jump UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x11:
ERROR_LOG(G3D, "Signal with Call UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
case 0x12:
ERROR_LOG(G3D, "Signal with Return UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
break;
default:
ERROR_LOG(G3D, "UNKNOWN Signal UNIMPLEMENTED %i ! signal/end: %04x %04x", behaviour, signal, enddata);
break;
}
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
}
break;
case GE_CMD_FINISH:
currentList->status = PSP_GE_LIST_DONE;
finished = true;
break;
default:
DEBUG_LOG(G3D,"Ah, not finished: %06x", prev & 0xFFFFFF);
break;
}
break;
default:
DEBUG_LOG(G3D,"DL Unknown: %08x @ %08x", op, currentList == NULL ? 0 : currentList->pc);
break;
}
}
void GPUCommon::DoState(PointerWrap &p) {
p.Do(dlIdGenerator);
p.Do<DisplayList>(dlQueue);

View File

@ -10,12 +10,17 @@ public:
currentList(NULL),
stackptr(0),
dumpNextFrame_(false),
dumpThisFrame_(false)
dumpThisFrame_(false),
interruptsEnabled_(true)
{}
virtual void InterruptStart();
virtual void InterruptEnd();
virtual void EnableInterrupts(bool enable) {
interruptsEnabled_ = enable;
}
virtual void ExecuteOp(u32 op, u32 diff);
virtual void PreExecuteOp(u32 op, u32 diff);
virtual bool InterpretList(DisplayList &list);
virtual bool ProcessDLQueue();
@ -40,7 +45,7 @@ protected:
bool dumpNextFrame_;
bool dumpThisFrame_;
bool interruptsEnabled_;
public:
virtual DisplayList* getList(int listid)

View File

@ -15,4 +15,6 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/CommonTypes.h"
void GeDisassembleOp(u32 pc, u32 op, u32 prev, char *buffer);

View File

@ -104,60 +104,6 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
}
break;
case GE_CMD_JUMP:
{
u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0x0FFFFFFF;
DEBUG_LOG(G3D,"DL CMD JUMP - %08x to %08x", currentList->pc, target);
currentList->pc = target - 4; // pc will be increased after we return, counteract that
if (!Memory::IsValidAddress(currentList->pc))
{
ERROR_LOG(G3D, "Invalid DL PC %08x on jump", currentList->pc);
finished = true;
}
}
break;
case GE_CMD_CALL:
{
u32 retval = currentList->pc + 4;
stack[stackptr++] = retval;
u32 target = (((gstate.base & 0x00FF0000) << 8) | (op & 0xFFFFFC)) & 0xFFFFFFF;
DEBUG_LOG(G3D,"DL CMD CALL - %08x to %08x, ret=%08x", currentList->pc, target, retval);
currentList->pc = target - 4; // pc will be increased after we return, counteract that
if (!Memory::IsValidAddress(currentList->pc))
{
ERROR_LOG(G3D, "Invalid DL PC %08x on call", currentList->pc);
finished = true;
}
}
break;
case GE_CMD_RET:
//TODO : debug!
{
u32 target = stack[--stackptr] & 0xFFFFFFF;
DEBUG_LOG(G3D,"DL CMD RET - from %08x to %08x", currentList->pc, target);
currentList->pc = target - 4;
if (!Memory::IsValidAddress(currentList->pc))
{
ERROR_LOG(G3D, "Invalid DL PC %08x on return", currentList->pc);
finished = true;
}
}
break;
case GE_CMD_SIGNAL:
{
ERROR_LOG(G3D, "DL GE_CMD_SIGNAL %08x", data & 0xFFFFFF);
int behaviour = (data >> 16) & 0xFF;
currentList->subIntrToken = data & 0xFFFF;
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
}
break;
case GE_CMD_BJUMP:
// bounding box jump. Let's just not jump, for now.
DEBUG_LOG(G3D,"DL BBOX JUMP - unimplemented");
@ -168,49 +114,11 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
DEBUG_LOG(G3D,"DL BBOX TEST - unimplemented");
break;
case GE_CMD_ORIGIN:
gstate.offsetAddr = currentList->pc & 0xFFFFFF;
gstate_c.offsetAddr = currentList->pc;
break;
case GE_CMD_VERTEXTYPE:
DEBUG_LOG(G3D,"DL SetVertexType: %06x", data);
// This sets through-mode or not, as well.
break;
case GE_CMD_OFFSETADDR:
// offsetAddr = data<<8;
break;
case GE_CMD_FINISH:
DEBUG_LOG(G3D,"DL CMD FINISH");
currentList->subIntrToken = data & 0xFFFF;
// TODO: Should this run while interrupts are suspended?
if (interruptsEnabled_)
__GeTriggerInterrupt(currentList->id, currentList->pc, currentList->subIntrBase, currentList->subIntrToken);
break;
case GE_CMD_END:
DEBUG_LOG(G3D,"DL CMD END");
{
switch (prev >> 24)
{
case GE_CMD_FINISH:
finished = true;
break;
default:
DEBUG_LOG(G3D,"Ah, not finished: %06x", prev & 0xFFFFFF);
break;
}
}
// This should generate a Reading Ended interrupt
// if (interruptsEnabled_)
// __TriggerInterrupt(PSP_GE_INTR);
break;
case GE_CMD_REGION1:
{
int x1 = data & 0x3ff;
@ -744,10 +652,8 @@ void NullGPU::ExecuteOp(u32 op, u32 diff)
break;
default:
DEBUG_LOG(G3D,"DL Unknown: %08x @ %08x", op, currentList->pc);
GPUCommon::ExecuteOp(op, diff);
break;
//ETC...
}
}