|
|
1.1 ! root 1: /* ! 2: ! 3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved. ! 4: ! 5: */ ! 6: ! 7: ! 8: ! 9: /* MiNT debugging output routines */ ! 10: ! 11: /* also, ksprintf is put here, for lack of any better place to put it */ ! 12: ! 13: ! 14: ! 15: #include "mint.h" ! 16: ! 17: #include <stdarg.h> ! 18: ! 19: ! 20: ! 21: static void VDEBUGOUT P_((const char *, va_list)); ! 22: ! 23: ! 24: ! 25: /* ! 26: ! 27: * ksprintf implements a very crude sprintf() function that provides only ! 28: ! 29: * what MiNT needs... ! 30: ! 31: * ! 32: ! 33: * NOTE: this sprintf probably doesn't conform to any standard at ! 34: ! 35: * all. It's only use in life is that it won't overflow fixed ! 36: ! 37: * size buffers (i.e. it won't try to write more than SPRINTF_MAX ! 38: ! 39: * characters into a string) ! 40: ! 41: */ ! 42: ! 43: ! 44: ! 45: static int ! 46: ! 47: PUTC(char *p, int c, int *cnt, int width) { ! 48: ! 49: int put = 1; ! 50: ! 51: ! 52: ! 53: if (*cnt <= 0) return 0; ! 54: ! 55: *p++ = c; ! 56: ! 57: *cnt -= 1; ! 58: ! 59: while (*cnt > 0 && --width > 0) { ! 60: ! 61: *p++ = ' '; ! 62: ! 63: *cnt -= 1; ! 64: ! 65: put++; ! 66: ! 67: } ! 68: ! 69: return put; ! 70: ! 71: } ! 72: ! 73: ! 74: ! 75: static int ! 76: ! 77: PUTS(char *p, const char *s, int *cnt, int width) { ! 78: ! 79: int put = 0; ! 80: ! 81: ! 82: ! 83: if (s == 0) s = "(null)"; ! 84: ! 85: ! 86: ! 87: while (*cnt > 0 && *s) { ! 88: ! 89: *p++ = *s++; ! 90: ! 91: put++; ! 92: ! 93: *cnt -= 1; ! 94: ! 95: width--; ! 96: ! 97: } ! 98: ! 99: while (width-- > 0 && *cnt > 0) { ! 100: ! 101: *p++ = ' '; ! 102: ! 103: put++; ! 104: ! 105: *cnt -= 1; ! 106: ! 107: } ! 108: ! 109: return put; ! 110: ! 111: } ! 112: ! 113: ! 114: ! 115: static int ! 116: ! 117: PUTL(char *p, unsigned long u, int base, int *cnt, int width, int fill_char) ! 118: ! 119: { ! 120: ! 121: int put = 0; ! 122: ! 123: static char obuf[32]; ! 124: ! 125: char *t; ! 126: ! 127: ! 128: ! 129: t = obuf; ! 130: ! 131: ! 132: ! 133: do { ! 134: ! 135: *t++ = "0123456789abcdef"[u % base]; ! 136: ! 137: u /= base; ! 138: ! 139: width--; ! 140: ! 141: } while (u > 0); ! 142: ! 143: ! 144: ! 145: while (width-- > 0 && *cnt > 0) { ! 146: ! 147: *p++ = fill_char; ! 148: ! 149: put++; ! 150: ! 151: *cnt -= 1; ! 152: ! 153: } ! 154: ! 155: while (*cnt > 0 && t != obuf) { ! 156: ! 157: *p++ = *--t; ! 158: ! 159: put++; ! 160: ! 161: *cnt -= 1; ! 162: ! 163: } ! 164: ! 165: return put; ! 166: ! 167: } ! 168: ! 169: ! 170: ! 171: int ! 172: ! 173: vksprintf(char *buf, const char *fmt, va_list args) ! 174: ! 175: { ! 176: ! 177: char *p = buf, c, fill_char; ! 178: ! 179: char *s_arg; ! 180: ! 181: int i_arg; ! 182: ! 183: long l_arg; ! 184: ! 185: int cnt; ! 186: ! 187: int width, long_flag; ! 188: ! 189: ! 190: ! 191: cnt = SPRINTF_MAX - 1; ! 192: ! 193: while( (c = *fmt++) != 0 ) { ! 194: ! 195: if (c != '%') { ! 196: ! 197: p += PUTC(p, c, &cnt, 1); ! 198: ! 199: continue; ! 200: ! 201: } ! 202: ! 203: c = *fmt++; ! 204: ! 205: width = 0; ! 206: ! 207: long_flag = 0; ! 208: ! 209: fill_char = ' '; ! 210: ! 211: if (c == '0') fill_char = '0'; ! 212: ! 213: while (c && isdigit(c)) { ! 214: ! 215: width = 10*width + (c-'0'); ! 216: ! 217: c = *fmt++; ! 218: ! 219: } ! 220: ! 221: if (c == 'l' || c == 'L') { ! 222: ! 223: long_flag = 1; ! 224: ! 225: c = *fmt++; ! 226: ! 227: } ! 228: ! 229: if (!c) break; ! 230: ! 231: ! 232: ! 233: switch (c) { ! 234: ! 235: case '%': ! 236: ! 237: p += PUTC(p, c, &cnt, width); ! 238: ! 239: break; ! 240: ! 241: case 'c': ! 242: ! 243: i_arg = va_arg(args, int); ! 244: ! 245: p += PUTC(p, i_arg, &cnt, width); ! 246: ! 247: break; ! 248: ! 249: case 's': ! 250: ! 251: s_arg = va_arg(args, char *); ! 252: ! 253: p += PUTS(p, s_arg, &cnt, width); ! 254: ! 255: break; ! 256: ! 257: case 'd': ! 258: ! 259: if (long_flag) { ! 260: ! 261: l_arg = va_arg(args, long); ! 262: ! 263: } else { ! 264: ! 265: l_arg = va_arg(args, int); ! 266: ! 267: } ! 268: ! 269: if (l_arg < 0) { ! 270: ! 271: p += PUTC(p, '-', &cnt, 1); ! 272: ! 273: width--; ! 274: ! 275: l_arg = -l_arg; ! 276: ! 277: } ! 278: ! 279: p += PUTL(p, l_arg, 10, &cnt, width, fill_char); ! 280: ! 281: break; ! 282: ! 283: case 'o': ! 284: ! 285: if (long_flag) { ! 286: ! 287: l_arg = va_arg(args, long); ! 288: ! 289: } else { ! 290: ! 291: l_arg = va_arg(args, unsigned int); ! 292: ! 293: } ! 294: ! 295: p += PUTL(p, l_arg, 8, &cnt, width, fill_char); ! 296: ! 297: break; ! 298: ! 299: case 'x': ! 300: ! 301: if (long_flag) { ! 302: ! 303: l_arg = va_arg(args, long); ! 304: ! 305: } else { ! 306: ! 307: l_arg = va_arg(args, unsigned int); ! 308: ! 309: } ! 310: ! 311: p += PUTL(p, l_arg, 16, &cnt, width, fill_char); ! 312: ! 313: break; ! 314: ! 315: case 'u': ! 316: ! 317: if (long_flag) { ! 318: ! 319: l_arg = va_arg(args, long); ! 320: ! 321: } else { ! 322: ! 323: l_arg = va_arg(args, unsigned int); ! 324: ! 325: } ! 326: ! 327: p += PUTL(p, l_arg, 10, &cnt, width, fill_char); ! 328: ! 329: break; ! 330: ! 331: ! 332: ! 333: } ! 334: ! 335: } ! 336: ! 337: *p = 0; ! 338: ! 339: return (p - buf); ! 340: ! 341: } ! 342: ! 343: ! 344: ! 345: int ! 346: ! 347: ksprintf(char *buf, const char *fmt, ...) ! 348: ! 349: { ! 350: ! 351: va_list args; ! 352: ! 353: int foo; ! 354: ! 355: ! 356: ! 357: va_start(args, fmt); ! 358: ! 359: foo = vksprintf(buf, fmt, args); ! 360: ! 361: va_end(args); ! 362: ! 363: return foo; ! 364: ! 365: } ! 366: ! 367: ! 368: ! 369: int debug_level = 0; /* how much debugging info should we print? */ ! 370: ! 371: int out_device = 2; /* BIOS device to write errors to */ ! 372: ! 373: ! 374: ! 375: /* ! 376: ! 377: * out_next[i] is the out_device value to use when the current ! 378: ! 379: * device is i and the user hits F3. ! 380: ! 381: * Cycle is CON -> PRN -> AUX -> MIDI -> 6 -> 7 -> 8 -> 9 -> CON ! 382: ! 383: * (Note: BIOS devices 6-8 exist on Mega STe and TT, 9 on TT.) ! 384: ! 385: * ! 386: ! 387: * out_device and this table are exported to bios.c and used here in HALT(). ! 388: ! 389: */ ! 390: ! 391: ! 392: ! 393: /* 0 1 2 3 4 5 6 7 8 9 */ ! 394: ! 395: char out_next[] = { 1, 3, 0, 6, 0, 0, 7, 8, 9, 2 }; ! 396: ! 397: ! 398: ! 399: void ! 400: ! 401: debug_ws(s) ! 402: ! 403: const char *s; ! 404: ! 405: { ! 406: ! 407: long r; ! 408: ! 409: ! 410: ! 411: while (*s) { ! 412: ! 413: (void)Bconout(out_device, *s); ! 414: ! 415: if (*s == '\n' && out_device != 0 && Bconstat(out_device)) { ! 416: ! 417: r = Bconin(out_device) & 0x00ff0000; ! 418: ! 419: if (r == 0x3b0000) ! 420: ! 421: debug_level++; ! 422: ! 423: else if (r == 0x3c0000) ! 424: ! 425: --debug_level; ! 426: ! 427: else if (r == 0x400000) ! 428: ! 429: DUMPPROC(); ! 430: ! 431: else if (r == 0x620000) { ! 432: ! 433: do { ! 434: ! 435: r = Bconin(out_device) & 0x00ff0000; ! 436: ! 437: } while (r != 0x610000); ! 438: ! 439: } ! 440: ! 441: } ! 442: ! 443: s++; ! 444: ! 445: } ! 446: ! 447: } ! 448: ! 449: ! 450: ! 451: static void ! 452: ! 453: VDEBUGOUT(s, args) ! 454: ! 455: const char *s; ! 456: ! 457: va_list args; ! 458: ! 459: { ! 460: ! 461: char buf[SPRINTF_MAX]; ! 462: ! 463: ! 464: ! 465: ksprintf(buf, "pid %d (%s): ", curproc->pid, curproc->name); ! 466: ! 467: debug_ws(buf); ! 468: ! 469: vksprintf(buf, s, args); ! 470: ! 471: debug_ws(buf); ! 472: ! 473: debug_ws("\r\n"); ! 474: ! 475: } ! 476: ! 477: ! 478: ! 479: void TRACE(const char *s, ...) ! 480: ! 481: { ! 482: ! 483: va_list args; ! 484: ! 485: ! 486: ! 487: if (debug_level > 1) { ! 488: ! 489: va_start(args, s); ! 490: ! 491: VDEBUGOUT(s, args); ! 492: ! 493: va_end(args); ! 494: ! 495: } ! 496: ! 497: } ! 498: ! 499: ! 500: ! 501: void DEBUG(const char *s, ...) ! 502: ! 503: { ! 504: ! 505: va_list args; ! 506: ! 507: ! 508: ! 509: if (debug_level) { ! 510: ! 511: va_start(args, s); ! 512: ! 513: VDEBUGOUT(s, args); ! 514: ! 515: va_end(args); ! 516: ! 517: } ! 518: ! 519: } ! 520: ! 521: ! 522: ! 523: void ALERT(const char *s, ...) ! 524: ! 525: { ! 526: ! 527: va_list args; ! 528: ! 529: ! 530: ! 531: va_start(args, s); ! 532: ! 533: VDEBUGOUT(s, args); ! 534: ! 535: va_end(args); ! 536: ! 537: } ! 538: ! 539: ! 540: ! 541: EXITING ! 542: ! 543: void FATAL(const char *s, ...) ! 544: ! 545: { ! 546: ! 547: va_list args; ! 548: ! 549: ! 550: ! 551: va_start(args, s); ! 552: ! 553: VDEBUGOUT(s, args); ! 554: ! 555: va_end(args); ! 556: ! 557: HALT(); ! 558: ! 559: } ! 560: ! 561: ! 562: ! 563: ! 564: ! 565: EXITING ! 566: ! 567: void HALT() ! 568: ! 569: { ! 570: ! 571: long r; ! 572: ! 573: extern long tosssp; /* in main.c */ ! 574: ! 575: ! 576: ! 577: restr_intr(); /* restore interrupts to normal */ ! 578: ! 579: debug_ws("Fatal MiNT error: adjust debug level and hit a key...\r\n"); ! 580: ! 581: sys_q[READY_Q] = 0; /* prevent context switches */ ! 582: ! 583: ! 584: ! 585: for(;;) { ! 586: ! 587: r = Bconin(2) & 0x00ff0000; ! 588: ! 589: if (r == 0x3b0000) ! 590: ! 591: debug_level++; ! 592: ! 593: else if (r == 0x3c0000) ! 594: ! 595: --debug_level; ! 596: ! 597: else if (r == 0x3d0000) /* F3: cycle to next device */ ! 598: ! 599: out_device = out_next[out_device]; ! 600: ! 601: else if (r == 0x3e0000) ! 602: ! 603: out_device = 2; /* F4: reset to console */ ! 604: ! 605: else if (r == 0x3f0000) ! 606: ! 607: DUMPMEM(core); /* F5: dump memory */ ! 608: ! 609: else if (r == 0x400000) ! 610: ! 611: DUMPPROC(); ! 612: ! 613: else ! 614: ! 615: break; ! 616: ! 617: } ! 618: ! 619: for(;;) { ! 620: ! 621: debug_ws("System halted. Press 'x' to exit, or else reboot\r\n"); ! 622: ! 623: r = Bconin(2); ! 624: ! 625: ! 626: ! 627: if ( (r & 0x0ff) == 'x' ) { ! 628: ! 629: close_filesys(); ! 630: ! 631: (void)Super((void *)tosssp); /* gratuitous (void *) for Lattice */ ! 632: ! 633: zeroexit(); ! 634: ! 635: } ! 636: ! 637: } ! 638: ! 639: } ! 640: ! 641: ! 642: ! 643: ! 644: ! 645: /* some key definitions */ ! 646: ! 647: #define CTRLALT 0xc ! 648: ! 649: #define DEL 0x53 /* scan code of delete key */ ! 650: ! 651: #define UNDO 0x61 /* scan code of undo key */ ! 652: ! 653: ! 654: ! 655: void ! 656: ! 657: do_func_key(scan) ! 658: ! 659: int scan; ! 660: ! 661: { ! 662: ! 663: extern struct tty con_tty; ! 664: ! 665: ! 666: ! 667: switch (scan) { ! 668: ! 669: case DEL: ! 670: ! 671: reboot(); ! 672: ! 673: break; ! 674: ! 675: case UNDO: ! 676: ! 677: killgroup(con_tty.pgrp, SIGQUIT); ! 678: ! 679: break; ! 680: ! 681: case 0x3b: /* F1 */ ! 682: ! 683: debug_level++; ! 684: ! 685: break; ! 686: ! 687: case 0x3c: /* F2 */ ! 688: ! 689: if (debug_level > 0) ! 690: ! 691: --debug_level; ! 692: ! 693: break; ! 694: ! 695: case 0x3d: /* F3 */ ! 696: ! 697: out_device = out_next[out_device]; ! 698: ! 699: break; ! 700: ! 701: case 0x3e: /* F4 */ ! 702: ! 703: out_device = 2; ! 704: ! 705: break; ! 706: ! 707: case 0x3f: /* F5 */ ! 708: ! 709: DUMPMEM(core); ! 710: ! 711: break; ! 712: ! 713: case 0x40: /* F6 */ ! 714: ! 715: DUMPPROC(); ! 716: ! 717: break; ! 718: ! 719: } ! 720: ! 721: } ! 722:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.