#pragma once #include "pch.h" #include "Utilities/SimpleLock.h" #include "Debugger/DebugUtilities.h" #include "Debugger/DebugTypes.h" #include "Debugger/DebuggerFeatures.h" #include "Shared/SettingTypes.h" class IConsole; class Emulator; class SnesCpu; class SnesPpu; class Spc; class BaseCartridge; class SnesMemoryManager; class InternalRegisters; class SnesDmaController; class EmuSettings; class ExpressionEvaluator; class MemoryDumper; class MemoryAccessCounter; class Disassembler; class DisassemblySearch; class BreakpointManager; class PpuTools; class CodeDataLogger; class CallstackManager; class LabelManager; class CdlManager; class ScriptManager; class Breakpoint; class BaseEventManager; class IAssembler; class IDebugger; class ITraceLogger; class TraceLogFileSaver; class FrozenAddressManager; struct TraceRow; struct BaseState; enum class EventType; enum class MemoryOperationType; enum class EvalResultType : int32_t; struct CpuInfo { unique_ptr Debugger; unique_ptr Evaluator; }; class Debugger { private: Emulator* _emu = nullptr; IConsole* _console = nullptr; EmuSettings* _settings = nullptr; CpuInfo _debuggers[(int)DebugUtilities::GetLastCpuType() + 1]; CpuType _mainCpuType = CpuType::Snes; unordered_set _cpuTypes; ConsoleType _consoleType = ConsoleType::Snes; unique_ptr _scriptManager; unique_ptr _memoryDumper; unique_ptr _memoryAccessCounter; unique_ptr _codeDataLogger; unique_ptr _disassembler; unique_ptr _disassemblySearch; unique_ptr _labelManager; unique_ptr _cdlManager; unique_ptr _traceLogSaver; SimpleLock _logLock; std::list _debuggerLog; atomic _executionStopped; atomic _breakRequestCount; atomic _suspendRequestCount; DebugControllerState _inputOverrides[8] = {}; bool _waitForBreakResume = false; void Reset(); __noinline bool ProcessStepBack(IDebugger* debugger); template DebuggerType* GetDebugger(); template uint64_t GetCpuCycleCount(); template void ProcessScripts(uint32_t addr, T& value, MemoryOperationType opType); template void ProcessScripts(uint32_t addr, T& value, MemoryType memType, MemoryOperationType opType); bool IsDebugWindowOpened(CpuType cpuType); bool IsBreakOptionEnabled(BreakSource src); template void SleepOnBreakRequest(); void ClearPendingBreakExceptions(); bool IsBreakpointForbidden(BreakSource source, CpuType sourceCpu, MemoryOperationInfo* operation); public: Debugger(Emulator* emu, IConsole* console); ~Debugger(); void Release(); template void ProcessInstruction(); template void ProcessMemoryRead(uint32_t addr, T& value, MemoryOperationType opType); template bool ProcessMemoryWrite(uint32_t addr, T& value, MemoryOperationType opType); template void ProcessMemoryAccess(uint32_t addr, T& value); template void ProcessIdleCycle(); template void ProcessHaltedCpu(); template void ProcessPpuRead(uint16_t addr, T& value, MemoryType memoryType, MemoryOperationType opType); template void ProcessPpuWrite(uint16_t addr, T& value, MemoryType memoryType); template void ProcessPpuCycle(); template void ProcessInterrupt(uint32_t originalPc, uint32_t currentPc, bool forNmi); void InternalProcessInterrupt(CpuType cpuType, IDebugger& dbg, StepRequest& stepRequest, AddressInfo& src, uint32_t srcAddr, AddressInfo& dest, uint32_t destAddr, AddressInfo& ret, uint32_t retAddr, uint32_t retSp, bool forNmi); void ProcessEvent(EventType type, std::optional cpuType); void ProcessConfigChange(); void GetTokenList(CpuType cpuType, char* tokenList); int64_t EvaluateExpression(string expression, CpuType cpuType, EvalResultType &resultType, bool useCache); void Run(); void PauseOnNextFrame(); void Step(CpuType cpuType, int32_t stepCount, StepType type, BreakSource source = BreakSource::Unspecified); bool IsPaused(); bool IsExecutionStopped(); bool HasBreakRequest(); void BreakRequest(bool release); void ResetSuspendCounter(); void SuspendDebugger(bool release); __noinline void BreakImmediately(CpuType sourceCpu, BreakSource source); template void ProcessPredictiveBreakpoint(CpuType sourceCpu, BreakpointManager* bpManager, MemoryOperationInfo& operation, AddressInfo& addressInfo); template void ProcessBreakConditions(CpuType sourceCpu, StepRequest& step, BreakpointManager* bpManager, MemoryOperationInfo& operation, AddressInfo& addressInfo); void SleepUntilResume(CpuType sourceCpu, BreakSource source, MemoryOperationInfo* operation = nullptr, int breakpointId = -1); void GetCpuState(BaseState& dstState, CpuType cpuType); void SetCpuState(BaseState& srcState, CpuType cpuType); BaseState& GetCpuStateRef(CpuType cpuType); void GetPpuState(BaseState& state, CpuType cpuType); void SetPpuState(BaseState& srcState, CpuType cpuType); void GetConsoleState(BaseState& state, ConsoleType consoleType); DebuggerFeatures GetDebuggerFeatures(CpuType cpuType); uint32_t GetProgramCounter(CpuType cpuType, bool forInstStart); uint8_t GetCpuFlags(CpuType cpuType); CpuInstructionProgress GetInstructionProgress(CpuType cpuType); void SetProgramCounter(CpuType cpuType, uint32_t addr); AddressInfo GetAbsoluteAddress(AddressInfo relAddress); AddressInfo GetRelativeAddress(AddressInfo absAddress, CpuType cpuType); bool HasCpuType(CpuType cpuType); void SetBreakpoints(Breakpoint breakpoints[], uint32_t length); void SetInputOverrides(uint32_t index, DebugControllerState state); void GetAvailableInputOverrides(uint8_t* availableIndexes); void Log(string message); string GetLog(); bool SaveRomToDisk(string filename, bool saveAsIps, CdlStripOption stripOption); void ClearExecutionTrace(); uint32_t GetExecutionTrace(TraceRow output[], uint32_t startOffset, uint32_t maxLineCount); CpuType GetMainCpuType() { return _mainCpuType; } IDebugger* GetMainDebugger(); TraceLogFileSaver* GetTraceLogFileSaver() { return _traceLogSaver.get(); } MemoryDumper* GetMemoryDumper() { return _memoryDumper.get(); } MemoryAccessCounter* GetMemoryAccessCounter() { return _memoryAccessCounter.get(); } Disassembler* GetDisassembler() { return _disassembler.get(); } DisassemblySearch* GetDisassemblySearch() { return _disassemblySearch.get(); } LabelManager* GetLabelManager() { return _labelManager.get(); } CdlManager* GetCdlManager() { return _cdlManager.get(); } ScriptManager* GetScriptManager() { return _scriptManager.get(); } IConsole* GetConsole() { return _console; } Emulator* GetEmulator() { return _emu; } FrozenAddressManager* GetFrozenAddressManager(CpuType cpuType); ITraceLogger* GetTraceLogger(CpuType cpuType); PpuTools* GetPpuTools(CpuType cpuType); BaseEventManager* GetEventManager(CpuType cpuType); CallstackManager* GetCallstackManager(CpuType cpuType); IAssembler* GetAssembler(CpuType cpuType); };