Mesen-S/Core/TraceLogger.h
Sour 5f055110fa Added Game Boy support
CPU/APU are decent - PPU is still just a scanline renderer
No Super Game Boy support yet
2020-05-18 16:11:08 -04:00

158 lines
4.2 KiB
C++

#pragma once
#include "stdafx.h"
#include "CpuTypes.h"
#include "PpuTypes.h"
#include "SpcTypes.h"
#include "GbTypes.h"
#include "DebugTypes.h"
#include "DisassemblyInfo.h"
#include "DebugUtilities.h"
#include "../Utilities/SimpleLock.h"
class Console;
class Debugger;
class LabelManager;
class MemoryDumper;
class EmuSettings;
struct DebugState;
struct TraceLoggerOptions
{
bool LogCpu;
bool LogSpc;
bool LogNecDsp;
bool LogSa1;
bool LogGsu;
bool LogCx4;
bool LogGameboy;
bool ShowExtraInfo;
bool IndentCode;
bool UseLabels;
bool UseWindowsEol;
bool ExtendZeroPage;
char Condition[1000];
char Format[1000];
};
enum class RowDataType
{
Text = 0,
ByteCode,
Disassembly,
EffectiveAddress,
MemoryValue,
Align,
PC,
A,
B,
C,
D,
E,
F,
H,
L,
X,
Y,
DB,
SP,
PS,
Cycle,
Scanline,
HClock,
FrameCount,
CycleCount
};
struct RowPart
{
RowDataType DataType;
string Text;
bool DisplayInHex;
int MinWidth;
};
class TraceLogger
{
private:
static constexpr int ExecutionLogSize = 30000;
//Must be static to be thread-safe when switching game
static string _executionTrace;
TraceLoggerOptions _options;
string _outputFilepath;
string _outputBuffer;
ofstream _outputFile;
Console* _console;
EmuSettings* _settings;
LabelManager* _labelManager;
MemoryDumper* _memoryDumper;
vector<RowPart> _rowParts;
vector<RowPart> _spcRowParts;
vector<RowPart> _dspRowParts;
vector<RowPart> _gsuRowParts;
vector<RowPart> _cx4RowParts;
vector<RowPart> _gbRowParts;
bool _logCpu[(int)DebugUtilities::GetLastCpuType() + 1] = {};
bool _pendingLog;
//CpuState _lastState;
//DisassemblyInfo _lastDisassemblyInfo;
bool _logToFile;
uint32_t _currentPos;
uint32_t _logCount;
DebugState *_stateCache = nullptr;
DisassemblyInfo *_disassemblyCache = nullptr;
CpuType* _logCpuType = nullptr;
DebugState *_stateCacheCopy = nullptr;
DisassemblyInfo *_disassemblyCacheCopy = nullptr;
CpuType* _logCpuTypeCopy = nullptr;
SimpleLock _lock;
template<CpuType cpuType> void GetStatusFlag(string &output, uint8_t ps, RowPart& part);
void WriteByteCode(DisassemblyInfo &info, RowPart &rowPart, string &output);
void WriteDisassembly(DisassemblyInfo &info, RowPart &rowPart, uint8_t sp, uint32_t pc, string &output);
void WriteEffectiveAddress(DisassemblyInfo &info, RowPart &rowPart, void *cpuState, string &output, SnesMemoryType cpuMemoryType, CpuType cpuType);
void WriteMemoryValue(DisassemblyInfo &info, RowPart &rowPart, void *cpuState, string &output, SnesMemoryType memType, CpuType cpuType);
void WriteAlign(int originalSize, RowPart &rowPart, string &output);
void AddRow(CpuType cpuType, DisassemblyInfo &disassemblyInfo, DebugState &state);
//bool ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
void ParseFormatString(vector<RowPart> &rowParts, string format);
void GetTraceRow(string &output, CpuType cpuType, DisassemblyInfo &disassemblyInfo, DebugState &state);
void GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo, SnesMemoryType memType, CpuType cpuType);
void GetTraceRow(string &output, SpcState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
void GetTraceRow(string &output, NecDspState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
void GetTraceRow(string &output, GsuState &gsuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
void GetTraceRow(string& output, Cx4State& cx4State, PpuState& ppuState, DisassemblyInfo& disassemblyInfo);
void GetTraceRow(string &output, GbCpuState &gbState, GbPpuState &gbPpuState, DisassemblyInfo &disassemblyInfo);
template<typename T> void WriteValue(string &output, T value, RowPart& rowPart);
public:
TraceLogger(Debugger* debugger, shared_ptr<Console> console);
~TraceLogger();
__forceinline bool IsCpuLogged(CpuType type) { return _logCpu[(int)type]; }
void Log(CpuType cpuType, DebugState &state, DisassemblyInfo &disassemblyInfo);
void Clear();
//void LogNonExec(OperationInfo& operationInfo);
void SetOptions(TraceLoggerOptions options);
void StartLogging(string filename);
void StopLogging();
void LogExtraInfo(const char *log, uint32_t cycleCount);
const char* GetExecutionTrace(uint32_t lineCount);
};