Mesen/Core/Debugger.h
Sour 8508b211cc Debugger: Event Viewer - Added option to show NTSC borders
+ Ported most of Mesen-S' event viewer code to allow this to work
2019-11-19 22:28:45 -05:00

282 lines
8.1 KiB
C++

#pragma once
#include "stdafx.h"
#include <atomic>
#include <deque>
#include <unordered_set>
using std::atomic;
using std::deque;
using std::unordered_set;
#include "../Utilities/SimpleLock.h"
#include "DebuggerTypes.h"
class CPU;
class APU;
class PPU;
class MemoryManager;
class Console;
class Assembler;
class Disassembler;
class LabelManager;
class MemoryDumper;
class MemoryAccessCounter;
class Profiler;
class CodeRunner;
class BaseMapper;
class ScriptHost;
class TraceLogger;
class PerformanceTracker;
class Breakpoint;
class CodeDataLogger;
class ExpressionEvaluator;
class DummyCpu;
class EventManager;
struct ExpressionData;
enum EvalResultType : int32_t;
enum class CdlStripFlag;
class Debugger
{
private:
static constexpr int BreakpointTypeCount = 8;
//Must be static to be thread-safe when switching game
static string _disassemblerOutput;
shared_ptr<Disassembler> _disassembler;
shared_ptr<Assembler> _assembler;
shared_ptr<MemoryDumper> _memoryDumper;
shared_ptr<CodeDataLogger> _codeDataLogger;
shared_ptr<MemoryAccessCounter> _memoryAccessCounter;
shared_ptr<LabelManager> _labelManager;
shared_ptr<TraceLogger> _traceLogger;
shared_ptr<Profiler> _profiler;
shared_ptr<PerformanceTracker> _performanceTracker;
shared_ptr<EventManager> _eventManager;
unique_ptr<CodeRunner> _codeRunner;
shared_ptr<Console> _console;
shared_ptr<CPU> _cpu;
shared_ptr<PPU> _ppu;
shared_ptr<APU> _apu;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseMapper> _mapper;
shared_ptr<DummyCpu> _dummyCpu;
bool _bpDummyCpuRequired;
bool _breakOnFirstCycle;
bool _hasScript;
SimpleLock _scriptLock;
int _nextScriptId;
vector<shared_ptr<ScriptHost>> _scripts;
atomic<int32_t> _preventResume;
atomic<bool> _stopFlag;
atomic<bool> _executionStopped;
atomic<int32_t> _suspendCount;
vector<Breakpoint> _breakpoints[BreakpointTypeCount];
vector<ExpressionData> _breakpointRpnList[BreakpointTypeCount];
bool _hasBreakpoint[BreakpointTypeCount] = {};
vector<uint8_t> _frozenAddresses;
uint32_t _opCodeCycle;
MemoryOperationType _memoryOperationType;
deque<StackFrameInfo> _callstack;
deque<int32_t> _subReturnAddresses;
int32_t _stepOutReturnAddress;
unordered_set<uint32_t> _functionEntryPoints;
unique_ptr<ExpressionEvaluator> _watchExpEval;
unique_ptr<ExpressionEvaluator> _bpExpEval;
DebugState _debugState;
SimpleLock _breakLock;
//Used to alter the executing address via "Set Next Statement"
uint16_t *_currentReadAddr;
uint8_t *_currentReadValue;
int32_t _nextReadAddr;
uint16_t _returnToAddress;
uint32_t _flags;
string _romName;
atomic<int32_t> _stepCount;
atomic<int32_t> _ppuStepCount;
atomic<int32_t> _stepCycleCount;
atomic<uint8_t> _lastInstruction;
atomic<bool> _stepOut;
atomic<int32_t> _stepOverAddr;
BreakSource _breakSource;
atomic<bool> _released;
SimpleLock _releaseLock;
bool _enableBreakOnUninitRead;
atomic<bool> _breakRequested;
bool _pausedForDebugHelper;
atomic<int32_t> _breakOnScanline;
bool _proccessPpuCycle[341];
std::unordered_map<int, int> _ppuViewerUpdateCycle;
uint16_t _ppuScrollX;
uint16_t _ppuScrollY;
int64_t _prevInstructionCycle;
int64_t _curInstructionCycle;
int64_t _runToCycle;
bool _needRewind;
vector<stringstream> _rewindCache;
vector<uint64_t> _rewindPrevInstructionCycleCache;
uint32_t _inputOverride[4];
private:
bool ProcessBreakpoints(BreakpointType type, OperationInfo &operationInfo, bool allowBreak = true, bool allowMark = true);
void ProcessAllBreakpoints(OperationInfo &operationInfo);
void AddCallstackFrame(uint16_t source, uint16_t target, StackFrameFlags flags);
void UpdateCallstack(uint8_t currentInstruction, uint32_t addr);
void ProcessStepConditions(uint16_t addr);
bool SleepUntilResume(BreakSource source, uint32_t breakpointId = 0, BreakpointType bpType = BreakpointType::Global, uint16_t bpAddress = 0, uint8_t bpValue = 0, MemoryOperationType bpMemOpType = MemoryOperationType::Read);
void UpdatePpuCyclesToProcess();
void ResetStepState();
public:
Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<APU> apu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper);
~Debugger();
void ReleaseDebugger(bool needPause);
void SetPpu(shared_ptr<PPU> ppu);
Console* GetConsole();
void SetFlags(uint32_t flags);
bool CheckFlag(DebuggerFlags flag);
void SetBreakpoints(Breakpoint breakpoints[], uint32_t length);
shared_ptr<LabelManager> GetLabelManager();
void GetFunctionEntryPoints(int32_t* entryPoints, int32_t maxCount);
int32_t GetFunctionEntryPointCount();
void GetCallstack(StackFrameInfo* callstackArray, uint32_t &callstackSize);
void GetInstructionProgress(InstructionProgress &state);
void GetApuState(ApuState *state);
void GetState(DebugState *state, bool includeMapperInfo = true);
void SetState(DebugState state);
void Suspend();
void Resume();
void Break();
void ResumeFromBreak();
void PpuStep(uint32_t count = 1);
void Step(uint32_t count = 1, BreakSource source = BreakSource::CpuStep);
void StepCycles(uint32_t cycleCount = 1);
void StepOver();
void StepOut();
void StepBack();
void Run();
void BreakImmediately(BreakSource source);
void BreakOnScanline(int16_t scanline);
bool LoadCdlFile(string cdlFilepath);
void SetCdlData(uint8_t* cdlData, uint32_t length);
void ResetCdl();
void UpdateCdlCache();
bool IsMarkedAsCode(uint16_t relativeAddress);
shared_ptr<CodeDataLogger> GetCodeDataLogger();
void SetNextStatement(uint16_t addr);
void SetPpuViewerScanlineCycle(int32_t ppuViewerId, int32_t scanline, int32_t cycle);
void ClearPpuViewerSettings(int32_t ppuViewer);
bool IsExecutionStopped();
bool IsPauseIconShown();
void PreventResume();
void AllowResume();
void GenerateCodeOutput();
const char* GetCode(uint32_t &length);
int32_t GetRelativeAddress(uint32_t addr, AddressType type);
int32_t GetRelativePpuAddress(uint32_t addr, PpuAddressType type);
int32_t GetAbsoluteAddress(uint32_t addr);
int32_t GetAbsoluteChrAddress(uint32_t addr);
void GetAbsoluteAddressAndType(uint32_t relativeAddr, AddressTypeInfo* info);
void GetPpuAbsoluteAddressAndType(uint32_t relativeAddr, PpuAddressTypeInfo* info);
shared_ptr<Profiler> GetProfiler();
shared_ptr<Assembler> GetAssembler();
shared_ptr<TraceLogger> GetTraceLogger();
shared_ptr<MemoryDumper> GetMemoryDumper();
shared_ptr<MemoryAccessCounter> GetMemoryAccessCounter();
shared_ptr<PerformanceTracker> GetPerformanceTracker();
shared_ptr<EventManager> GetEventManager();
int32_t EvaluateExpression(string expression, EvalResultType &resultType, bool useCache);
bool IsPpuCycleToProcess();
void ProcessPpuCycle();
bool ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value);
void ProcessVramReadOperation(MemoryOperationType type, uint16_t addr, uint8_t &value);
void ProcessVramWriteOperation(uint16_t addr, uint8_t &value);
void SetLastFramePpuScroll(uint16_t addr, uint8_t xScroll, bool updateHorizontalScrollOnly);
uint32_t GetPpuScroll();
void ProcessInterrupt(uint16_t cpuAddr, uint16_t destCpuAddr, bool forNmi);
void AddTrace(const char *log);
void SetFreezeState(uint16_t address, bool frozen);
void GetFreezeState(uint16_t startAddress, uint16_t length, bool* freezeState);
void StartCodeRunner(uint8_t *byteCode, uint32_t codeLength);
void StopCodeRunner();
void GetNesHeader(uint8_t* header);
void SaveRomToDisk(string filename, bool saveAsIps, uint8_t* header, CdlStripFlag cdlStripflag);
void RevertPrgChrChanges();
bool HasPrgChrChanges();
int32_t FindSubEntryPoint(uint16_t relativeAddress);
void SetInputOverride(uint8_t port, uint32_t state);
int32_t LoadScript(string name, string content, int32_t scriptId);
void RemoveScript(int32_t scriptId);
const char* GetScriptLog(int32_t scriptId);
void ResetCounters();
void UpdateProgramCounter(uint16_t &addr, uint8_t &value);
void ProcessScriptSaveState(uint16_t &addr, uint8_t &value);
void ProcessCpuOperation(uint16_t &addr, uint8_t &value, MemoryOperationType type);
void ProcessPpuOperation(uint16_t addr, uint8_t &value, MemoryOperationType type);
void ProcessEvent(EventType type);
uint32_t GetScreenPixel(uint8_t x, uint8_t y);
};