#pragma once #include "stdafx.h" #include #include using std::atomic; using std::deque; #include "CPU.h" #include "PPU.h" #include "DebugState.h" #include "Breakpoint.h" #include "TraceLogger.h" #include "../Utilities/SimpleLock.h" #include "CodeDataLogger.h" class MemoryManager; class Console; class Disassembler; enum class DebugMemoryType { CpuMemory = 0, PpuMemory = 1, PaletteMemory = 2, SpriteMemory = 3, SecondarySpriteMemory = 4, PrgRom = 5, ChrRom = 6, ChrRam = 7, }; class Debugger { private: static Debugger* Instance; unique_ptr _disassembler; unique_ptr _codeDataLogger; shared_ptr _console; shared_ptr _cpu; shared_ptr _ppu; shared_ptr _memoryManager; shared_ptr _mapper; vector _readBreakpoints; vector _writeBreakpoints; vector _execBreakpoints; vector _globalBreakpoints; vector _readVramBreakpoints; vector _writeVramBreakpoints; deque _callstackAbsolute; deque _callstackRelative; SimpleLock _bpLock; SimpleLock _breakLock; unique_ptr _traceLogger; uint16_t *_currentReadAddr; //Used to alter the executing address via "Set Next Statement" string _romFilepath; string _outputCache; atomic _stepCount; atomic _stepCycleCount; atomic _lastInstruction; atomic _stepOut; atomic _stepOverAddr; private: void PrivateProcessPpuCycle(); void PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value); void PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value); bool HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t value); void UpdateCallstack(uint32_t addr); void ProcessStepConditions(uint32_t addr); void BreakOnBreakpoint(MemoryOperationType type, uint32_t addr, uint8_t value); bool SleepUntilResume(); public: Debugger(shared_ptr console, shared_ptr cpu, shared_ptr ppu, shared_ptr memoryManager, shared_ptr mapper); ~Debugger(); void SetBreakpoints(Breakpoint breakpoints[], uint32_t length); uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer); void GetNametable(int nametableIndex, uint32_t* frameBuffer, uint8_t* tileData, uint8_t* paletteData); void GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette); void GetSprites(uint32_t* frameBuffer); void GetPalette(uint32_t* frameBuffer); void GetCallstack(int32_t* callstackAbsolute, int32_t* callstackRelative); void GetState(DebugState *state); void Step(uint32_t count = 1); void StepCycles(uint32_t cycleCount = 1); void StepOver(); void StepOut(); void Run(); bool LoadCdlFile(string cdlFilepath); bool SaveCdlFile(string cdlFilepath); CdlRatios GetCdlRatios(); void ResetCdlLog(); void SetNextStatement(uint16_t addr); bool IsCodeChanged(); string GenerateOutput(); string* GetCode(); uint8_t GetMemoryValue(uint32_t addr); uint32_t GetRelativeAddress(uint32_t addr); void StartTraceLogger(TraceLoggerOptions options); void StopTraceLogger(); int32_t EvaluateExpression(string expression, EvalResultType &resultType); static void ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value); static void ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value); static void ProcessPpuCycle(); static void BreakIfDebugging(); };