Skip to content

Commit

Permalink
Handle GE pause signals per tests.
Browse files Browse the repository at this point in the history
They really should pause, but we were resetting them incorrectly.
And most importantly, sceGeContinue() inside the signal handler absolutely
must work.  Games use this a lot.
  • Loading branch information
unknownbrackets committed Apr 12, 2014
1 parent 702294f commit 4561440
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 17 deletions.
4 changes: 1 addition & 3 deletions Core/HLE/sceGe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class GeIntrHandler : public IntrHandler
SubIntrHandler* handler = get(subintr);
if (handler != NULL)
{
DEBUG_LOG(CPU, "Entering interrupt handler %08x", handler->handlerAddress);
DEBUG_LOG(CPU, "Entering GE interrupt handler %08x", handler->handlerAddress);
currentMIPS->pc = handler->handlerAddress;
u32 data = dl->subIntrToken;
currentMIPS->r[MIPS_REG_A0] = data & 0xFFFF;
Expand Down Expand Up @@ -162,8 +162,6 @@ class GeIntrHandler : public IntrHandler
break;
}

dl->signal = PSP_GE_SIGNAL_NONE;

gpu->InterruptEnd(intrdata.listid);
}
};
Expand Down
21 changes: 7 additions & 14 deletions GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,6 @@ u32 GPUCommon::UpdateStall(int listid, u32 newstall) {
return SCE_KERNEL_ERROR_ALREADY;

dl.stall = newstall & 0x0FFFFFFF;

if (dl.signal == PSP_GE_SIGNAL_HANDLER_PAUSE)

This comment has been minimized.

Copy link
@xsacha

xsacha Jul 3, 2014

Collaborator

Removing these two lines causes Armored Core: Last Raven and Armored Core: Silent Line to freeze in several different spots.

This comment has been minimized.

Copy link
@unknownbrackets

unknownbrackets Jul 3, 2014

Author Collaborator

There's a test in pspautotests for pause signals. If I remember right, this was causing wrong signals to be sent (it should not call the FINISH handler on FINISH after a pause signal.)

-[Unknown]

This comment has been minimized.

Copy link
@xsacha

xsacha Jul 3, 2014

Collaborator

If not a suspend, maybe something else is meant to happen here.

Are you sure the test still fails with just these two lines reverted? Maybe the other changes fixed it. There's another if (signal == PAUSE) signal = SUSPEND further down too but it doesn't seem to affect this game.

This comment has been minimized.

Copy link
@unknownbrackets

unknownbrackets Jul 3, 2014

Author Collaborator

I'm not sure, I know there were other changes after this commit also.

-[Unknown]

This comment has been minimized.

Copy link
@xsacha

xsacha Jul 3, 2014

Collaborator

I'm not able to run the tests on Android or Linux:
E/NativeApp(25969): Failed to init unittest cpu/cpu_alu/cpu_alu : Could not find executable umd0://tests/cpu/cpu_alu/cpu_alu.prx

This comment has been minimized.

Copy link
@unknownbrackets

unknownbrackets Jul 3, 2014

Author Collaborator

This is "run cpu tests"? It expects them in /sdcard/pspautotests/tests/cpu/cpu_alu/cpu_alu.prx.

You can also compile headless (HEADLESS=1 on ab.sh iirc) and upload that, it has --help, just adb shell in and put the files in /data/local/tmp iirc (only place you can put executable files.)

-[Unknown]

This comment has been minimized.

Copy link
@xsacha

xsacha Jul 3, 2014

Collaborator

Yes. They are in the correct location (otherwise it is greyed out).

This comment has been minimized.

Copy link
@unknownbrackets

unknownbrackets Jul 3, 2014

Author Collaborator

Hmm, I have not used the UI one in a while, maybe it's broken...

-[Unknown]

dl.signal = PSP_GE_SIGNAL_HANDLER_SUSPEND;

guard.unlock();
ProcessDLQueue();
Expand All @@ -349,8 +346,8 @@ u32 GPUCommon::Continue() {
{
if (!isbreak)
{
if (currentList->signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
return 0x80000021;
// TODO: Supposedly this returns SCE_KERNEL_ERROR_BUSY in some case, previously it had
// currentList->signal == PSP_GE_SIGNAL_HANDLER_PAUSE, but it doesn't reproduce.

currentList->state = PSP_GE_DL_STATE_RUNNING;
currentList->signal = PSP_GE_SIGNAL_NONE;
Expand Down Expand Up @@ -457,9 +454,8 @@ bool GPUCommon::InterpretList(DisplayList &list) {

easy_guard guard(listLock);

// TODO: This has to be right... but it freezes right now?
//if (list.state == PSP_GE_DL_STATE_PAUSED)
// return false;
if (list.state == PSP_GE_DL_STATE_PAUSED)
return false;
currentList = &list;

if (!list.started && list.context.IsValid()) {
Expand Down Expand Up @@ -813,7 +809,7 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) {
if (sceKernelGetCompiledSdkVersion() <= 0x02000010)
currentList->state = PSP_GE_DL_STATE_PAUSED;
currentList->signal = behaviour;
DEBUG_LOG(G3D, "Signal with Wait UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
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.
Expand All @@ -826,9 +822,8 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) {
// 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->state = PSP_GE_DL_STATE_PAUSED;
currentList->signal = behaviour;
ERROR_LOG_REPORT(G3D, "Signal with Pause UNIMPLEMENTED! signal/end: %04x %04x", signal, enddata);
ERROR_LOG_REPORT(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.
Expand Down Expand Up @@ -909,6 +904,7 @@ void GPUCommon::ExecuteOp(u32 op, u32 diff) {
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;
Expand Down Expand Up @@ -1039,9 +1035,6 @@ void GPUCommon::InterruptEnd(int listid) {
__GeTriggerWait(GPU_SYNC_LIST, listid);
}

if (dl.signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
dl.signal = PSP_GE_SIGNAL_HANDLER_SUSPEND;

guard.unlock();
ProcessDLQueue();
}
Expand Down

0 comments on commit 4561440

Please sign in to comment.