|
|
1.1 root 1: /*
1.1.1.6 root 2: Hatari - debugui.c
1.1 root 3:
1.1.1.4 root 4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
1.1.1.6 root 7: debugui.c - this is the code for the mini-debugger. When the pause button is
8: pressed, the emulator is (hopefully) halted and this little CLI can be used
9: (in the terminal box) for debugging tasks like memory and register dumps.
1.1 root 10: */
1.1.1.10! root 11: const char DebugUI_fileid[] = "Hatari debugui.c : " __DATE__ " " __TIME__;
1.1 root 12:
13: #include <ctype.h>
1.1.1.8 root 14: #include <stdio.h>
15:
16: #include "config.h"
17:
18: #if HAVE_LIBREADLINE
19: #include <readline/readline.h>
20: #include <readline/history.h>
21: #endif
1.1 root 22:
23: #include "main.h"
1.1.1.9 root 24: #include "change.h"
1.1 root 25: #include "configuration.h"
1.1.1.9 root 26: #include "file.h"
1.1 root 27: #include "reset.h"
28: #include "m68000.h"
1.1.1.9 root 29: #include "str.h"
1.1.1.3 root 30: #include "stMemory.h"
1.1 root 31: #include "sound.h"
32: #include "tos.h"
1.1.1.4 root 33: #include "debugui.h"
1.1 root 34:
1.1.1.8 root 35: #include "hatari-glue.h"
1.1 root 36:
37: #define MEMDUMP_COLS 16 /* memdump, number of bytes per row */
38: #define MEMDUMP_ROWS 4 /* memdump, number of rows */
1.1.1.2 root 39: #define NON_PRINT_CHAR '.' /* character to display for non-printables */
1.1 root 40: #define DISASM_INSTS 5 /* disasm - number of instructions */
41:
1.1.1.9 root 42: static bool bMemDump; /* has memdump been called? */
1.1.1.6 root 43: static unsigned long memdump_addr; /* memdump address */
44: static unsigned long disasm_addr; /* disasm address */
45:
1.1.1.9 root 46: static FILE *debugOutput;
1.1.1.2 root 47:
48:
1.1.1.6 root 49:
50: /*-----------------------------------------------------------------------*/
1.1.1.8 root 51: /**
52: * Get a hex adress range, eg. "fa0000-fa0100"
53: * returns -1 if not a range,
54: * -2 if a range, but not a valid one.
55: * 0 if OK.
56: */
1.1.1.9 root 57: static int getRange(char *str, unsigned long *lower, unsigned long *upper)
1.1.1.6 root 58: {
1.1.1.9 root 59: bool fDash = FALSE;
1.1.1.6 root 60: int i=0;
61:
62: while (str[i] != '\0')
63: {
64: if (str[i] == '-')
65: {
66: str[i] = ' ';
67: fDash = TRUE;
68: }
69: i++;
70: }
71: if (fDash == FALSE)
72: return -1;
73:
74: i = sscanf(str, "%lx%lx", lower, upper);
75: if (i != 2)
76: return -2;
77: if (*lower > *upper)
78: return -3;
79: return 0;
80: }
81:
82:
1.1.1.2 root 83: /*-----------------------------------------------------------------------*/
1.1.1.8 root 84: /**
1.1.1.9 root 85: * Open given log file.
1.1.1.8 root 86: */
1.1.1.9 root 87: static void DebugUI_SetLogFile(const char *logpath)
1.1.1.6 root 88: {
1.1.1.9 root 89: File_Close(debugOutput);
90: debugOutput = File_Open(logpath, "w");
91: if (debugOutput)
92: fprintf(stderr, "Debug log '%s' opened\n", logpath);
93: else
94: debugOutput = stderr;
95: }
96:
97:
98: /*-----------------------------------------------------------------------*/
99: /**
100: * Close a log file if open, and set it to default stream.
101: */
102: static void DebugUI_SetLogDefault(void)
103: {
104: if (debugOutput != stderr)
105: {
106: if (debugOutput)
107: {
108: File_Close(debugOutput);
109: fprintf(stderr, "Debug log closed.\n");
110: }
111: debugOutput = stderr;
112: }
1.1.1.2 root 113: }
114:
1.1.1.6 root 115:
1.1 root 116: /*-----------------------------------------------------------------------*/
1.1.1.8 root 117: /**
118: * Load a binary file to a memory address.
119: */
1.1.1.6 root 120: static void DebugUI_LoadBin(char *args)
121: {
122: FILE *fp;
123: unsigned char c;
124: char dummy[100];
125: char filename[200];
126: unsigned long address;
127: int i=0;
128:
129: if (sscanf(args, "%s%s%lx", dummy, filename, &address) != 3)
130: {
131: fprintf(stderr, "Invalid arguments!\n");
132: return;
133: }
134: address &= 0x00FFFFFF;
135: if ((fp = fopen(filename, "rb")) == NULL)
136: {
137: fprintf(stderr,"Cannot open file!\n");
138: }
139:
140: c = fgetc(fp);
141: while (!feof(fp))
142: {
143: i++;
144: STMemory_WriteByte(address++, c);
145: c = fgetc(fp);
146: }
147: fprintf(stderr," Read 0x%x bytes.\n", i);
148: fclose(fp);
1.1 root 149: }
150:
1.1.1.6 root 151:
1.1 root 152: /*-----------------------------------------------------------------------*/
1.1.1.8 root 153: /**
154: * Dump memory from an address to a binary file.
155: */
1.1.1.6 root 156: static void DebugUI_SaveBin(char *args)
157: {
158: FILE *fp;
159: unsigned char c;
160: char filename[200];
161: char dummy[100];
162: unsigned long address;
163: unsigned long bytes, i=0;
164:
165: if (sscanf(args, "%s%s%lx%lx", dummy, filename, &address, &bytes) != 4)
166: {
1.1.1.9 root 167: fprintf(stderr, " Invalid arguments!\n");
1.1.1.6 root 168: return;
169: }
170: address &= 0x00FFFFFF;
171: if ((fp = fopen(filename, "wb")) == NULL)
172: {
173: fprintf(stderr," Cannot open file!\n");
174: }
175:
176: while (i < bytes)
177: {
178: c = STMemory_ReadByte(address++);
179: fputc(c, fp);
180: i++;
181: }
182: fclose(fp);
183: fprintf(stderr, " Wrote 0x%lx bytes.\n", bytes);
1.1 root 184: }
185:
1.1.1.6 root 186:
1.1 root 187: /*-----------------------------------------------------------------------*/
1.1.1.8 root 188: /**
189: * Do a register dump.
190: */
1.1.1.4 root 191: static void DebugUI_RegDump(void)
1.1 root 192: {
1.1.1.6 root 193: uaecptr nextpc;
194: /* use the UAE function instead */
1.1.1.9 root 195: m68k_dumpstate(debugOutput, &nextpc);
196: fflush(debugOutput);
1.1 root 197: }
198:
199:
200: /*-----------------------------------------------------------------------*/
1.1.1.8 root 201: /**
202: * Dissassemble - arg = starting address, or PC.
203: */
1.1.1.9 root 204: static void DebugUI_DisAsm(char *arg, bool cont)
1.1.1.6 root 205: {
206: int i,j;
207: unsigned long disasm_upper;
208: uaecptr nextpc;
1.1.1.9 root 209: bool isRange = FALSE;
1.1.1.6 root 210:
211: if (cont != TRUE)
212: {
213: j = getRange(arg, &disasm_addr, &disasm_upper);
214:
215: if (j == -1)
216: { /* single address, not a range */
1.1.1.9 root 217: if (!Str_IsHex(arg))
1.1.1.6 root 218: {
219: fprintf(stderr,"Invalid address!\n");
220: return;
221: }
222: i = sscanf(arg, "%lx", &disasm_addr);
223:
224: if (i == 0)
225: {
226: fprintf(stderr,"Invalid address!\n");
227: return;
228: }
229: } /* single address */
230: else if (j == -2 || j == -3)
231: {
232: fprintf(stderr,"Invalid range!\n");
233: return;
234: }
235: else
236: { /* range */
237: isRange = TRUE;
238: disasm_upper &= 0x00FFFFFF;
239: }
240: }
241: else /* continue*/
242: if(!disasm_addr)
1.1.1.8 root 243: disasm_addr = M68000_GetPC();
1.1.1.6 root 244:
245: disasm_addr &= 0x00FFFFFF;
246:
247: /* output a single block. */
248: if (isRange == FALSE)
249: {
1.1.1.9 root 250: m68k_disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, DISASM_INSTS);
1.1.1.6 root 251: disasm_addr = nextpc;
1.1.1.9 root 252: fflush(debugOutput);
1.1.1.6 root 253: return;
254: }
255:
256: /* output a range */
257: while (disasm_addr < disasm_upper)
258: {
1.1.1.9 root 259: m68k_disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1);
1.1.1.6 root 260: disasm_addr = nextpc;
261: }
1.1.1.9 root 262: fflush(debugOutput);
1.1.1.2 root 263: }
264:
1.1.1.6 root 265:
1.1.1.2 root 266: /*-----------------------------------------------------------------------*/
1.1.1.8 root 267: /**
268: * Set a register:
269: */
1.1.1.6 root 270: static void DebugUI_RegSet(char *arg)
271: {
272: int i;
1.1.1.9 root 273: bool s = FALSE;
1.1.1.6 root 274: char reg[4];
275: long value;
276:
277: for (i=0;i<4;i++)
278: reg[i] = 0;
279: i=0;
280: while (arg[i] != '\0')
281: {
282: if(arg[i] == '=')
283: {
284: arg[i] = ' ';
285: s = TRUE;
286: }
287: i++;
288: }
289:
290: if (s == FALSE)
291: {
292: fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR and yyyy is a hex value.\n");
293: return;
294: }
295:
296: if (sscanf(arg, "%s%lx", reg, &value) == 2)
297: s = TRUE;
298: else
299: s = FALSE;
300: if (s == FALSE)
301: {
302: fprintf(stderr,"\tError, usage: r or r xx=yyyy\n\tWhere: xx=A0-A7, D0-D7, PC or SR and yyyy is a hex value.\n");
303: return;
304: }
1.1.1.2 root 305:
1.1.1.6 root 306: for (i=0;i<4;i++)
307: reg[i] = toupper(reg[i]);
308:
309: /* set SR and update conditional flags for the UAE CPU core. */
310: if (reg[0] == 'S' && reg[1] == 'R')
311: {
1.1.1.8 root 312: M68000_SetSR(value);
1.1.1.6 root 313: }
314: else if (reg[0] == 'P' && reg[1] == 'C') /* set PC? */
315: {
1.1.1.8 root 316: M68000_SetPC(value);
1.1.1.6 root 317: }
318: else if (reg[0] == 'D') /* Data regs? */
319: {
320: switch (reg[1])
321: {
322: case '0':
323: Regs[REG_D0] = value;
324: break;
325: case '1':
326: Regs[REG_D1] = value;
327: break;
328: case '2':
329: Regs[REG_D2] = value;
330: break;
331: case '3':
332: Regs[REG_D3] = value;
333: break;
334: case '4':
335: Regs[REG_D4] = value;
336: break;
337: case '5':
338: Regs[REG_D5] = value;
339: break;
340: case '6':
341: Regs[REG_D6] = value;
342: break;
343: case '7':
344: Regs[REG_D7] = value;
345: break;
346:
347: default:
348: fprintf(stderr,"\tBad data register, valid values are 0-7\n");
349: break;
350: }
351: }
352: else if(reg[0] == 'A') /* Address regs? */
353: {
354: switch( reg[1] )
355: {
356: case '0':
357: Regs[REG_A0] = value;
358: break;
359: case '1':
360: Regs[REG_A1] = value;
361: break;
362: case '2':
363: Regs[REG_A2] = value;
364: break;
365: case '3':
366: Regs[REG_A3] = value;
367: break;
368: case '4':
369: Regs[REG_A4] = value;
370: break;
371: case '5':
372: Regs[REG_A5] = value;
373: break;
374: case '6':
375: Regs[REG_A6] = value;
376: break;
377: case '7':
378: Regs[REG_A7] = value;
379: break;
380:
381: default:
382: fprintf(stderr,"\tBad address register, valid values are 0-7\n");
383: break;
384: }
385: }
386: else
387: {
388: fprintf(stderr, "\t Bad register!\n");
389: }
1.1 root 390: }
391:
1.1.1.6 root 392:
1.1 root 393: /*-----------------------------------------------------------------------*/
1.1.1.8 root 394: /**
395: * Do a memory dump, args = starting address.
396: */
1.1.1.9 root 397: static void DebugUI_MemDump(char *arg, bool cont)
1.1.1.6 root 398: {
399: int i,j;
400: char c;
1.1.1.9 root 401: bool isRange = FALSE;
1.1.1.6 root 402: unsigned long memdump_upper;
1.1.1.2 root 403:
1.1.1.6 root 404: if (cont != TRUE)
405: {
406: j = getRange(arg, &memdump_addr, &memdump_upper);
407:
408: if (j == -1)
409: { /* single address, not a range */
1.1.1.9 root 410: if (!Str_IsHex(arg))
1.1.1.6 root 411: {
412: bMemDump = FALSE;
413: fprintf(stderr, "Invalid address!\n");
414: return;
415: }
416: i = sscanf(arg, "%lx", &memdump_addr);
417:
418: if (i == 0)
419: {
420: bMemDump = FALSE;
421: fprintf(stderr, "Invalid address!\n");
422: return;
423: }
424: } /* single address */
425: else if (j == -2 || j == -3)
426: {
427: fprintf(stderr, "Invalid range!\n");
428: return;
429: }
430: else
431: { /* range */
432: isRange = TRUE;
433: memdump_upper &= 0x00FFFFFF;
434: }
435: } /* continue */
436:
437: memdump_addr &= 0x00FFFFFF;
438: bMemDump = TRUE;
439:
440: if (isRange != TRUE)
441: {
442: for (j=0;j<MEMDUMP_ROWS;j++)
443: {
1.1.1.9 root 444: fprintf(debugOutput, "%6.6lX: ", memdump_addr); /* print address */
1.1.1.6 root 445: for (i = 0; i < MEMDUMP_COLS; i++) /* print hex data */
1.1.1.9 root 446: fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++));
447: fprintf(debugOutput, " "); /* print ASCII data */
1.1.1.6 root 448: for (i = 0; i < MEMDUMP_COLS; i++)
449: {
450: c = STMemory_ReadByte(memdump_addr-MEMDUMP_COLS+i);
1.1.1.8 root 451: if (!isprint((unsigned)c))
1.1.1.6 root 452: c = NON_PRINT_CHAR; /* non-printable as dots */
1.1.1.9 root 453: fprintf(debugOutput,"%c", c);
1.1.1.6 root 454: }
1.1.1.9 root 455: fprintf(debugOutput, "\n"); /* newline */
1.1.1.6 root 456: }
1.1.1.9 root 457: fflush(debugOutput);
1.1.1.6 root 458: return;
459: } /* not a range */
460:
461: while (memdump_addr < memdump_upper)
462: {
1.1.1.9 root 463: fprintf(debugOutput, "%6.6lX: ", memdump_addr); /* print address */
1.1.1.6 root 464: for (i = 0; i < MEMDUMP_COLS; i++) /* print hex data */
1.1.1.9 root 465: fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++));
466: fprintf(debugOutput, " "); /* print ASCII data */
1.1.1.6 root 467: for (i = 0; i < MEMDUMP_COLS; i++)
468: {
469: c = STMemory_ReadByte(memdump_addr-MEMDUMP_COLS+i);
1.1.1.8 root 470: if(!isprint((unsigned)c))
1.1.1.6 root 471: c = NON_PRINT_CHAR; /* non-printable as dots */
1.1.1.9 root 472: fprintf(debugOutput,"%c", c);
1.1.1.6 root 473: }
1.1.1.9 root 474: fprintf(debugOutput, "\n"); /* newline */
1.1.1.6 root 475: } /* while */
1.1.1.9 root 476: fflush(debugOutput);
1.1.1.2 root 477: } /* end of memdump */
1.1 root 478:
1.1.1.6 root 479:
1.1 root 480: /*-----------------------------------------------------------------------*/
1.1.1.8 root 481: /**
482: * Do a memory write, arg = starting address, followed by bytes.
483: */
484: static void DebugUI_MemWrite(char *arg)
1.1 root 485: {
1.1.1.6 root 486: int i, j, numBytes;
487: long write_addr;
488: unsigned char bytes[300]; /* store bytes */
489: char temp[15];
490: int d;
491:
492: numBytes = 0;
493: i = 0;
494:
1.1.1.9 root 495: Str_Trunc(arg);
1.1.1.6 root 496: while (arg[i] == ' ')
497: i++; /* skip spaces */
498: while (arg[i] != ' ')
499: i++; /* skip command */
500: while (arg[i] == ' ')
501: i++; /* skip spaces */
502:
503: j = 0;
1.1.1.8 root 504: while (isxdigit((unsigned)arg[i]) && j < 14) /* get address */
1.1.1.6 root 505: temp[j++] = arg[i++];
506: temp[j] = '\0';
507: j = sscanf(temp, "%lx", &write_addr);
508:
509: /* if next char is not valid, or it's not a valid address */
510: if ((arg[i] != '\0' && arg[i] != ' ') || (j == 0))
511: {
512: fprintf(stderr, "Bad address!\n");
513: return;
514: }
515:
516: write_addr &= 0x00FFFFFF;
517:
518: while (arg[i] == ' ')
519: i++; /* skip spaces */
520:
521: /* get bytes data */
522: while (arg[i] != '\0')
523: {
524: j = 0;
1.1.1.8 root 525: while(isxdigit((unsigned)arg[i]) && j < 14) /* get byte */
1.1.1.6 root 526: temp[j++] = arg[i++];
527: temp[j] = '\0';
528:
529: /* if next char is not a null or a space - it's not valid. */
530: if (arg[i] != '\0' && arg[i] != ' ')
531: {
532: fprintf(stderr, "Bad byte argument: %c\n", arg[i]);
533: return;
534: }
535:
536: if (temp[0] != '\0')
537: {
538: if (sscanf(temp,"%x", &d) != 1)
539: {
540: fprintf(stderr, "Bad byte argument!\n");
541: return;
542: }
543: }
544:
545: bytes[numBytes] = (d&0x0FF);
546: numBytes++;
547: while (arg[i] == ' ')
548: i++; /* skip any spaces */
549: }
550:
551: /* write the data */
552: for (i = 0; i < numBytes; i++)
553: STMemory_WriteByte(write_addr + i, bytes[i]);
1.1 root 554: }
555:
1.1.1.6 root 556:
1.1 root 557: /*-----------------------------------------------------------------------*/
1.1.1.8 root 558: /**
559: * Print help.
560: */
1.1.1.4 root 561: static void DebugUI_Help(void)
1.1 root 562: {
1.1.1.6 root 563: fprintf(stderr, "---- debug mode commands ----\n"
564: " d [address]- disassemble from PC, or given address. \n"
565: " r [REG=value] - dump register values/ set register to value \n"
566: " m [address] - dump memory at address, \n\tm alone continues from previous address.\n"
567: " w address bytes - write bytes to a memory address, bytes are space separated. \n"
568: " f [filename] - open log file, no argument closes the log file\n"
569: " Output of reg & mem dumps and disassembly will be written to the log\n"
570: " l filename address - load a file into memory starting at address. \n"
571: " s filename address length - dump length bytes from memory to a file. \n"
1.1.1.9 root 572: " o [command line] - set Hatari command line options\n\n"
1.1.1.8 root 573: " q - quit emulator\n"
574: " c - continue emulation\n\n"
1.1.1.6 root 575: " Adresses may be given as a range e.g. fc0000-fc0100\nAll values in hexadecimal.\n"
576: "-----------------------------\n"
577: "\n");
1.1 root 578: }
579:
1.1.1.9 root 580:
1.1 root 581: /*-----------------------------------------------------------------------*/
1.1.1.8 root 582: /**
1.1.1.9 root 583: * Parse and return debug command.
1.1.1.8 root 584: */
1.1.1.9 root 585: int DebugUI_ParseCommand(char *input)
1.1.1.6 root 586: {
587: char command[255], arg[255];
1.1.1.8 root 588: static char lastcommand = 0;
1.1.1.9 root 589: int i, retval;
1.1.1.6 root 590:
1.1.1.9 root 591: /* Used for 'm' and 'd' to continue at last pos */
592: command[0] = lastcommand;
1.1.1.8 root 593: command[1] = 0;
594: arg[0] = 0;
1.1.1.9 root 595: i = sscanf(input, "%s%s", command, arg);
596: Str_ToLower(command);
1.1 root 597:
1.1.1.6 root 598: if (i == 0)
599: {
600: fprintf(stderr, " Unknown command.\n");
601: return DEBUG_CMD;
602: }
1.1.1.9 root 603: if (!debugOutput) {
604: DebugUI_SetLogDefault();
605: }
1.1.1.6 root 606:
1.1.1.8 root 607: lastcommand = 0;
608: retval = DEBUG_CMD; /* Default return value */
609:
1.1.1.6 root 610: switch (command[0])
611: {
1.1.1.8 root 612: case 'c':
613: retval = DEBUG_QUIT;
614: break;
615:
1.1.1.6 root 616: case 'q':
1.1.1.8 root 617: bQuitProgram = TRUE;
618: M68000_SetSpecial(SPCFLAG_BRK); /* Assure that CPU core shuts down */
619: retval = DEBUG_QUIT;
1.1.1.6 root 620: break;
621:
622: case 'h':
623: case '?':
624: DebugUI_Help(); /* get help */
625: break;
626:
627: case 'o':
1.1.1.9 root 628: Change_ApplyCommandline(input+1);
1.1.1.6 root 629: break;
630:
631: case 'd':
632: if (i < 2) /* no arg? */
633: DebugUI_DisAsm(arg, TRUE); /* No arg - disassemble at PC */
634: else
635: DebugUI_DisAsm(arg, FALSE); /* disasm at address. */
1.1.1.8 root 636: lastcommand = 'd';
1.1.1.6 root 637: break;
638:
639: case 'm':
640: if (i < 2)
641: { /* no arg? */
642: if (bMemDump == FALSE)
643: fprintf(stderr," Usage: m address\n");
1.1.1.8 root 644: else
645: DebugUI_MemDump(arg, TRUE); /* No arg - continue memdump */
1.1.1.6 root 646: }
647: else
648: DebugUI_MemDump(arg, FALSE); /* new memdump */
1.1.1.8 root 649: lastcommand = 'm';
1.1.1.6 root 650: break;
651:
652: case 'f':
653: if (i < 2)
1.1.1.9 root 654: DebugUI_SetLogDefault();
1.1.1.6 root 655: else
1.1.1.9 root 656: DebugUI_SetLogFile(arg);
1.1.1.6 root 657: break;
658:
659: case 'w':
1.1.1.8 root 660: if (i < 2) /* not enough args? */
1.1.1.6 root 661: fprintf(stderr, " Usage: w address bytes\n");
1.1.1.8 root 662: else
1.1.1.9 root 663: DebugUI_MemWrite(input);
1.1.1.6 root 664: break;
665:
666: case 'r':
667: if (i < 2)
1.1.1.8 root 668: DebugUI_RegDump(); /* no arg - dump regs */
669: else
670: DebugUI_RegSet(arg);
1.1.1.6 root 671: break;
672:
673: case 'l':
1.1.1.8 root 674: if (i < 2) /* not enough args? */
1.1.1.6 root 675: fprintf(stderr," Usage: l filename address\n");
1.1.1.8 root 676: else
1.1.1.9 root 677: DebugUI_LoadBin(input);
1.1.1.6 root 678: break;
679:
680: case 's':
1.1.1.8 root 681: if (i < 2) /* not enough args? */
1.1.1.6 root 682: fprintf(stderr," Usage: s filename address bytes\n");
1.1.1.8 root 683: else
1.1.1.9 root 684: DebugUI_SaveBin(input);
1.1.1.6 root 685: break;
686:
687: default:
1.1.1.8 root 688: if (command[0])
689: fprintf(stderr," Unknown command: '%s'\n", command);
1.1.1.6 root 690: break;
691: }
692:
1.1.1.9 root 693: return retval;
694: }
695:
696: /*-----------------------------------------------------------------------*/
697: /**
698: * Get a UI command, parse and return it.
699: */
700: static int DebugUI_GetCommand(void)
701: {
702: char *input;
703: int retval;
1.1.1.8 root 704:
1.1.1.9 root 705: #if HAVE_LIBREADLINE
706: input = readline("> ");
707: if (!input)
708: return DEBUG_QUIT;
709: if (input[0] != 0)
710: add_history(input);
711: #else
712: fprintf(stderr, "> ");
713: input = malloc(256);
714: if (!input)
715: return DEBUG_QUIT;
716: input[0] = '\0';
717: fgets(input, 256, stdin);
718: #endif
719: retval = DebugUI_ParseCommand(input);
720:
721: free(input);
1.1.1.8 root 722: return retval;
1.1 root 723: }
724:
725:
726: /*-----------------------------------------------------------------------*/
1.1.1.8 root 727: /**
728: * Debug UI
729: */
1.1.1.4 root 730: void DebugUI(void)
1.1 root 731: {
1.1.1.6 root 732: bMemDump = FALSE;
733: disasm_addr = 0;
1.1.1.2 root 734:
1.1.1.8 root 735: fprintf(stderr, "\nYou have entered debug mode. Type c to continue emulation, h for help."
736: "\n----------------------------------------------------------------------\n");
1.1.1.9 root 737: while (DebugUI_GetCommand() != DEBUG_QUIT)
1.1.1.6 root 738: ;
739: fprintf(stderr,"Returning to emulation...\n------------------------------\n\n");
1.1.1.9 root 740: DebugUI_SetLogDefault();
1.1 root 741: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.