yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
rom_debug_agent.h
Go to the documentation of this file.
1#ifndef YAZE_CLI_SERVICE_AGENT_ROM_DEBUG_AGENT_H_
2#define YAZE_CLI_SERVICE_AGENT_ROM_DEBUG_AGENT_H_
3
4#include <cstdint>
5#include <map>
6#include <memory>
7#include <optional>
8#include <string>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "absl/status/statusor.h"
17#include "protos/emulator_service.grpc.pb.h"
18
19namespace yaze {
20namespace cli {
21namespace agent {
22
38 public:
43 uint32_t address; // Breakpoint address
44 std::string location_description; // Human-readable location (e.g., "MainGameLoop+$10")
45 std::string disassembly; // Disassembled instruction
46 std::string instruction_explanation; // AI-friendly explanation of what the instruction does
47 std::map<std::string, uint16_t> registers; // Current register values
48 std::vector<std::string> call_stack; // Call stack leading to this point
49 std::vector<std::string> context_lines; // Surrounding disassembly for context
50 std::vector<std::string> suggestions; // Debugging suggestions
51 std::string memory_context; // Relevant memory state description
52 };
53
58 uint32_t address; // Memory address
59 size_t length; // Length of analyzed region
60 std::string data_type; // "sprite", "tile", "palette", "dma", "audio", etc.
61 std::string structure_name; // Specific structure name if known
62 std::string description; // Human-readable description
63 std::vector<uint8_t> data; // Raw data
64 std::map<std::string, uint32_t> fields; // Parsed fields (if structured data)
65 std::vector<std::string> anomalies; // Detected issues or unusual values
66 };
67
72 uint32_t address; // Patch location
73 size_t length; // Patch size
74 std::vector<uint8_t> original_code; // Original ROM code
75 std::vector<uint8_t> patched_code; // Patched code
76 std::string original_disassembly; // Disassembled original
77 std::string patched_disassembly; // Disassembled patch
78 std::vector<std::string> differences; // Key differences explained
79 std::vector<std::string> potential_issues; // Detected problems
80 bool is_safe; // Whether patch appears safe
81 };
82
86 enum class IssueType {
87 kBadJumpTarget, // Jump to invalid address
88 kStackImbalance, // Stack pointer corruption
89 kWramCorruption, // Writing to critical WRAM areas
90 kDmaConflict, // DMA during wrong time
91 kBankOverflow, // Code/data exceeds bank boundary
92 kInvalidOpcode, // Executing data as code
93 kInfiniteLoop, // Detected infinite loop
94 kNullPointer, // Dereferencing zero page incorrectly
95 kAudioDesync, // SPC700 communication issue
96 kPpuTimingViolation, // Writing to PPU at wrong time
97 };
98
104 uint32_t address;
105 std::string description;
106 std::string suggested_fix;
107 int severity; // 1-5, 5 being most severe
108 };
109
110 // Constructor
111 explicit RomDebugAgent(yaze::net::EmulatorServiceImpl* emulator_service);
112
113 // --- Core Analysis Functions ---
114
118 absl::StatusOr<BreakpointAnalysis> AnalyzeBreakpoint(
119 const yaze::agent::BreakpointHitResponse& hit);
120
124 absl::StatusOr<MemoryAnalysis> AnalyzeMemory(
125 uint32_t address, size_t length);
126
130 absl::StatusOr<std::string> ExplainExecutionTrace(
131 const std::vector<ExecutionTraceBuffer::TraceEntry>& trace);
132
136 absl::StatusOr<PatchComparisonResult> ComparePatch(
137 uint32_t address, size_t length, const std::vector<uint8_t>& original);
138
139 // --- Pattern Detection ---
140
144 std::vector<DetectedIssue> ScanForIssues(
145 uint32_t start_address, uint32_t end_address);
146
150 bool IsValidJumpTarget(uint32_t address) const;
151
155 bool HasStackImbalance(uint32_t routine_start, uint32_t routine_end);
156
160 bool IsMemoryWriteSafe(uint32_t address, size_t length) const;
161
162 // --- Helper Functions ---
163
167 std::string DescribeMemoryLocation(uint32_t address) const;
168
172 std::string IdentifyDataType(uint32_t address) const;
173
177 std::string FormatRegisterState(const std::map<std::string, uint16_t>& regs) const;
178
182 absl::Status LoadSymbols(const std::string& symbol_file);
183
187 void SetOriginalRom(const std::vector<uint8_t>& rom_data);
188
189 // --- Mesen2 Live Debugging Integration ---
190
194 void SetMesenClient(std::shared_ptr<emu::mesen::MesenSocketClient> client);
195
199 bool IsMesenConnected() const;
200
204 absl::StatusOr<emu::mesen::GameState> GetLiveGameState();
205
209 absl::StatusOr<std::vector<emu::mesen::SpriteInfo>> GetLiveSprites(bool all = false);
210
214 absl::StatusOr<emu::mesen::CpuState> GetLiveCpuState();
215
219 absl::StatusOr<BreakpointAnalysis> AnalyzeLiveBreakpoint(uint32_t address);
220
224 absl::StatusOr<std::string> ExplainCurrentGameState();
225
229 std::vector<std::string> AnalyzeSpriteAnomalies();
230
231 private:
232 // --- ALTTP Memory Layout Constants ---
233
234 // WRAM regions ($7E0000-$7FFFFF)
235 static constexpr uint32_t WRAM_START = 0x7E0000;
236 static constexpr uint32_t WRAM_END = 0x7FFFFF;
237
238 // System variables
239 static constexpr uint32_t GAME_MODE = 0x7E0010;
240 static constexpr uint32_t SUBMODULE = 0x7E0011;
241 static constexpr uint32_t NMI_FLAG = 0x7E0012;
242 static constexpr uint32_t FRAME_COUNTER = 0x7E001A;
243
244 // Player/Link state
245 static constexpr uint32_t LINK_X_POS = 0x7E0022;
246 static constexpr uint32_t LINK_Y_POS = 0x7E0020;
247 static constexpr uint32_t LINK_STATE = 0x7E005D;
248 static constexpr uint32_t LINK_DIRECTION = 0x7E002F;
249
250 // Sprite tables
251 static constexpr uint32_t SPRITE_TABLE_START = 0x7E0D00;
252 static constexpr uint32_t SPRITE_TABLE_END = 0x7E0FFF;
253 static constexpr uint32_t SPRITE_STATE = 0x7E0D10;
254 static constexpr uint32_t SPRITE_X_LOW = 0x7E0D30;
255 static constexpr uint32_t SPRITE_X_HIGH = 0x7E0D20;
256 static constexpr uint32_t SPRITE_Y_LOW = 0x7E0D00;
257 static constexpr uint32_t SPRITE_Y_HIGH = 0x7E0D20;
258
259 // OAM (Object Attribute Memory) buffer
260 static constexpr uint32_t OAM_BUFFER = 0x7E0800;
261 static constexpr uint32_t OAM_BUFFER_END = 0x7E0A1F;
262
263 // DMA registers
264 static constexpr uint32_t DMA0_CONTROL = 0x004300;
265 static constexpr uint32_t DMA_ENABLE = 0x00420B;
266 static constexpr uint32_t HDMA_ENABLE = 0x00420C;
267
268 // PPU registers
269 static constexpr uint32_t PPU_INIDISP = 0x002100;
270 static constexpr uint32_t PPU_BGMODE = 0x002105;
271 static constexpr uint32_t PPU_CGADD = 0x002121;
272 static constexpr uint32_t PPU_CGDATA = 0x002122;
273
274 // Audio communication
275 static constexpr uint32_t APU_PORT0 = 0x002140;
276 static constexpr uint32_t APU_PORT1 = 0x002141;
277 static constexpr uint32_t APU_PORT2 = 0x002142;
278 static constexpr uint32_t APU_PORT3 = 0x002143;
279
280 // Save data
281 static constexpr uint32_t SRAM_START = 0x7EF000;
282 static constexpr uint32_t SRAM_END = 0x7EF4FF;
283 static constexpr uint32_t PLAYER_NAME = 0x7EF000;
284 static constexpr uint32_t PLAYER_HEALTH = 0x7EF36D;
285 static constexpr uint32_t PLAYER_MAX_HEALTH = 0x7EF36C;
286 static constexpr uint32_t INVENTORY_START = 0x7EF340;
287
288 // --- Helper Methods ---
289
293 absl::StatusOr<std::string> AnalyzeInstruction(
294 uint32_t address, const uint8_t* code, size_t max_length);
295
299 std::vector<std::string> GetDisassemblyContext(
300 uint32_t address, int before_lines, int after_lines);
301
305 std::vector<std::string> BuildCallStack(uint32_t current_pc);
306
310 std::optional<DetectedIssue> DetectIssuePattern(
311 uint32_t address, const uint8_t* code, size_t length);
312
316 bool IsCriticalMemoryArea(uint32_t address) const;
317
321 std::optional<std::string> GetStructureInfo(uint32_t address) const;
322
323 // Member variables
325 std::unique_ptr<Disassembler65816> disassembler_;
326 std::unique_ptr<yaze::emu::debug::SymbolProvider> symbol_provider_;
327 std::vector<uint8_t> original_rom_; // Original ROM for comparison
328 std::shared_ptr<emu::mesen::MesenSocketClient> mesen_client_; // Mesen2 integration
329
330 // Cache for performance
331 mutable std::map<uint32_t, std::string> address_description_cache_;
332 mutable std::map<uint32_t, std::string> data_type_cache_;
333};
334
335} // namespace agent
336} // namespace cli
337} // namespace yaze
338
339#endif // YAZE_CLI_SERVICE_AGENT_ROM_DEBUG_AGENT_H_
ROM Debugging Agent for AI-assisted ROM hacking.
static constexpr uint32_t FRAME_COUNTER
yaze::net::EmulatorServiceImpl * emulator_service_
void SetOriginalRom(const std::vector< uint8_t > &rom_data)
Set the original ROM data for comparison.
static constexpr uint32_t OAM_BUFFER
static constexpr uint32_t PLAYER_HEALTH
absl::StatusOr< emu::mesen::CpuState > GetLiveCpuState()
Get live CPU state from Mesen2.
static constexpr uint32_t SPRITE_X_LOW
static constexpr uint32_t LINK_Y_POS
static constexpr uint32_t OAM_BUFFER_END
static constexpr uint32_t DMA_ENABLE
static constexpr uint32_t SPRITE_X_HIGH
absl::StatusOr< std::string > ExplainExecutionTrace(const std::vector< ExecutionTraceBuffer::TraceEntry > &trace)
Analyze execution trace and explain program flow.
static constexpr uint32_t WRAM_END
absl::StatusOr< BreakpointAnalysis > AnalyzeBreakpoint(const yaze::agent::BreakpointHitResponse &hit)
Analyze a breakpoint hit with full context.
static constexpr uint32_t APU_PORT0
bool IsMemoryWriteSafe(uint32_t address, size_t length) const
Check if memory write is safe.
static constexpr uint32_t PPU_BGMODE
static constexpr uint32_t LINK_X_POS
std::string FormatRegisterState(const std::map< std::string, uint16_t > &regs) const
Format register state for debugging output.
static constexpr uint32_t SPRITE_TABLE_START
bool IsValidJumpTarget(uint32_t address) const
Check if an address is a valid jump target.
static constexpr uint32_t PPU_CGADD
std::vector< std::string > AnalyzeSpriteAnomalies()
Detect anomalies in current sprite table.
absl::StatusOr< BreakpointAnalysis > AnalyzeLiveBreakpoint(uint32_t address)
Analyze a live breakpoint hit from Mesen2.
static constexpr uint32_t INVENTORY_START
static constexpr uint32_t GAME_MODE
absl::StatusOr< std::string > ExplainCurrentGameState()
Generate AI-friendly explanation of current game state.
static constexpr uint32_t APU_PORT2
static constexpr uint32_t SRAM_END
std::optional< std::string > GetStructureInfo(uint32_t address) const
Get structure information for a memory address.
std::map< uint32_t, std::string > address_description_cache_
std::vector< DetectedIssue > ScanForIssues(uint32_t start_address, uint32_t end_address)
Scan for common ROM hacking issues in a code region.
static constexpr uint32_t SRAM_START
std::vector< std::string > GetDisassemblyContext(uint32_t address, int before_lines, int after_lines)
Get surrounding context for an address.
std::vector< std::string > BuildCallStack(uint32_t current_pc)
Build call stack from execution trace.
bool HasStackImbalance(uint32_t routine_start, uint32_t routine_end)
Detect stack imbalance in a subroutine.
std::vector< uint8_t > original_rom_
std::map< uint32_t, std::string > data_type_cache_
static constexpr uint32_t SPRITE_STATE
static constexpr uint32_t APU_PORT3
absl::StatusOr< std::vector< emu::mesen::SpriteInfo > > GetLiveSprites(bool all=false)
Get live sprite list from Mesen2.
void SetMesenClient(std::shared_ptr< emu::mesen::MesenSocketClient > client)
Set the Mesen2 socket client for live debugging.
absl::Status LoadSymbols(const std::string &symbol_file)
Load symbol table for better disassembly.
static constexpr uint32_t SPRITE_Y_LOW
absl::StatusOr< PatchComparisonResult > ComparePatch(uint32_t address, size_t length, const std::vector< uint8_t > &original)
Compare original ROM code with patched code.
std::unique_ptr< yaze::emu::debug::SymbolProvider > symbol_provider_
std::shared_ptr< emu::mesen::MesenSocketClient > mesen_client_
std::optional< DetectedIssue > DetectIssuePattern(uint32_t address, const uint8_t *code, size_t length)
Detect pattern of common issues.
RomDebugAgent(yaze::net::EmulatorServiceImpl *emulator_service)
static constexpr uint32_t SPRITE_Y_HIGH
static constexpr uint32_t SPRITE_TABLE_END
std::string DescribeMemoryLocation(uint32_t address) const
Get human-readable description of a memory address.
static constexpr uint32_t SUBMODULE
absl::StatusOr< std::string > AnalyzeInstruction(uint32_t address, const uint8_t *code, size_t max_length)
Analyze the instruction at an address.
static constexpr uint32_t PPU_INIDISP
bool IsCriticalMemoryArea(uint32_t address) const
Check if address is in a critical system area.
static constexpr uint32_t NMI_FLAG
absl::StatusOr< MemoryAnalysis > AnalyzeMemory(uint32_t address, size_t length)
Analyze a memory region and identify its purpose.
static constexpr uint32_t LINK_STATE
absl::StatusOr< emu::mesen::GameState > GetLiveGameState()
Get live game state from Mesen2.
bool IsMesenConnected() const
Check if connected to Mesen2.
static constexpr uint32_t PLAYER_NAME
static constexpr uint32_t HDMA_ENABLE
static constexpr uint32_t WRAM_START
static constexpr uint32_t PPU_CGDATA
static constexpr uint32_t PLAYER_MAX_HEALTH
static constexpr uint32_t DMA0_CONTROL
static constexpr uint32_t APU_PORT1
std::unique_ptr< Disassembler65816 > disassembler_
IssueType
Common ROM hacking issue types.
static constexpr uint32_t LINK_DIRECTION
std::string IdentifyDataType(uint32_t address) const
Get the data type at a memory address.
Analysis result for a breakpoint hit.
std::map< std::string, uint32_t > fields