mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Merge pull request #4369 from unknownbrackets/deadbeef
Fill regs with 0xDEADBEEF after syscalls...
This commit is contained in:
commit
590ad5c6df
@ -286,6 +286,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
|
||||
debugConfig->Get("DisplayStatusBar", &bDisplayStatusBar, true);
|
||||
debugConfig->Get("ShowBottomTabTitles",&bShowBottomTabTitles,true);
|
||||
debugConfig->Get("ShowDeveloperMenu", &bShowDeveloperMenu, false);
|
||||
debugConfig->Get("SkipDeadbeefFilling", &bSkipDeadbeefFilling, false);
|
||||
|
||||
IniFile::Section *speedhacks = iniFile.GetOrCreateSection("SpeedHacks");
|
||||
speedhacks->Get("PrescaleUV", &bPrescaleUV, false);
|
||||
@ -482,6 +483,7 @@ void Config::Save() {
|
||||
debugConfig->Set("DisplayStatusBar", bDisplayStatusBar);
|
||||
debugConfig->Set("ShowBottomTabTitles",bShowBottomTabTitles);
|
||||
debugConfig->Set("ShowDeveloperMenu", bShowDeveloperMenu);
|
||||
debugConfig->Set("SkipDeadbeefFilling", bSkipDeadbeefFilling);
|
||||
|
||||
IniFile::Section *speedhacks = iniFile.GetOrCreateSection("SpeedHacks");
|
||||
speedhacks->Set("PrescaleUV", bPrescaleUV);
|
||||
|
@ -216,6 +216,8 @@ public:
|
||||
bool bDisplayStatusBar;
|
||||
bool bShowBottomTabTitles;
|
||||
bool bShowDeveloperMenu;
|
||||
// Double edged sword: much easier debugging, but not accurate.
|
||||
bool bSkipDeadbeefFilling;
|
||||
|
||||
std::string currentDirectory;
|
||||
std::string externalDirectory;
|
||||
|
@ -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,28 @@ 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()
|
||||
{
|
||||
if (g_Config.bSkipDeadbeefFilling)
|
||||
return;
|
||||
|
||||
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 +476,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.
|
||||
@ -1892,9 +1895,10 @@ void ThreadContext::reset()
|
||||
{
|
||||
for (int i = 0; i<32; i++)
|
||||
{
|
||||
r[i] = 0;
|
||||
f[i] = 0.0f;
|
||||
r[i] = 0xDEADBEEF;
|
||||
fi[i] = 0x7f800001;
|
||||
}
|
||||
r[0] = 0;
|
||||
for (int i = 0; i<128; i++)
|
||||
{
|
||||
v[i] = 0.0f;
|
||||
@ -1919,15 +1923,13 @@ void ThreadContext::reset()
|
||||
fpcond = 0;
|
||||
fcr0 = 0;
|
||||
fcr31 = 0;
|
||||
hi = 0;
|
||||
lo = 0;
|
||||
hi = 0xDEADBEEF;
|
||||
lo = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
void __KernelResetThread(Thread *t, int lowestPriority)
|
||||
{
|
||||
t->context.reset();
|
||||
t->context.hi = 0;
|
||||
t->context.lo = 0;
|
||||
t->context.pc = t->nt.entrypoint;
|
||||
|
||||
// If the thread would be better than lowestPriority, reset to its initial. Yes, kinda odd...
|
||||
@ -2207,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.");
|
||||
@ -3002,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)
|
||||
{
|
||||
@ -3270,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) {
|
||||
@ -3377,6 +3385,8 @@ void __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
|
||||
|
||||
void __KernelReturnFromMipsCall()
|
||||
{
|
||||
hleSkipDeadbeef();
|
||||
|
||||
Thread *cur = __GetCurrentThread();
|
||||
if (cur == NULL)
|
||||
{
|
||||
|
@ -114,9 +114,15 @@ struct ThreadContext
|
||||
|
||||
// r must be followed by f.
|
||||
u32 r[32];
|
||||
float f[32];
|
||||
|
||||
float v[128];
|
||||
union {
|
||||
float f[32];
|
||||
u32 fi[32];
|
||||
int fs[32];
|
||||
};
|
||||
union {
|
||||
float v[128];
|
||||
u32 vi[128];
|
||||
};
|
||||
u32 vfpuCtrl[16];
|
||||
|
||||
union {
|
||||
|
Loading…
Reference in New Issue
Block a user