mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Fill registers with 0xDEADBEEF after most syscalls.
Some, like sceMpegRingbufferPut(), we don't, since... it's complicated. But most we do, like a real PSP does.
This commit is contained in:
parent
04ec987448
commit
9ebaf7b68b
5 changed files with 43 additions and 0 deletions
|
@ -52,6 +52,8 @@ enum
|
|||
HLE_AFTER_RUN_INTERRUPTS = 0x10,
|
||||
// Switch to CORE_STEPPING after the syscall (for debugging.)
|
||||
HLE_AFTER_DEBUG_BREAK = 0x20,
|
||||
// Don't fill temp regs with 0xDEADBEEF.
|
||||
HLE_AFTER_SKIP_DEADBEEF = 0x40,
|
||||
};
|
||||
|
||||
typedef std::vector<Syscall> SyscallVector;
|
||||
|
@ -287,6 +289,11 @@ void hleDebugBreak()
|
|||
hleAfterSyscall |= HLE_AFTER_DEBUG_BREAK;
|
||||
}
|
||||
|
||||
void hleSkipDeadbeef()
|
||||
{
|
||||
hleAfterSyscall |= HLE_AFTER_SKIP_DEADBEEF;
|
||||
}
|
||||
|
||||
// Pauses execution after an HLE call.
|
||||
bool hleExecuteDebugBreak(const HLEFunction &func)
|
||||
{
|
||||
|
@ -341,8 +348,26 @@ void hleEatMicro(int usec)
|
|||
hleEatCycles((int) usToCycles(usec));
|
||||
}
|
||||
|
||||
const static u32 deadbeefRegs[12] = {0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF, 0xDEADBEEF};
|
||||
inline static void SetDeadbeefRegs()
|
||||
{
|
||||
// TODO: Debug setting?
|
||||
currentMIPS->r[MIPS_REG_COMPILER_SCRATCH] = 0xDEADBEEF;
|
||||
// Set all the arguments and temp regs.
|
||||
memcpy(¤tMIPS->r[MIPS_REG_A0], deadbeefRegs, sizeof(deadbeefRegs));
|
||||
// Using a magic number since there's confusion/disagreement on reg names.
|
||||
currentMIPS->r[24] = 0xDEADBEEF;
|
||||
currentMIPS->r[25] = 0xDEADBEEF;
|
||||
|
||||
currentMIPS->lo = 0xDEADBEEF;
|
||||
currentMIPS->hi = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
inline void hleFinishSyscall(int modulenum, int funcnum)
|
||||
{
|
||||
if ((hleAfterSyscall & HLE_AFTER_SKIP_DEADBEEF) == 0)
|
||||
SetDeadbeefRegs();
|
||||
|
||||
if ((hleAfterSyscall & HLE_AFTER_CURRENT_CALLBACKS) != 0)
|
||||
__KernelForceCallbacks();
|
||||
|
||||
|
@ -449,6 +474,8 @@ void CallSyscall(MIPSOpcode op)
|
|||
|
||||
if (hleAfterSyscall != HLE_AFTER_NOTHING)
|
||||
hleFinishSyscall(modulenum, funcnum);
|
||||
else
|
||||
SetDeadbeefRegs();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -91,6 +91,8 @@ void hleReSchedule(bool callbacks, const char *reason);
|
|||
void hleRunInterrupts();
|
||||
// Pause emulation after the syscall finishes.
|
||||
void hleDebugBreak();
|
||||
// Don't set temp regs to 0xDEADBEEF.
|
||||
void hleSkipDeadbeef();
|
||||
|
||||
// Delays the result for usec microseconds, allowing other threads to run during this time.
|
||||
u32 hleDelayResult(u32 result, const char *reason, int usec);
|
||||
|
|
|
@ -405,6 +405,8 @@ void __KernelReturnFromInterrupt()
|
|||
{
|
||||
VERBOSE_LOG(SCEINTC, "Left interrupt handler at %08x", currentMIPS->pc);
|
||||
|
||||
hleSkipDeadbeef();
|
||||
|
||||
// This is what we just ran.
|
||||
PendingInterrupt pend = pendingInterrupts.front();
|
||||
pendingInterrupts.pop_front();
|
||||
|
|
|
@ -1601,6 +1601,7 @@ u32 sceKernelStopUnloadSelfModuleWithStatus(u32 exitCode, u32 argSize, u32 argp,
|
|||
void __KernelReturnFromModuleFunc()
|
||||
{
|
||||
// Return from the thread as normal.
|
||||
hleSkipDeadbeef();
|
||||
__KernelReturnFromThread();
|
||||
|
||||
SceUID leftModuleID = __KernelGetCurThreadModuleId();
|
||||
|
|
|
@ -1284,6 +1284,7 @@ bool __KernelSwitchOffThread(const char *reason)
|
|||
Thread *t = kernelObjects.GetFast<Thread>(threadIdleID[0]);
|
||||
if (t)
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
__KernelSwitchContext(t, reason);
|
||||
return true;
|
||||
}
|
||||
|
@ -1327,6 +1328,8 @@ bool __KernelSwitchToThread(SceUID threadID, const char *reason)
|
|||
|
||||
void __KernelIdle()
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
|
||||
CoreTiming::Idle();
|
||||
// Advance must happen between Idle and Reschedule, so that threads that were waiting for something
|
||||
// that was triggered at the end of the Idle period must get a chance to be scheduled.
|
||||
|
@ -2206,6 +2209,8 @@ int sceKernelGetThreadStackFreeSize(SceUID threadID)
|
|||
|
||||
void __KernelReturnFromThread()
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
|
||||
int exitStatus = currentMIPS->r[MIPS_REG_V0];
|
||||
Thread *thread = __GetCurrentThread();
|
||||
_dbg_assert_msg_(SCEKERNEL, thread != NULL, "Returned from a NULL thread.");
|
||||
|
@ -3001,11 +3006,14 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter)
|
|||
// Stack should stay aligned even though we saved only 3 regs.
|
||||
currentMIPS->r[MIPS_REG_SP] = thread->currentStack.end - 0x10;
|
||||
|
||||
hleSkipDeadbeef();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __KernelReturnFromExtendStack()
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
|
||||
Thread *thread = __GetCurrentThread();
|
||||
if (!thread)
|
||||
{
|
||||
|
@ -3269,6 +3277,7 @@ bool __CanExecuteCallbackNow(Thread *thread) {
|
|||
|
||||
void __KernelCallAddress(Thread *thread, u32 entryPoint, Action *afterAction, const u32 args[], int numargs, bool reschedAfter, SceUID cbId)
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
_dbg_assert_msg_(SCEKERNEL, numargs <= 6, "MipsCalls can only take 6 args.");
|
||||
|
||||
if (thread) {
|
||||
|
@ -3376,6 +3385,8 @@ void __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
|
|||
|
||||
void __KernelReturnFromMipsCall()
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
|
||||
Thread *cur = __GetCurrentThread();
|
||||
if (cur == NULL)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue