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