From 828523165faa3bb1a60fd05ffb06ae9221eadfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 2 Nov 2024 23:03:48 +0100 Subject: [PATCH] Rework the step functions. --- Core/Core.cpp | 25 ++++++++++++++----------- Windows/Debugger/Debugger_Disasm.cpp | 14 +++++++++++--- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index b2d34b6b01..dbb66d51ae 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -55,7 +55,7 @@ static std::condition_variable m_StepCond; static std::mutex m_hStepMutex; static std::condition_variable m_InactiveCond; static std::mutex m_hInactiveMutex; -static bool singleStepPending = false; +static int g_singleStepsPending = 0; static int steppingCounter = 0; static const char *steppingReason = ""; static uint32_t steppingAddress = 0; @@ -229,7 +229,7 @@ void Core_RunLoop(GraphicsContext *ctx) { void Core_DoSingleStep() { std::lock_guard guard(m_hStepMutex); - singleStepPending = true; + g_singleStepsPending++; m_StepCond.notify_all(); } @@ -250,7 +250,7 @@ u32 Core_PerformStep(DebugInterface *cpu, CPUStepType stepType, int stepSize) { for (int i = 0; i < (newAddress - currentPc) / 4; i++) { Core_DoSingleStep(); } - return newAddress; + return cpu->GetPC(); } case CPUStepType::Over: { @@ -316,17 +316,17 @@ u32 Core_PerformStep(DebugInterface *cpu, CPUStepType stepType, int stepSize) { } } -static inline bool Core_WaitStepping() { +static inline int Core_WaitStepping() { std::unique_lock guard(m_hStepMutex); // We only wait 16ms so that we can still draw UI or react to events. double sleepStart = time_now_d(); - if (!singleStepPending && coreState == CORE_STEPPING) + if (!g_singleStepsPending && coreState == CORE_STEPPING) m_StepCond.wait_for(guard, std::chrono::milliseconds(16)); double sleepEnd = time_now_d(); DisplayNotifySleep(sleepEnd - sleepStart); - bool result = singleStepPending; - singleStepPending = false; + int result = g_singleStepsPending; + g_singleStepsPending = 0; return result; } @@ -352,13 +352,16 @@ void Core_ProcessStepping() { } // Need to check inside the lock to avoid races. - bool doStep = Core_WaitStepping(); + int doSteps = Core_WaitStepping(); // We may still be stepping without singleStepPending to process a save state. - if (doStep && coreState == CORE_STEPPING) { + if (doSteps && coreState == CORE_STEPPING) { Core_ResetException(); - currentMIPS->SingleStep(); - steppingCounter++; + + for (int i = 0; i < doSteps; i++) { + currentMIPS->SingleStep(); + steppingCounter++; + } // Update disasm dialog. System_Notify(SystemNotification::DISASSEMBLY); diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index e7d75fcfa8..8bc1aed8e9 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -208,11 +208,19 @@ void CDisasm::step(CPUStepType stepType) ptr->setDontRedraw(true); lastTicks_ = CoreTiming::GetTicks(); - u32 stepSize = ptr->getInstructionSizeAt(cpu->GetPC()); - u32 newAddress = Core_PerformStep(cpu, stepType, stepSize); + u32 oldAddress = cpu->GetPC(); + u32 stepSize = ptr->getInstructionSizeAt(oldAddress); + Core_PerformStep(cpu, stepType, stepSize); Sleep(1); - ptr->scrollStepping(newAddress); + // At this point, the step should be done, and the new address is just PC. + // Ideally, this part should be done as a reaction to an update message and not directly here. + // That way we could get rid of the sleep. + u32 newAddress = cpu->GetPC(); + if (newAddress > oldAddress && newAddress < oldAddress + 12) { + // Heuristic for when to scroll at the edge rather than jump the window. + ptr->scrollStepping(newAddress); + } ptr->gotoAddr(newAddress); UpdateDialog(); }