mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Utility: A savedata shutdown ends at priority 0x20
On hardware the last part of a savedata shutdown runs at priority 0x20, whatever the dialog's own thread priorities, so a caller at 0x20 gets the CPU back first and sees SHUTDOWN, and one at 0x21 or worse only sees NONE (pspautotests utility/savedata/shutdownstatus). We ended it at the access thread's priority, so Freak Out, which calls ShutdownStart from 0x20 and waits for SHUTDOWN, sat at 'Please press START' forever. NFL Street 3, which calls it from 111 and then InitStart straight away, still gets NONE. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
51bac9349e
commit
00c9a2d389
1 file changed
+13
-3
+13
-3
@@ -736,6 +736,11 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int accessPriori
|
||||
// The windows aren't this regular, but close.
|
||||
int partDelay = delayUs / 4;
|
||||
const int dialogPriority = PhasePriority(graphicsPriority, accessPriority);
|
||||
// A savedata shutdown ends at priority 0x20, whatever the dialog's thread priorities: a caller at
|
||||
// 0x20 gets the CPU back first and sees SHUTDOWN, one at 0x21 or worse only NONE
|
||||
// (pspautotests utility/savedata/shutdownstatus). Freak Out calls ShutdownStart from 0x20 and
|
||||
// waits for SHUTDOWN; NFL Street 3 calls it from 111 and then InitStart straight away.
|
||||
const int finalPriority = type == UtilityDialogType::SAVEDATA ? 0x20 : accessPriority;
|
||||
const u32_le insts[] = {
|
||||
// Make sure we don't discard/deadbeef 'em.
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_S0, MIPS_REG_A0, 0),
|
||||
@@ -749,7 +754,7 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int accessPriori
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_S0, 0),
|
||||
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
|
||||
|
||||
// Cleaning up at accessThread priority, then the status goes to NONE.
|
||||
// Cleaning up at accessThread priority.
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_ZERO, 0),
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A1, MIPS_REG_ZERO, accessPriority),
|
||||
(u32_le)MIPS_MAKE_SYSCALL("ThreadManForUser", "sceKernelChangeThreadPriority"),
|
||||
@@ -758,13 +763,18 @@ void UtilityDialogShutdown(UtilityDialogType type, int delayUs, int accessPriori
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_S0, 0),
|
||||
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityWorkUs"),
|
||||
|
||||
// Then the status goes to NONE, from priority finalPriority (see below).
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_ZERO, 0),
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A1, MIPS_REG_ZERO, finalPriority),
|
||||
(u32_le)MIPS_MAKE_SYSCALL("ThreadManForUser", "sceKernelChangeThreadPriority"),
|
||||
|
||||
(u32_le)MIPS_MAKE_ORI(MIPS_REG_A0, MIPS_REG_ZERO, (int)type),
|
||||
(u32_le)MIPS_MAKE_JR_RA(),
|
||||
(u32_le)MIPS_MAKE_SYSCALL("sceUtility", "__UtilityFinishDialog"),
|
||||
};
|
||||
|
||||
// Starting the thread reschedules normally, so a caller with worse priority than both phases sees
|
||||
// NONE by the time ShutdownStart returns.
|
||||
// Starting the thread reschedules normally, so a caller with worse priority than every phase
|
||||
// only runs again once the status is NONE.
|
||||
CleanupDialogThreads(true);
|
||||
accessThread = new HLEHelperThread("ScePafJob", insts, (uint32_t)ARRAY_SIZE(insts), accessPriority, 0x200);
|
||||
accessThread->Start(partDelay, 0);
|
||||
|
||||
Reference in new issue
Block a user