1 #pragma once
2 #include "stdafx.h"
3 #include "DebuggerTypes.h"
4 #include "../Utilities/SimpleLock.h"
5 #include "DisassemblyInfo.h"
6 #include "ExpressionEvaluator.h"
7 
8 class MemoryManager;
9 class LabelManager;
10 class Debugger;
11 
12 enum class RowDataType
13 {
14 	Text = 0,
15 	ByteCode,
16 	Disassembly,
17 	EffectiveAddress,
18 	MemoryValue,
19 	Align,
20 	PC,
21 	A,
22 	X,
23 	Y,
24 	SP,
25 	PS,
26 	Cycle,
27 	Scanline,
28 	FrameCount,
29 	CycleCount
30 };
31 
32 struct RowPart
33 {
34 	RowDataType DataType;
35 	string Text;
36 	bool DisplayInHex;
37 	int MinWidth;
38 };
39 
40 struct TraceLoggerOptions
41 {
42 	bool ShowExtraInfo;
43 	bool IndentCode;
44 	bool UseLabels;
45 	bool UseWindowsEol;
46 	bool ExtendZeroPage;
47 
48 	char Condition[1000];
49 	char Format[1000];
50 };
51 
52 class TraceLogger
53 {
54 private:
55 	static constexpr int ExecutionLogSize = 30000;
56 
57 	//Must be static to be thread-safe when switching game
58 	static string _executionTrace;
59 
60 	TraceLoggerOptions _options;
61 	string _outputFilepath;
62 	string _outputBuffer;
63 	ofstream _outputFile;
64 	shared_ptr<MemoryManager> _memoryManager;
65 	shared_ptr<LabelManager> _labelManager;
66 
67 	shared_ptr<ExpressionEvaluator> _expEvaluator;
68 	ExpressionData _conditionData;
69 
70 	vector<RowPart> _rowParts;
71 
72 	bool _pendingLog;
73 	DebugState _lastState;
74 	DisassemblyInfo _lastDisassemblyInfo;
75 
76 	bool _logToFile;
77 	uint16_t _currentPos;
78 	uint32_t _logCount;
79 	State _cpuStateCache[ExecutionLogSize] = {};
80 	PPUDebugState _ppuStateCache[ExecutionLogSize] = {};
81 	DisassemblyInfo _disassemblyCache[ExecutionLogSize];
82 
83 	State _cpuStateCacheCopy[ExecutionLogSize] = {};
84 	PPUDebugState _ppuStateCacheCopy[ExecutionLogSize] = {};
85 	DisassemblyInfo _disassemblyCacheCopy[ExecutionLogSize];
86 
87 	SimpleLock _lock;
88 
89 	void GetStatusFlag(string &output, uint8_t ps, RowPart& part);
90 	void AddRow(DisassemblyInfo &disassemblyInfo, DebugState &state);
91 	bool ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
92 
93 	void GetTraceRow(string &output, State &cpuState, PPUDebugState &ppuState, DisassemblyInfo &disassemblyInfo);
94 
95 	template<typename T> void WriteValue(string &output, T value, RowPart& rowPart);
96 
97 public:
98 	TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
99 	~TraceLogger();
100 
101 	void Log(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo);
102 	void Clear();
103 	void LogNonExec(OperationInfo& operationInfo);
104 	void SetOptions(TraceLoggerOptions options);
105 	void StartLogging(string filename);
106 	void StopLogging();
107 
108 	void LogExtraInfo(const char *log, uint64_t cycleCount);
109 
110 	const char* GetExecutionTrace(uint32_t lineCount);
111 };