yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
memory_debugging_example.cc
Go to the documentation of this file.
1
9#include <iostream>
10#include <memory>
11
12#include "app/emu/emulator.h"
15#include "absl/status/status.h"
16#include "util/log.h"
17
18namespace yaze {
19namespace cli {
20namespace agent {
21
33 public:
35 : emulator_(emulator),
36 breakpoint_mgr_(emulator->breakpoint_manager()),
37 watchpoint_mgr_(emulator->watchpoint_manager()) {}
38
42 absl::Status TrackPlayerHealth() {
43 // Common health addresses in Zelda3 (example addresses)
44 constexpr uint32_t PLAYER_HEALTH = 0x7EF36D; // Player's current health
45 constexpr uint32_t PLAYER_MAX_HEALTH = 0x7EF36C; // Max health
46
47 // Add watchpoint to track all changes to player health
48 uint32_t health_wp = watchpoint_mgr_.AddWatchpoint(
49 PLAYER_HEALTH, PLAYER_HEALTH,
50 false, // Don't track reads (too noisy)
51 true, // Track writes
52 false, // Don't break (just log)
53 "Player Health Tracking"
54 );
55
56 LOG_INFO("MemoryDebug", "Added watchpoint for player health at $%06X (ID: %d)",
57 PLAYER_HEALTH, health_wp);
58
59 // Add a breakpoint that triggers when health reaches zero
60 uint32_t death_bp = breakpoint_mgr_.AddBreakpoint(
61 PLAYER_HEALTH,
64 "", // Could add condition like "value == 0"
65 "Player Death Detection"
66 );
67
68 LOG_INFO("MemoryDebug", "Added breakpoint for player death at $%06X (ID: %d)",
69 PLAYER_HEALTH, death_bp);
70
71 return absl::OkStatus();
72 }
73
77 absl::Status MonitorInventory() {
78 // Zelda3 inventory ranges (example)
79 constexpr uint32_t INVENTORY_START = 0x7EF340;
80 constexpr uint32_t INVENTORY_END = 0x7EF37F;
81
82 // Add range watchpoint for entire inventory
83 uint32_t inv_wp = watchpoint_mgr_.AddWatchpoint(
84 INVENTORY_START, INVENTORY_END,
85 false, // Don't track reads
86 true, // Track writes
87 false, // Don't break
88 "Inventory Changes"
89 );
90
91 LOG_INFO("MemoryDebug", "Monitoring inventory range $%06X-$%06X (ID: %d)",
92 INVENTORY_START, INVENTORY_END, inv_wp);
93
94 return absl::OkStatus();
95 }
96
100 absl::Status DebugSpriteData() {
101 // Sprite data typically in specific WRAM regions
102 constexpr uint32_t SPRITE_TABLE_START = 0x7E0D00;
103 constexpr uint32_t SPRITE_TABLE_END = 0x7E0EFF;
104
105 // Add watchpoint with break-on-access for debugging
106 uint32_t sprite_wp = watchpoint_mgr_.AddWatchpoint(
107 SPRITE_TABLE_START, SPRITE_TABLE_END,
108 true, // Track reads (to see what accesses sprite data)
109 true, // Track writes
110 true, // Break on suspicious writes
111 "Sprite Table Debugging"
112 );
113
114 LOG_INFO("MemoryDebug", "Debugging sprite table $%06X-$%06X (ID: %d)",
115 SPRITE_TABLE_START, SPRITE_TABLE_END, sprite_wp);
116
117 return absl::OkStatus();
118 }
119
123 absl::Status TrackDMATransfers() {
124 // DMA registers
125 constexpr uint32_t DMA_REGS_START = 0x004300;
126 constexpr uint32_t DMA_REGS_END = 0x00437F;
127
128 // Monitor DMA register writes
129 uint32_t dma_wp = watchpoint_mgr_.AddWatchpoint(
130 DMA_REGS_START, DMA_REGS_END,
131 false, // Don't track reads
132 true, // Track writes
133 false, // Don't break
134 "DMA Transfer Monitoring"
135 );
136
137 LOG_INFO("MemoryDebug", "Monitoring DMA registers $%06X-$%06X (ID: %d)",
138 DMA_REGS_START, DMA_REGS_END, dma_wp);
139
140 return absl::OkStatus();
141 }
142
146 absl::Status AnalyzeWatchpointData() {
147 // Get all watchpoints
148 auto watchpoints = watchpoint_mgr_.GetAllWatchpoints();
149
150 for (const auto& wp : watchpoints) {
151 LOG_INFO("MemoryDebug", "Watchpoint '%s' (ID: %d):",
152 wp.description.c_str(), wp.id);
153
154 // Get history for this watchpoint's address range
155 auto history = watchpoint_mgr_.GetHistory(wp.start_address, 100);
156
157 // Analyze access patterns
158 int read_count = 0;
159 int write_count = 0;
160 uint8_t last_value = 0;
161 bool value_changed = false;
162
163 for (const auto& access : history) {
164 if (access.is_write) {
165 write_count++;
166 if (access.new_value != last_value) {
167 value_changed = true;
168 last_value = access.new_value;
169 }
170 } else {
171 read_count++;
172 }
173 }
174
175 LOG_INFO("MemoryDebug", " - Reads: %d, Writes: %d, Value changes: %s",
176 read_count, write_count, value_changed ? "Yes" : "No");
177
178 // Report interesting patterns
179 if (write_count > 10) {
180 LOG_WARNING("MemoryDebug", " - High write frequency detected!");
181 }
182 if (value_changed) {
183 LOG_INFO("MemoryDebug", " - Last value: $%02X", last_value);
184 }
185 }
186
187 return absl::OkStatus();
188 }
189
193 absl::Status ExportWatchpointHistory(const std::string& filename) {
194 if (watchpoint_mgr_.ExportHistoryToCSV(filename)) {
195 LOG_INFO("MemoryDebug", "Exported watchpoint history to %s", filename.c_str());
196 return absl::OkStatus();
197 }
198 return absl::InternalError("Failed to export watchpoint history");
199 }
200
207 LOG_INFO("MemoryDebug", "Cleared all breakpoints and watchpoints");
208 }
209
214 // Enable debugging mode
216
217 // Set up various monitoring points
222
223 LOG_INFO("MemoryDebug", "Memory debugging session initialized");
224
225 // Run emulation for a bit to collect data
226 // (In practice, this would be controlled by the agent)
227 LOG_INFO("MemoryDebug", "Running emulation to collect memory access data...");
228
229 // After some emulation...
231
232 // Export results
233 RETURN_IF_ERROR(ExportWatchpointHistory("/tmp/memory_debug.csv"));
234
235 // Clean up
237
238 return absl::OkStatus();
239 }
240
241 private:
245};
246
247} // namespace agent
248} // namespace cli
249} // namespace yaze
Demonstrates memory debugging capabilities for AI agents.
absl::Status ExportWatchpointHistory(const std::string &filename)
Manages CPU and SPC700 breakpoints for debugging.
void ClearAll()
Clear all breakpoints.
uint32_t AddBreakpoint(uint32_t address, Type type, CpuType cpu, const std::string &condition="", const std::string &description="")
Add a new breakpoint.
A class for emulating and debugging SNES games.
Definition emulator.h:39
void set_debugging(bool debugging)
Definition emulator.h:120
Manages memory watchpoints for debugging.
uint32_t AddWatchpoint(uint32_t start_address, uint32_t end_address, bool track_reads, bool track_writes, bool break_on_access=false, const std::string &description="")
Add a memory watchpoint.
bool ExportHistoryToCSV(const std::string &filepath) const
Export access history to CSV.
std::vector< Watchpoint > GetAllWatchpoints() const
Get all watchpoints.
std::vector< AccessLog > GetHistory(uint32_t address, int max_entries=100) const
Get access history for a specific address.
void ClearAll()
Clear all watchpoints.
#define LOG_INFO(category, format,...)
Definition log.h:105
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22