diff --git a/Core/Console.cpp b/Core/Console.cpp index 707267c3..a4ba43a9 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -349,6 +349,8 @@ void Console::Run() _runLock.Acquire(); _stopLock.Acquire(); + _emulationThreadId = std::this_thread::get_id(); + targetTime = GetFrameDelay(); VideoDecoder::GetInstance()->StartThread(); @@ -487,6 +489,8 @@ void Console::Run() _stopLock.Release(); _runLock.Release(); + _emulationThreadId = std::thread::id(); + MessageManager::SendNotification(ConsoleNotificationType::GameStopped); MessageManager::SendNotification(ConsoleNotificationType::EmulationStopped); } @@ -636,6 +640,11 @@ uint32_t Console::GetLagCounter() return Instance->_lagCounter; } +std::thread::id Console::GetEmulationThreadId() +{ + return Instance->_emulationThreadId; +} + void Console::ResetLagCounter() { Instance->_lagCounter = 0; diff --git a/Core/Console.h b/Core/Console.h index 7e8011a0..4d23276b 100644 --- a/Core/Console.h +++ b/Core/Console.h @@ -58,6 +58,7 @@ class Console atomic _lagCounter; bool _initialized = false; + std::thread::id _emulationThreadId; void LoadHdPack(VirtualFile &romFile, VirtualFile &patchFile); @@ -71,6 +72,9 @@ class Console ~Console(); void Run(); void Stop(); + + static std::thread::id GetEmulationThreadId(); + static void RequestReset(); static void Reset(bool softReset = true); static void PowerCycle(); diff --git a/Core/DebugBreakHelper.h b/Core/DebugBreakHelper.h index e4d69bfa..e2a10bcc 100644 --- a/Core/DebugBreakHelper.h +++ b/Core/DebugBreakHelper.h @@ -1,31 +1,40 @@ #pragma once #include "stdafx.h" #include "Debugger.h" +#include "Console.h" class DebugBreakHelper { private: Debugger* _debugger; bool _needResume = false; + bool _isEmulationThread = false; public: DebugBreakHelper(Debugger* debugger) { _debugger = debugger; - if(!debugger->IsExecutionStopped()) { - debugger->SetSendNotificationFlag(false); - debugger->Step(1); - while(!debugger->IsExecutionStopped()) {} - _needResume = true; + _isEmulationThread = Console::GetEmulationThreadId() == std::this_thread::get_id(); + + if(!_isEmulationThread) { + //Only attempt to break if this is done in a thread other than the main emulation thread + debugger->PreventResume(); + if(!debugger->IsExecutionStopped()) { + debugger->Step(1); + while(!debugger->IsExecutionStopped()) {} + _needResume = true; + } } } ~DebugBreakHelper() { - if(_needResume) { - _debugger->Run(); - _debugger->SetSendNotificationFlag(true); + if(!_isEmulationThread) { + if(_needResume) { + _debugger->Run(); + } + _debugger->AllowResume(); } } }; \ No newline at end of file diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index dcc20da4..633752e0 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -54,8 +54,8 @@ Debugger::Debugger(shared_ptr console, shared_ptr cpu, shared_ptr< _stepOverAddr = -1; _stepCycleCount = -1; _ppuStepCount = -1; - _sendNotification = true; + _preventResume = 0; _stopFlag = false; _suspendCount = 0; @@ -578,7 +578,7 @@ bool Debugger::SleepUntilResume() auto lock = _breakLock.AcquireSafe(); _executionStopped = true; - if(_sendNotification) { + if(_preventResume == 0) { SoundMixer::StopAudio(); MessageManager::SendNotification(ConsoleNotificationType::CodeBreak); ProcessEvent(EventType::CodeBreak); @@ -588,7 +588,7 @@ bool Debugger::SleepUntilResume() } } - while(stepCount == 0 && !_stopFlag && _suspendCount == 0) { + while((stepCount == 0 && !_stopFlag && _suspendCount == 0) || _preventResume > 0) { std::this_thread::sleep_for(std::chrono::duration(10)); stepCount = _stepCount.load(); } @@ -657,7 +657,7 @@ void Debugger::PpuStep(uint32_t count) _stepCount = -1; } -void Debugger::Step(uint32_t count, bool sendNotification) +void Debugger::Step(uint32_t count) { //Run CPU for [count] INSTRUCTIONS before breaking again _stepOut = false; @@ -703,11 +703,6 @@ void Debugger::StepBack() } } -void Debugger::SetSendNotificationFlag(bool enabled) -{ - _sendNotification = enabled; -} - void Debugger::Run() { //Resume execution after a breakpoint has been hit @@ -891,6 +886,16 @@ bool Debugger::IsExecutionStopped() return _executionStopped || _console->IsPaused(); } +void Debugger::PreventResume() +{ + _preventResume++; +} + +void Debugger::AllowResume() +{ + _preventResume--; +} + void Debugger::GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info) { if(relativeAddr < 0x2000) { @@ -1054,12 +1059,17 @@ int Debugger::LoadScript(string content, int32_t scriptId) _hasScript = true; return script->GetScriptId(); } else { - auto result = std::find_if(_scripts.begin(), _scripts.end(), [=](shared_ptr &script) { - return script->GetScriptId() == scriptId; - }); - if(result != _scripts.end()) { - (*result)->LoadScript(content, this); - return scriptId; + if(content.empty()) { + RemoveScript(scriptId); + return 0; + } else { + auto result = std::find_if(_scripts.begin(), _scripts.end(), [=](shared_ptr &script) { + return script->GetScriptId() == scriptId; + }); + if(result != _scripts.end()) { + (*result)->LoadScript(content, this); + return scriptId; + } } } diff --git a/Core/Debugger.h b/Core/Debugger.h index c549760a..e32682a5 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -65,6 +65,7 @@ private: bool _bpUpdateNeeded; SimpleLock _bpUpdateLock; + atomic _preventResume; atomic _stopFlag; atomic _executionStopped; atomic _suspendCount; @@ -102,7 +103,6 @@ private: atomic _lastInstruction; atomic _stepOut; atomic _stepOverAddr; - atomic _sendNotification; int32_t _ppuViewerScanline; int32_t _ppuViewerCycle; @@ -158,13 +158,12 @@ public: void Resume(); void PpuStep(uint32_t count = 1); - void Step(uint32_t count = 1, bool sendNotification = true); + void Step(uint32_t count = 1); void StepCycles(uint32_t cycleCount = 1); void StepOver(); void StepOut(); void StepBack(); void Run(); - void SetSendNotificationFlag(bool enabled); bool LoadCdlFile(string cdlFilepath); void ResetCdl(); @@ -177,6 +176,9 @@ public: bool IsExecutionStopped(); + void PreventResume(); + void AllowResume(); + void GenerateCodeOutput(); const char* GetCode(uint32_t &length); diff --git a/GUI.NET/Debugger/frmScript.cs b/GUI.NET/Debugger/frmScript.cs index faec7578..30245950 100644 --- a/GUI.NET/Debugger/frmScript.cs +++ b/GUI.NET/Debugger/frmScript.cs @@ -232,11 +232,13 @@ namespace Mesen.GUI.Debugger private void StopScript() { - _scriptId = InteropEmu.DebugLoadScript(string.Empty, _scriptId); - if(_scriptId < 0) { - MessageBox.Show("Error while stopping script."); - } else { - lblScriptActive.Visible = false; + if(_scriptId >= 0) { + if(InteropEmu.DebugLoadScript(string.Empty, _scriptId) == 0) { + lblScriptActive.Visible = false; + _scriptId = -1; + } else { + MessageBox.Show("Error while stopping script."); + } } }