mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-21 14:41:39 +00:00
Move the pc-management cmds to GPUCommon.
This commit is contained in:
parent
417ce893dc
commit
0f15a5eae6
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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...
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user