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
28 } table[MAX_BREAK_POINTS], stored[MAX_BREAK_POINTS];
33 class DEBUGGER : public DEVICE
38 void check_mem_break_points(break_point_t *bp, uint32_t addr, int length)
40 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
41 if(bp->table[i].status == 1) {
42 if(addr >= bp->table[i].addr && addr < bp->table[i].addr + length) {
43 bp->hit = now_suspended = true;
44 bp->hit_addr = bp->table[i].addr;
50 void check_io_break_points(break_point_t *bp, uint32_t addr)
52 for(int i = 0; i < MAX_BREAK_POINTS; i++) {
53 if(bp->table[i].status == 1) {
54 if((addr & bp->table[i].mask) == (bp->table[i].addr & bp->table[i].mask)) {
55 bp->hit = now_suspended = true;
63 DEBUGGER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
65 memset(&bp, 0, sizeof(bp));
66 memset(&rbp, 0, sizeof(rbp));
67 memset(&wbp, 0, sizeof(wbp));
68 memset(&ibp, 0, sizeof(ibp));
69 memset(&obp, 0, sizeof(obp));
70 first_symbol = last_symbol = NULL;
71 my_tcscpy_s(file_path, _MAX_PATH, _T("debug.bin"));
72 now_debugging = now_going = now_suspended = now_waiting = false;
73 memset(history, 0, sizeof(history));
75 memset(cpu_trace, 0xff, sizeof(cpu_trace));
76 prev_cpu_trace = 0xffffffff;
78 set_device_name(_T("Debugger"));
87 void write_data8(uint32_t addr, uint32_t data)
89 check_mem_break_points(&wbp, addr, 1);
90 d_mem->write_data8(addr, data);
92 uint32_t read_data8(uint32_t addr)
94 check_mem_break_points(&rbp, addr, 1);
95 return d_mem->read_data8(addr);
97 void write_data16(uint32_t addr, uint32_t data)
99 check_mem_break_points(&wbp, addr, 2);
100 d_mem->write_data16(addr, data);
102 uint32_t read_data16(uint32_t addr)
104 check_mem_break_points(&rbp, addr, 2);
105 return d_mem->read_data16(addr);
107 void write_data32(uint32_t addr, uint32_t data)
109 check_mem_break_points(&wbp, addr, 4);
110 d_mem->write_data32(addr, data);
112 uint32_t read_data32(uint32_t addr)
114 check_mem_break_points(&rbp, addr, 4);
115 return d_mem->read_data32(addr);
117 void write_data8w(uint32_t addr, uint32_t data, int* wait)
119 check_mem_break_points(&wbp, addr, 1);
120 d_mem->write_data8w(addr, data, wait);
122 uint32_t read_data8w(uint32_t addr, int* wait)
124 check_mem_break_points(&rbp, addr, 1);
125 return d_mem->read_data8w(addr, wait);
127 void write_data16w(uint32_t addr, uint32_t data, int* wait)
129 check_mem_break_points(&wbp, addr, 2);
130 d_mem->write_data16w(addr, data, wait);
132 uint32_t read_data16w(uint32_t addr, int* wait)
134 check_mem_break_points(&rbp, addr, 2);
135 return d_mem->read_data16w(addr, wait);
137 void write_data32w(uint32_t addr, uint32_t data, int* wait)
139 check_mem_break_points(&wbp, addr, 4);
140 d_mem->write_data32w(addr, data, wait);
142 uint32_t read_data32w(uint32_t addr, int* wait)
144 check_mem_break_points(&rbp, addr, 4);
145 return d_mem->read_data32w(addr, wait);
147 uint32_t fetch_op(uint32_t addr, int *wait)
149 check_mem_break_points(&rbp, addr, 1);
150 return d_mem->fetch_op(addr, wait);
152 void write_io8(uint32_t addr, uint32_t data)
154 check_io_break_points(&obp, addr);
155 d_io->write_io8(addr, data);
157 uint32_t read_io8(uint32_t addr)
159 check_io_break_points(&ibp, addr);
160 return d_io->read_io8(addr);
162 void write_io16(uint32_t addr, uint32_t data)
164 check_io_break_points(&obp, addr);
165 d_io->write_io16(addr, data);
167 uint32_t read_io16(uint32_t addr)
169 check_io_break_points(&ibp, addr);
170 return d_io->read_io16(addr);
172 void write_io32(uint32_t addr, uint32_t data)
174 check_io_break_points(&obp, addr);
175 d_io->write_io32(addr, data);
177 uint32_t read_io32(uint32_t addr)
179 check_io_break_points(&ibp, addr);
180 return d_io->read_io32(addr);
182 void write_io8w(uint32_t addr, uint32_t data, int* wait)
184 check_io_break_points(&obp, addr);
185 d_io->write_io8w(addr, data, wait);
187 uint32_t read_io8w(uint32_t addr, int* wait)
189 check_io_break_points(&ibp, addr);
190 return d_io->read_io8w(addr, wait);
192 void write_io16w(uint32_t addr, uint32_t data, int* wait)
194 check_io_break_points(&obp, addr);
195 d_io->write_io16w(addr, data, wait);
197 uint32_t read_io16w(uint32_t addr, int* wait)
199 check_io_break_points(&ibp, addr);
200 return d_io->read_io16w(addr, wait);
202 void write_io32w(uint32_t addr, uint32_t data, int* wait)
204 check_io_break_points(&obp, addr);
205 d_io->write_io32w(addr, data, wait);
207 uint32_t read_io32w(uint32_t addr, int* wait)
209 check_io_break_points(&ibp, addr);
210 return d_io->read_io32w(addr, wait);
214 void set_context_mem(DEVICE* device)
218 void set_context_io(DEVICE* device)
222 void check_break_points(uint32_t addr)
224 check_mem_break_points(&bp, addr, 1);
226 void store_break_points()
228 memcpy( bp.stored, bp.table, sizeof( bp.table));
229 memcpy(rbp.stored, rbp.table, sizeof(rbp.table));
230 memcpy(wbp.stored, wbp.table, sizeof(wbp.table));
231 memcpy(ibp.stored, ibp.table, sizeof(ibp.table));
232 memcpy(obp.stored, obp.table, sizeof(obp.table));
233 memset( bp.table, 0, sizeof( bp.table));
234 memset(rbp.table, 0, sizeof(rbp.table));
235 memset(wbp.table, 0, sizeof(wbp.table));
236 memset(ibp.table, 0, sizeof(ibp.table));
237 memset(obp.table, 0, sizeof(obp.table));
239 void restore_break_points()
241 memcpy( bp.table, bp.stored, sizeof( bp.table));
242 memcpy(rbp.table, rbp.stored, sizeof(rbp.table));
243 memcpy(wbp.table, wbp.stored, sizeof(wbp.table));
244 memcpy(ibp.table, ibp.stored, sizeof(ibp.table));
245 memcpy(obp.table, obp.stored, sizeof(obp.table));
249 return (bp.hit || rbp.hit || wbp.hit || ibp.hit || obp.hit);
251 void add_symbol(uint32_t addr, const _TCHAR *name)
253 symbol_t *symbol = (symbol_t *)calloc(sizeof(symbol_t), 1);
255 symbol->name = (_TCHAR *)calloc(sizeof(_TCHAR), _tcslen(name) + 1);
256 my_tcscpy_s(symbol->name, _tcslen(name) + 1, name);
258 if(first_symbol == NULL) {
259 first_symbol = symbol;
261 last_symbol->next_symbol = symbol;
263 last_symbol = symbol;
265 void release_symbols()
267 for(symbol_t* symbol = first_symbol; symbol;) {
268 symbol_t *next_symbol = symbol->next_symbol;
269 if(symbol->name != NULL) {
273 symbol = next_symbol;
275 first_symbol = last_symbol = NULL;
277 void add_cpu_trace(uint32_t pc)
279 if(prev_cpu_trace != pc) {
280 cpu_trace[cpu_trace_ptr++] = prev_cpu_trace = pc;
281 cpu_trace_ptr &= (MAX_CPU_TRACE - 1);
284 break_point_t bp, rbp, wbp, ibp, obp;
285 symbol_t *first_symbol, *last_symbol;
286 _TCHAR file_path[_MAX_PATH];
287 bool now_debugging, now_going, now_suspended, now_waiting;
288 _TCHAR history[MAX_COMMAND_HISTORY][MAX_COMMAND_LENGTH + 1];
290 uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace;