2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
19 #define MAX_BREAK_POINTS 8
20 #define MAX_COMMAND_LENGTH 64
21 #define MAX_COMMAND_HISTORY 32
22 #define MAX_CPU_TRACE 1024
27 int status; // 0 = none, 1 = enabled, other = disabled
29 } table[MAX_BREAK_POINTS], stored[MAX_BREAK_POINTS];
34 class DEBUGGER : public DEVICE
39 void check_mem_break_points(break_point_t *bp, uint32_t addr, int length)
41 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
42 if(bp->table[i].status == 1) {
43 if(addr >= bp->table[i].addr && addr < bp->table[i].addr + length) {
44 bp->hit = now_suspended = true;
45 bp->hit_addr = bp->table[i].addr;
46 bp->restart = bp->table[i].check_point;
52 void check_io_break_points(break_point_t *bp, uint32_t addr)
54 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
55 if(bp->table[i].status == 1) {
56 if((addr & bp->table[i].mask) == (bp->table[i].addr & bp->table[i].mask)) {
57 bp->hit = now_suspended = true;
59 bp->restart = bp->table[i].check_point;
66 DEBUGGER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
68 memset(&bp, 0, sizeof(bp));
69 memset(&rbp, 0, sizeof(rbp));
70 memset(&wbp, 0, sizeof(wbp));
71 memset(&ibp, 0, sizeof(ibp));
72 memset(&obp, 0, sizeof(obp));
73 first_symbol = last_symbol = NULL;
74 my_tcscpy_s(file_path, _MAX_PATH, _T("debug.bin"));
75 now_debugging = now_going = now_suspended = now_waiting = false;
76 memset(history, 0, sizeof(history));
78 memset(cpu_trace, 0xff, sizeof(cpu_trace));
79 prev_cpu_trace = 0xffffffff;
81 set_device_name(_T("Debugger"));
90 void write_data8(uint32_t addr, uint32_t data)
92 check_mem_break_points(&wbp, addr, 1);
93 d_mem->write_data8(addr, data);
95 uint32_t read_data8(uint32_t addr)
97 check_mem_break_points(&rbp, addr, 1);
98 return d_mem->read_data8(addr);
100 void write_data16(uint32_t addr, uint32_t data)
102 check_mem_break_points(&wbp, addr, 2);
103 d_mem->write_data16(addr, data);
105 uint32_t read_data16(uint32_t addr)
107 check_mem_break_points(&rbp, addr, 2);
108 return d_mem->read_data16(addr);
110 void write_data32(uint32_t addr, uint32_t data)
112 check_mem_break_points(&wbp, addr, 4);
113 d_mem->write_data32(addr, data);
115 uint32_t read_data32(uint32_t addr)
117 check_mem_break_points(&rbp, addr, 4);
118 return d_mem->read_data32(addr);
120 void write_data8w(uint32_t addr, uint32_t data, int* wait)
122 check_mem_break_points(&wbp, addr, 1);
123 d_mem->write_data8w(addr, data, wait);
125 uint32_t read_data8w(uint32_t addr, int* wait)
127 check_mem_break_points(&rbp, addr, 1);
128 return d_mem->read_data8w(addr, wait);
130 void write_data16w(uint32_t addr, uint32_t data, int* wait)
132 check_mem_break_points(&wbp, addr, 2);
133 d_mem->write_data16w(addr, data, wait);
135 uint32_t read_data16w(uint32_t addr, int* wait)
137 check_mem_break_points(&rbp, addr, 2);
138 return d_mem->read_data16w(addr, wait);
140 void write_data32w(uint32_t addr, uint32_t data, int* wait)
142 check_mem_break_points(&wbp, addr, 4);
143 d_mem->write_data32w(addr, data, wait);
145 uint32_t read_data32w(uint32_t addr, int* wait)
147 check_mem_break_points(&rbp, addr, 4);
148 return d_mem->read_data32w(addr, wait);
150 uint32_t fetch_op(uint32_t addr, int *wait)
152 check_mem_break_points(&rbp, addr, 1);
153 return d_mem->fetch_op(addr, wait);
155 void write_io8(uint32_t addr, uint32_t data)
157 check_io_break_points(&obp, addr);
158 d_io->write_io8(addr, data);
160 uint32_t read_io8(uint32_t addr)
162 check_io_break_points(&ibp, addr);
163 return d_io->read_io8(addr);
165 void write_io16(uint32_t addr, uint32_t data)
167 check_io_break_points(&obp, addr);
168 d_io->write_io16(addr, data);
170 uint32_t read_io16(uint32_t addr)
172 check_io_break_points(&ibp, addr);
173 return d_io->read_io16(addr);
175 void write_io32(uint32_t addr, uint32_t data)
177 check_io_break_points(&obp, addr);
178 d_io->write_io32(addr, data);
180 uint32_t read_io32(uint32_t addr)
182 check_io_break_points(&ibp, addr);
183 return d_io->read_io32(addr);
185 void write_io8w(uint32_t addr, uint32_t data, int* wait)
187 check_io_break_points(&obp, addr);
188 d_io->write_io8w(addr, data, wait);
190 uint32_t read_io8w(uint32_t addr, int* wait)
192 check_io_break_points(&ibp, addr);
193 return d_io->read_io8w(addr, wait);
195 void write_io16w(uint32_t addr, uint32_t data, int* wait)
197 check_io_break_points(&obp, addr);
198 d_io->write_io16w(addr, data, wait);
200 uint32_t read_io16w(uint32_t addr, int* wait)
202 check_io_break_points(&ibp, addr);
203 return d_io->read_io16w(addr, wait);
205 void write_io32w(uint32_t addr, uint32_t data, int* wait)
207 check_io_break_points(&obp, addr);
208 d_io->write_io32w(addr, data, wait);
210 uint32_t read_io32w(uint32_t addr, int* wait)
212 check_io_break_points(&ibp, addr);
213 return d_io->read_io32w(addr, wait);
217 void set_context_mem(DEVICE* device)
221 void set_context_io(DEVICE* device)
225 void check_break_points(uint32_t addr)
227 check_mem_break_points(&bp, addr, 1);
229 void store_break_points()
231 memcpy( bp.stored, bp.table, sizeof( bp.table));
232 memcpy(rbp.stored, rbp.table, sizeof(rbp.table));
233 memcpy(wbp.stored, wbp.table, sizeof(wbp.table));
234 memcpy(ibp.stored, ibp.table, sizeof(ibp.table));
235 memcpy(obp.stored, obp.table, sizeof(obp.table));
236 memset( bp.table, 0, sizeof( bp.table));
237 memset(rbp.table, 0, sizeof(rbp.table));
238 memset(wbp.table, 0, sizeof(wbp.table));
239 memset(ibp.table, 0, sizeof(ibp.table));
240 memset(obp.table, 0, sizeof(obp.table));
242 void restore_break_points()
244 memcpy( bp.table, bp.stored, sizeof( bp.table));
245 memcpy(rbp.table, rbp.stored, sizeof(rbp.table));
246 memcpy(wbp.table, wbp.stored, sizeof(wbp.table));
247 memcpy(ibp.table, ibp.stored, sizeof(ibp.table));
248 memcpy(obp.table, obp.stored, sizeof(obp.table));
252 return (bp.hit || rbp.hit || wbp.hit || ibp.hit || obp.hit);
254 void add_symbol(uint32_t addr, const _TCHAR *name)
256 symbol_t *symbol = (symbol_t *)calloc(sizeof(symbol_t), 1);
258 symbol->name = (_TCHAR *)calloc(sizeof(_TCHAR), _tcslen(name) + 1);
259 my_tcscpy_s(symbol->name, _tcslen(name) + 1, name);
261 if(first_symbol == NULL) {
262 first_symbol = symbol;
264 last_symbol->next_symbol = symbol;
266 last_symbol = symbol;
268 void release_symbols()
270 for(symbol_t* symbol = first_symbol; symbol;) {
271 symbol_t *next_symbol = symbol->next_symbol;
272 if(symbol->name != NULL) {
276 symbol = next_symbol;
278 first_symbol = last_symbol = NULL;
280 void add_cpu_trace(uint32_t pc)
282 if(prev_cpu_trace != pc) {
283 cpu_trace[cpu_trace_ptr++] = prev_cpu_trace = pc;
284 cpu_trace_ptr &= (MAX_CPU_TRACE - 1);
287 break_point_t bp, rbp, wbp, ibp, obp;
288 symbol_t *first_symbol, *last_symbol;
289 _TCHAR file_path[_MAX_PATH];
290 bool now_debugging, now_going, now_suspended, now_waiting;
291 _TCHAR history[MAX_COMMAND_HISTORY][MAX_COMMAND_LENGTH + 1];
293 uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace;