OSDN Git Service

scrolling enabled. now opening demo screen is all displayed correctly.
[motonesemu/motonesemu.git] / emulator / debug.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <curses.h>
4 #include "tools.h"
5 #include "6502core.h"
6
7 #define MAXBUF  1024
8 #define BYTES_PER_LINE 16
9
10 extern int debug_mode;
11 void dump_6502(int full);
12 void dump_vram(unsigned short addr, int size);
13 void dump_mem(unsigned short addr, int size);
14 unsigned char vram_data_get(unsigned short addr);
15 unsigned char dbg_get_byte(unsigned short addr);
16 unsigned short dbg_get_short(unsigned short addr);
17 void dump_ppu_reg(void);
18 void d1_set(int on_off);
19 void d2_set(int on_off);
20 void d3_set(int on_off);
21 void d4_set(int on_off);
22
23 #define MAX_HISTORY     10
24
25 struct cmd_list {
26     struct dlist l;
27     char *cmd;
28 };
29
30 static struct cmd_list* debug_history;
31 //global variable.
32 unsigned short break_point;
33
34 static void print_debug(void) {
35     printf("   command:\n");
36     printf("            s: step\n");
37     printf("            c: continue\n");
38     printf("       b addr: set break point\n");
39     printf("               (break point can be set only 1 address.)\n");
40     printf("          del: delete break point\n");
41     printf("  m addr size: memory dump\n");
42     printf("         show: show registers\n");
43     printf("        pshow: show ppu registers\n");
44     printf("  v addr size: vram dump\n");
45     printf("  da addr size: disassemble\n");
46     printf("   d1 on/off: debug log level 1 (dump instruction on execution)\n");
47     printf("   d2 on/off: debug log level 2 (dump reg status for each instruction)\n");
48     printf("   d3 on/off: debug log level 3 (dump load/store data value)\n");
49     printf("   d4 on/off: debug log level 4 (dump vram data write)\n");
50     printf("            q: quit emulator\n");
51 }
52
53 #if 0
54 static int read_cmd(char* buf) {
55     char ch, *p;
56     p = buf;
57             
58     while(1) {
59         if (kbhit()) {
60             ch = getchar();
61             if ( ch  != '\n') {
62                 *p = ch;
63                 p++;
64                 printf("%c", ch);
65             }
66             else {
67                 printf("\n");
68                 break;
69             }
70         }
71     }
72     return strlen(buf);
73 }
74 #endif
75
76 int emu_debug(void) {
77     char buf[MAXBUF];
78
79     //pause_cpu_clock();
80     while (TRUE) {
81         /*
82         fflush(stdin);
83         fflush(stdout);
84         */
85         printf("motonesemu: ");
86         memset(buf, 0, sizeof(buf));
87         //read_cmd(buf);
88         scanf("%s", buf);
89
90         if (!strcmp(buf, "s")){
91             break;
92         }
93         else if (!strcmp(buf, "q")){
94             extern int critical_error;
95
96             printf("quit...\n");
97             debug_mode = FALSE;
98             critical_error = TRUE;
99             //raise(SIGINT);
100             return FALSE;
101         }
102         else if (!strcmp(buf, "c")){
103             debug_mode = FALSE;
104             break;
105         }
106         else if (!strcmp(buf, "show")){
107             dump_6502(TRUE);
108         }
109         else if (!strcmp(buf, "d1")){
110             scanf("%s", buf);
111             if (!strcmp(buf, "on")){
112                 d1_set(TRUE);
113             }
114             else if (!strcmp(buf, "off")){
115                 d1_set(FALSE);
116             }
117             else {
118                 printf("log parameter must be either [on] or [off].\n");
119             }
120         }
121         else if (!strcmp(buf, "d2")){
122             scanf("%s", buf);
123             if (!strcmp(buf, "on")){
124                 d2_set(TRUE);
125             }
126             else if (!strcmp(buf, "off")){
127                 d2_set(FALSE);
128             }
129             else {
130                 printf("d2 parameter must be either [on] or [off].\n");
131             }
132         }
133         else if (!strcmp(buf, "d3")){
134             scanf("%s", buf);
135             if (!strcmp(buf, "on")){
136                 d3_set(TRUE);
137             }
138             else if (!strcmp(buf, "off")){
139                 d3_set(FALSE);
140             }
141             else {
142                 printf("d3 parameter must be either [on] or [off].\n");
143             }
144         }
145         else if (!strcmp(buf, "d4")){
146             scanf("%s", buf);
147             if (!strcmp(buf, "on")){
148                 d4_set(TRUE);
149             }
150             else if (!strcmp(buf, "off")){
151                 d4_set(FALSE);
152             }
153             else {
154                 printf("d4 parameter must be either [on] or [off].\n");
155             }
156         }
157         else if (!strcmp(buf, "b")){
158             unsigned int val;
159             scanf("%x", &val);
160             break_point = val;
161         }
162         else if (!strcmp(buf, "del")){
163             break_point = 0;
164         }
165         else if (!strcmp(buf, "m")){
166             unsigned int addr;
167             int size;
168             scanf("%x", &addr);
169             scanf("%d", &size);
170             dump_mem(addr, size);
171         }
172         else if (!strcmp(buf, "v")){
173             unsigned int addr;
174             int size;
175             scanf("%x", &addr);
176             scanf("%d", &size);
177             dump_vram(addr, size);
178         }
179         else if (!strcmp(buf, "da")){
180             unsigned int addr;
181             int size;
182             int disas_inst(unsigned short addr);
183             scanf("%x", &addr);
184             scanf("%d", &size);
185             while (size > 0) {
186                 int l = disas_inst(addr);
187                 if (l == 0) {
188                     printf("...(not an instruction)\n");
189                     dump_mem(addr, size);
190                     break;
191                 }
192                 size -= l;
193                 addr += l;
194             }
195         }
196         else if (!strcmp(buf, "pshow")){
197             dump_ppu_reg();
198         }
199         else {
200             printf("unknown command [%s].\n", buf);
201             print_debug();
202         }
203     }
204     //start_cpu_clock();
205     return TRUE;
206 }
207
208 void disasm(const char* mnemonic, int addr_mode, unsigned short pc) {
209
210     switch(addr_mode) {
211         case ADDR_MODE_ZP:
212             printf("%04x: %02x %02x       %-5s $%02x\n", pc, 
213                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
214                     mnemonic, dbg_get_byte(pc + 1));
215             break;
216         case ADDR_MODE_ZP_X:
217             printf("%04x: %02x %02x       %-5s $%02x, x\n", pc, 
218                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
219                     mnemonic, dbg_get_byte(pc + 1));
220             break;
221         case ADDR_MODE_ZP_Y:
222             printf("%04x: %02x %02x       %-5s $%02x, y\n", pc, 
223                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
224                     mnemonic, dbg_get_byte(pc + 1));
225             break;
226         case ADDR_MODE_ABS:
227             printf("%04x: %02x %02x %02x    %-5s $%04x\n", pc, 
228                     dbg_get_byte(pc), dbg_get_byte(pc + 1), dbg_get_byte(pc + 2), 
229                     mnemonic, dbg_get_short(pc + 1));
230             break;
231         case ADDR_MODE_ABS_X:
232             printf("%04x: %02x %02x %02x    %-5s $%04x, x\n", pc, 
233                     dbg_get_byte(pc), dbg_get_byte(pc + 1), dbg_get_byte(pc + 2), 
234                     mnemonic, dbg_get_short(pc + 1));
235             break;
236         case ADDR_MODE_ABS_Y:
237             printf("%04x: %02x %02x %02x    %-5s $%04x, y\n", pc, 
238                     dbg_get_byte(pc), dbg_get_byte(pc + 1), dbg_get_byte(pc + 2), 
239                     mnemonic, dbg_get_short(pc + 1));
240             break;
241         case ADDR_MODE_IND:
242             printf("%04x: %02x %02x       %-5s ($%04x)\n", pc, 
243                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
244                     mnemonic, dbg_get_short(pc + 1));
245             break;
246         case ADDR_MODE_IMP:
247         case ADDR_MODE_ACC:
248             printf("%04x: %02x          %-5s \n", pc, 
249                     dbg_get_byte(pc), 
250                     mnemonic);
251             break;
252         case ADDR_MODE_IMM:
253             printf("%04x: %02x %02x       %-5s #$%02x\n", pc, 
254                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
255                     mnemonic, dbg_get_byte(pc + 1));
256             break;
257         case ADDR_MODE_REL:
258             printf("%04x: %02x %02x       %-5s #%+d\n", pc, 
259                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
260                     mnemonic, (char)dbg_get_byte(pc + 1));
261             break;
262         case ADDR_MODE_INDEX_INDIR:
263             printf("%04x: %02x %02x       %-5s ($%02x, x), y\n", pc, 
264                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
265                     mnemonic, dbg_get_byte(pc + 1));
266             break;
267         case ADDR_MODE_INDIR_INDEX:
268             printf("%04x: %02x %02x       %-5s ($%02x), y\n", pc, 
269                     dbg_get_byte(pc), dbg_get_byte(pc + 1), 
270                     mnemonic, dbg_get_byte(pc + 1));
271             break;
272     }
273 }
274
275 void dump_vram(unsigned short addr, int size) {
276     int i;
277
278     if (addr % BYTES_PER_LINE)
279         printf("%04x: ", addr % BYTES_PER_LINE);
280
281     for (i = 0; i < addr % BYTES_PER_LINE; i++) {
282         printf("   ");
283     }
284     for (i = 0; i < size; i++) {
285         if (addr % BYTES_PER_LINE == 0)
286             printf("%04x: ", addr);
287
288         printf("%02x ", vram_data_get(addr));
289
290         if (addr % BYTES_PER_LINE == (BYTES_PER_LINE / 2) - 1)
291             printf("  ");
292
293         if (addr % BYTES_PER_LINE == (BYTES_PER_LINE - 1))
294             printf("\n");
295
296         addr++;
297     }
298     printf("\n");
299 }
300
301 void dump_mem(unsigned short addr, int size) {
302     int i;
303     unsigned char vram_data_get(unsigned short addr);
304
305     if (addr % BYTES_PER_LINE)
306         printf("%04x: ", addr);
307
308     for (i = 0; i < addr % BYTES_PER_LINE; i++) {
309         printf("   ");
310         if (i % BYTES_PER_LINE == (BYTES_PER_LINE / 2) - 1)
311             printf("  ");
312     }
313     for (i = 0; i < size; i++) {
314         if (addr % BYTES_PER_LINE == 0)
315             printf("%04x: ", addr);
316
317         printf("%02x ", dbg_get_byte(addr));
318
319         if (addr % BYTES_PER_LINE == (BYTES_PER_LINE / 2) - 1)
320             printf("  ");
321
322         if (addr % BYTES_PER_LINE == (BYTES_PER_LINE - 1))
323             printf("\n");
324
325         addr++;
326     }
327     printf("\n");
328 }
329
330 void break_hit(void) {
331     printf("------------------\nbreak...\n");
332     debug_mode = TRUE;
333     dump_6502(TRUE);
334 }
335
336
337 int init_debug(void) {
338     //dprint("init debug..\n");
339     debug_history = NULL;
340     break_point = 0;
341     //initscr();          /* Start curses mode          */
342
343     return TRUE;
344 }
345
346 void clean_debug(void) {
347     //dprint("clean debug..\n");
348     //endwin();           /* End curses mode        */
349 }
350