home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / mint / mint095s / debug.c < prev    next >
C/C++ Source or Header  |  1993-08-03  |  7KB  |  362 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
  3. */
  4.  
  5. /* MiNT debugging output routines */
  6. /* also, ksprintf is put here, for lack of any better place to put it */
  7.  
  8. #include "mint.h"
  9. #include <stdarg.h>
  10.  
  11. static void VDEBUGOUT P_((const char *, va_list));
  12.  
  13. /*
  14.  * ksprintf implements a very crude sprintf() function that provides only
  15.  * what MiNT needs...
  16.  *
  17.  * NOTE: this sprintf probably doesn't conform to any standard at
  18.  * all. It's only use in life is that it won't overflow fixed
  19.  * size buffers (i.e. it won't try to write more than SPRINTF_MAX
  20.  * characters into a string)
  21.  */
  22.  
  23. static int
  24. PUTC(char *p, int c, int *cnt, int width) {
  25.     int put = 1;
  26.  
  27.     if (*cnt <= 0) return 0;
  28.     *p++ = c;
  29.     *cnt -= 1;
  30.     while (*cnt > 0 && --width > 0) {
  31.         *p++ = ' ';
  32.         *cnt -= 1;
  33.         put++;
  34.     }
  35.     return put;
  36. }
  37.  
  38. static int
  39. PUTS(char *p, const char *s, int *cnt, int width) {
  40.     int put = 0;
  41.  
  42.     if (s == 0) s = "(null)";
  43.  
  44.     while (*cnt > 0 && *s) {
  45.         *p++ = *s++;
  46.         put++;
  47.         *cnt -= 1;
  48.         width--;
  49.     }
  50.     while (width-- > 0 && *cnt > 0) {
  51.         *p++ = ' ';
  52.         put++;
  53.         *cnt -= 1;
  54.     }
  55.     return put;
  56. }
  57.  
  58. static int
  59. PUTL(char *p, unsigned long u, int base, int *cnt, int width, int fill_char)
  60. {
  61.     int put = 0;
  62.     static char obuf[32];
  63.     char *t;
  64.  
  65.     t = obuf;
  66.  
  67.     do {
  68.         *t++ = "0123456789abcdef"[u % base];
  69.         u /= base;
  70.         width--;
  71.     } while (u > 0);
  72.  
  73.     while (width-- > 0 && *cnt > 0) {
  74.         *p++ = fill_char;
  75.         put++;
  76.         *cnt -= 1;
  77.     }
  78.     while (*cnt > 0 && t != obuf) {
  79.         *p++ = *--t;
  80.         put++;
  81.         *cnt -= 1;
  82.     }
  83.     return put;
  84. }
  85.  
  86. int
  87. vksprintf(char *buf, const char *fmt, va_list args)
  88. {
  89.     char *p = buf, c, fill_char;
  90.     char *s_arg;
  91.     int i_arg;
  92.     long l_arg;
  93.     int cnt;
  94.     int width, long_flag;
  95.  
  96.     cnt = SPRINTF_MAX - 1;
  97.     while( (c = *fmt++) != 0 ) {
  98.         if (c != '%') {
  99.             p += PUTC(p, c, &cnt, 1);
  100.             continue;
  101.         }
  102.         c = *fmt++;
  103.         width = 0;
  104.         long_flag = 0;
  105.         fill_char = ' ';
  106.         if (c == '0') fill_char = '0';
  107.         while (c && isdigit(c)) {
  108.             width = 10*width + (c-'0');
  109.             c = *fmt++;
  110.         }
  111.         if (c == 'l' || c == 'L') {
  112.             long_flag = 1;
  113.             c = *fmt++;
  114.         }
  115.         if (!c) break;
  116.  
  117.         switch (c) {
  118.         case '%':
  119.             p += PUTC(p, c, &cnt, width);
  120.             break;
  121.         case 'c':
  122.             i_arg = va_arg(args, int);
  123.             p += PUTC(p, i_arg, &cnt, width);
  124.             break;
  125.         case 's':
  126.             s_arg = va_arg(args, char *);
  127.             p += PUTS(p, s_arg, &cnt, width);
  128.             break;
  129.         case 'd':
  130.             if (long_flag) {
  131.                 l_arg = va_arg(args, long);
  132.             } else {
  133.                 l_arg = va_arg(args, int);
  134.             }
  135.             if (l_arg < 0) {
  136.                 p += PUTC(p, '-', &cnt, 1);
  137.                 width--;
  138.                 l_arg = -l_arg;
  139.             }
  140.             p += PUTL(p, l_arg, 10, &cnt, width, fill_char);
  141.             break;
  142.         case 'o':
  143.             if (long_flag) {
  144.                 l_arg = va_arg(args, long);
  145.             } else {
  146.                 l_arg = va_arg(args, unsigned int);
  147.             }
  148.             p += PUTL(p, l_arg, 8, &cnt, width, fill_char);
  149.             break;
  150.         case 'x':
  151.             if (long_flag) {
  152.                 l_arg = va_arg(args, long);
  153.             } else {
  154.                 l_arg = va_arg(args, unsigned int);
  155.             }
  156.             p += PUTL(p, l_arg, 16, &cnt, width, fill_char);
  157.             break;
  158.         case 'u':
  159.             if (long_flag) {
  160.                 l_arg = va_arg(args, long);
  161.             } else {
  162.                 l_arg = va_arg(args, unsigned int);
  163.             }
  164.             p += PUTL(p, l_arg, 10, &cnt, width, fill_char);
  165.             break;
  166.  
  167.         }
  168.     }
  169.     *p = 0;
  170.     return (p - buf);
  171. }
  172.  
  173. int
  174. ksprintf(char *buf, const char *fmt, ...)
  175. {
  176.     va_list args;
  177.     int foo;
  178.  
  179.     va_start(args, fmt);
  180.     foo = vksprintf(buf, fmt, args);    
  181.     va_end(args);
  182.     return foo;
  183. }
  184.  
  185. int debug_level = 0;    /* how much debugging info should we print? */
  186. int out_device = 2;    /* BIOS device to write errors to */
  187.  
  188. /*
  189.  * out_next[i] is the out_device value to use when the current
  190.  * device is i and the user hits F3.
  191.  * Cycle is CON -> PRN -> AUX -> MIDI -> 6 -> 7 -> 8 -> 9 -> CON
  192.  * (Note: BIOS devices 6-8 exist on Mega STe and TT, 9 on TT.)
  193.  *
  194.  * out_device and this table are exported to bios.c and used here in HALT().
  195.  */
  196.  
  197. /*            0  1  2  3  4  5  6  7  8  9 */
  198. char out_next[] = { 1, 3, 0, 6, 0, 0, 7, 8, 9, 2 };
  199.  
  200. void
  201. debug_ws(s)
  202.     const char *s;
  203. {
  204.     long r;
  205.  
  206.     while (*s) {
  207.         (void)Bconout(out_device, *s);
  208.         if (*s == '\n' && out_device != 0 && Bconstat(out_device)) {
  209.             r = Bconin(out_device) & 0x00ff0000;
  210.             if (r == 0x3b0000)
  211.                 debug_level++;
  212.             else if (r == 0x3c0000)
  213.                 --debug_level;
  214.             else if (r == 0x400000)
  215.                 DUMPPROC();
  216.             else if (r == 0x620000) {
  217.                 do {
  218.                     r = Bconin(out_device) & 0x00ff0000;
  219.                 } while (r != 0x610000);
  220.             }
  221.         }
  222.         s++;
  223.     }
  224. }
  225.  
  226. static void
  227. VDEBUGOUT(s, args)
  228.     const char *s;
  229.     va_list args;
  230. {
  231.     char buf[SPRINTF_MAX];
  232.  
  233.     ksprintf(buf, "pid %d (%s): ", curproc->pid, curproc->name);
  234.     debug_ws(buf);
  235.     vksprintf(buf, s, args);
  236.     debug_ws(buf);
  237.     debug_ws("\r\n");
  238. }
  239.  
  240. void TRACE(const char *s, ...)
  241. {
  242.     va_list args;
  243.  
  244.     if (debug_level > 1) {
  245.         va_start(args, s);
  246.         VDEBUGOUT(s, args);
  247.         va_end(args);
  248.     }
  249. }
  250.  
  251. void DEBUG(const char *s, ...)
  252. {
  253.     va_list args;
  254.  
  255.     if (debug_level) {
  256.         va_start(args, s);
  257.         VDEBUGOUT(s, args);
  258.         va_end(args);
  259.     }
  260. }
  261.  
  262. void ALERT(const char *s, ...)
  263. {
  264.     va_list args;
  265.  
  266.     va_start(args, s);
  267.     VDEBUGOUT(s, args);
  268.     va_end(args);
  269. }
  270.  
  271. EXITING
  272. void FATAL(const char *s, ...)
  273. {
  274.     va_list args;
  275.  
  276.     va_start(args, s);
  277.     VDEBUGOUT(s, args);
  278.     va_end(args);
  279.     HALT();
  280. }
  281.  
  282.  
  283. EXITING 
  284. void HALT()
  285. {
  286.     long r;
  287.     extern long tosssp;    /* in main.c */
  288.  
  289.     restr_intr();    /* restore interrupts to normal */
  290.     debug_ws("Fatal MiNT error: adjust debug level and hit a key...\r\n");
  291.     sys_q[READY_Q] = 0;    /* prevent context switches */
  292.  
  293.     for(;;) {
  294.         r = Bconin(2) & 0x00ff0000;
  295.         if (r == 0x3b0000)
  296.             debug_level++;
  297.         else if (r == 0x3c0000)
  298.             --debug_level;
  299.         else if (r == 0x3d0000)        /* F3: cycle to next device */
  300.             out_device = out_next[out_device];
  301.         else if (r == 0x3e0000)
  302.             out_device = 2;        /* F4: reset to console */
  303.         else if (r == 0x3f0000)
  304.             DUMPMEM(core);        /* F5: dump memory */
  305.         else if (r == 0x400000)    
  306.             DUMPPROC();
  307.         else
  308.             break;
  309.     }
  310.     for(;;) {
  311.     debug_ws("System halted. Press 'x' to exit, or else reboot\r\n");
  312.         r = Bconin(2);
  313.  
  314.         if ( (r & 0x0ff) == 'x' ) {
  315.             close_filesys();
  316.             (void)Super((void *)tosssp);    /* gratuitous (void *) for Lattice */
  317.             zeroexit();
  318.         }
  319.     }
  320. }
  321.  
  322.  
  323. /* some key definitions */
  324. #define CTRLALT 0xc
  325. #define DEL 0x53    /* scan code of delete key */
  326. #define UNDO 0x61    /* scan code of undo key */
  327.  
  328. void
  329. do_func_key(scan)
  330.     int scan;
  331. {
  332.     extern struct tty con_tty;
  333.  
  334.     switch (scan) {
  335.     case DEL:
  336.         reboot();
  337.         break;
  338.     case UNDO:
  339.         killgroup(con_tty.pgrp, SIGQUIT);
  340.         break;
  341.     case 0x3b:        /* F1 */
  342.         debug_level++;
  343.         break;
  344.     case 0x3c:        /* F2 */
  345.         if (debug_level > 0)
  346.             --debug_level;
  347.         break;
  348.     case 0x3d:        /* F3 */
  349.         out_device = out_next[out_device];
  350.         break;
  351.     case 0x3e:        /* F4 */
  352.         out_device = 2;
  353.         break;
  354.     case 0x3f:        /* F5 */
  355.         DUMPMEM(core);
  356.         break;
  357.     case 0x40:        /* F6 */
  358.         DUMPPROC();
  359.         break;
  360.     }
  361. }
  362.