2015-07-01 23:17:14 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <atomic>
|
2015-08-09 14:47:27 -04:00
|
|
|
#include <deque>
|
2015-07-01 23:17:14 -04:00
|
|
|
using std::atomic;
|
2015-08-09 14:47:27 -04:00
|
|
|
using std::deque;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
2016-01-10 19:56:40 -05:00
|
|
|
#include "DebugState.h"
|
2015-07-01 23:17:14 -04:00
|
|
|
#include "Breakpoint.h"
|
2016-01-10 19:56:40 -05:00
|
|
|
#include "TraceLogger.h"
|
2015-07-01 23:17:14 -04:00
|
|
|
#include "../Utilities/SimpleLock.h"
|
2015-08-17 19:32:10 -04:00
|
|
|
#include "CodeDataLogger.h"
|
2015-07-01 23:17:14 -04:00
|
|
|
|
2016-06-17 20:53:05 -04:00
|
|
|
class CPU;
|
|
|
|
class PPU;
|
2015-07-01 23:17:14 -04:00
|
|
|
class MemoryManager;
|
|
|
|
class Console;
|
|
|
|
class Disassembler;
|
|
|
|
|
2015-08-05 20:40:10 -04:00
|
|
|
enum class DebugMemoryType
|
|
|
|
{
|
|
|
|
CpuMemory = 0,
|
|
|
|
PpuMemory = 1,
|
2015-08-05 21:43:53 -04:00
|
|
|
PaletteMemory = 2,
|
|
|
|
SpriteMemory = 3,
|
|
|
|
SecondarySpriteMemory = 4,
|
|
|
|
PrgRom = 5,
|
|
|
|
ChrRom = 6,
|
2016-01-19 20:16:00 -05:00
|
|
|
ChrRam = 7,
|
2015-08-05 20:40:10 -04:00
|
|
|
};
|
|
|
|
|
2016-06-05 10:26:05 -04:00
|
|
|
enum class DebuggerFlags
|
|
|
|
{
|
|
|
|
PpuPartialDraw = 1
|
|
|
|
};
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
class Debugger
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
static Debugger* Instance;
|
|
|
|
|
|
|
|
unique_ptr<Disassembler> _disassembler;
|
2015-08-17 19:32:10 -04:00
|
|
|
unique_ptr<CodeDataLogger> _codeDataLogger;
|
2015-07-01 23:17:14 -04:00
|
|
|
shared_ptr<Console> _console;
|
|
|
|
shared_ptr<CPU> _cpu;
|
|
|
|
shared_ptr<PPU> _ppu;
|
|
|
|
shared_ptr<MemoryManager> _memoryManager;
|
|
|
|
shared_ptr<BaseMapper> _mapper;
|
2016-01-09 13:15:43 -05:00
|
|
|
|
2016-01-26 16:47:21 -05:00
|
|
|
atomic<bool> _bpUpdateNeeded;
|
2016-06-04 08:55:52 -04:00
|
|
|
atomic<bool> _updatingBreakpoints;
|
|
|
|
atomic<bool> _stopFlag;
|
2016-01-26 16:47:21 -05:00
|
|
|
atomic<bool> _executionStopped;
|
2016-06-04 08:55:52 -04:00
|
|
|
atomic<int32_t> _suspendCount;
|
2016-01-26 16:47:21 -05:00
|
|
|
vector<Breakpoint> _newBreakpoints;
|
2016-01-09 13:15:43 -05:00
|
|
|
vector<Breakpoint> _readBreakpoints;
|
|
|
|
vector<Breakpoint> _writeBreakpoints;
|
|
|
|
vector<Breakpoint> _execBreakpoints;
|
|
|
|
vector<Breakpoint> _globalBreakpoints;
|
|
|
|
vector<Breakpoint> _readVramBreakpoints;
|
|
|
|
vector<Breakpoint> _writeVramBreakpoints;
|
2016-01-26 16:47:21 -05:00
|
|
|
atomic<bool> _hasBreakpoint;
|
2016-01-09 13:15:43 -05:00
|
|
|
|
2015-08-09 14:47:27 -04:00
|
|
|
deque<uint32_t> _callstackAbsolute;
|
|
|
|
deque<uint32_t> _callstackRelative;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
2016-01-26 16:47:21 -05:00
|
|
|
DebugState _debugState;
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
SimpleLock _breakLock;
|
|
|
|
|
2016-01-10 19:56:40 -05:00
|
|
|
unique_ptr<TraceLogger> _traceLogger;
|
2016-06-26 09:01:23 -04:00
|
|
|
SimpleLock _traceLock;
|
2016-01-10 19:56:40 -05:00
|
|
|
|
2015-08-17 21:59:22 -04:00
|
|
|
uint16_t *_currentReadAddr; //Used to alter the executing address via "Set Next Statement"
|
|
|
|
|
2016-06-05 10:26:05 -04:00
|
|
|
uint32_t _flags;
|
|
|
|
|
2016-06-17 20:53:05 -04:00
|
|
|
string _romName;
|
2015-07-01 23:17:14 -04:00
|
|
|
string _outputCache;
|
2015-08-09 20:45:45 -04:00
|
|
|
atomic<int32_t> _stepCount;
|
2016-06-04 15:38:48 -04:00
|
|
|
atomic<int32_t> _ppuStepCount;
|
2015-07-01 23:17:14 -04:00
|
|
|
atomic<int32_t> _stepCycleCount;
|
|
|
|
atomic<uint8_t> _lastInstruction;
|
|
|
|
atomic<bool> _stepOut;
|
|
|
|
atomic<int32_t> _stepOverAddr;
|
|
|
|
|
|
|
|
private:
|
2016-01-26 16:47:21 -05:00
|
|
|
void UpdateBreakpoints();
|
|
|
|
|
2016-01-09 13:15:43 -05:00
|
|
|
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);
|
2015-08-17 19:32:10 -04:00
|
|
|
void UpdateCallstack(uint32_t addr);
|
|
|
|
void ProcessStepConditions(uint32_t addr);
|
2016-01-09 13:15:43 -05:00
|
|
|
void BreakOnBreakpoint(MemoryOperationType type, uint32_t addr, uint8_t value);
|
2015-07-01 23:17:14 -04:00
|
|
|
bool SleepUntilResume();
|
|
|
|
|
|
|
|
public:
|
|
|
|
Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper);
|
|
|
|
~Debugger();
|
|
|
|
|
2016-06-05 10:26:05 -04:00
|
|
|
void SetFlags(uint32_t flags);
|
|
|
|
bool CheckFlag(DebuggerFlags flag);
|
|
|
|
|
2016-01-09 13:15:43 -05:00
|
|
|
void SetBreakpoints(Breakpoint breakpoints[], uint32_t length);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
2015-08-05 20:40:10 -04:00
|
|
|
uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer);
|
2015-08-08 22:36:39 -04:00
|
|
|
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);
|
2015-08-05 20:40:10 -04:00
|
|
|
|
2015-08-09 14:47:27 -04:00
|
|
|
void GetCallstack(int32_t* callstackAbsolute, int32_t* callstackRelative);
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
void GetState(DebugState *state);
|
|
|
|
|
2016-06-04 08:55:52 -04:00
|
|
|
void Suspend();
|
|
|
|
void Resume();
|
|
|
|
|
2016-06-04 15:38:48 -04:00
|
|
|
void PpuStep(uint32_t count = 1);
|
2015-07-01 23:17:14 -04:00
|
|
|
void Step(uint32_t count = 1);
|
|
|
|
void StepCycles(uint32_t cycleCount = 1);
|
|
|
|
void StepOver();
|
|
|
|
void StepOut();
|
|
|
|
void Run();
|
|
|
|
|
2015-08-17 19:32:10 -04:00
|
|
|
bool LoadCdlFile(string cdlFilepath);
|
|
|
|
bool SaveCdlFile(string cdlFilepath);
|
|
|
|
CdlRatios GetCdlRatios();
|
|
|
|
void ResetCdlLog();
|
|
|
|
|
2015-08-17 21:59:22 -04:00
|
|
|
void SetNextStatement(uint16_t addr);
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
bool IsCodeChanged();
|
|
|
|
string GenerateOutput();
|
|
|
|
string* GetCode();
|
2016-01-10 13:23:19 -05:00
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
uint8_t GetMemoryValue(uint32_t addr);
|
|
|
|
uint32_t GetRelativeAddress(uint32_t addr);
|
2016-01-10 13:23:19 -05:00
|
|
|
|
2016-01-10 19:56:40 -05:00
|
|
|
void StartTraceLogger(TraceLoggerOptions options);
|
|
|
|
void StopTraceLogger();
|
|
|
|
|
2016-01-10 13:23:19 -05:00
|
|
|
int32_t EvaluateExpression(string expression, EvalResultType &resultType);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
2016-01-09 13:15:43 -05:00
|
|
|
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();
|
2015-12-29 20:54:55 -05:00
|
|
|
|
2016-06-05 10:26:05 -04:00
|
|
|
static bool IsEnabled();
|
2015-12-29 20:54:55 -05:00
|
|
|
static void BreakIfDebugging();
|
2015-07-01 23:17:14 -04:00
|
|
|
};
|