home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / debug / edebug / debug.c next >
Encoding:
C/C++ Source or Header  |  1995-03-21  |  22.0 KB  |  865 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. /*
  3. ** Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <setjmp.h>
  17. #include <math.h>
  18. #include <string.h>
  19. #include <pc.h>        /* For getkey() */
  20.  
  21. #include "ed.h"
  22. #include "debug.h"
  23. #include "unassmbl.h"
  24. #include <debug/syms.h>
  25.  
  26. typedef struct {
  27.   word16 sig0;
  28.   word16 sig1;
  29.   word16 sig2;
  30.   word16 sig3;
  31.   word16 exponent:15;
  32.   word16 sign:1;
  33. } NPXREG;
  34.  
  35. typedef struct {
  36.   word32 control;
  37.   word32 status;
  38.   word32 tag;
  39.   word32 eip;
  40.   word32 cs;
  41.   word32 dataptr;
  42.   word32 datasel;
  43.   NPXREG reg[8];
  44. } NPX;
  45.  
  46. static char char32spc[] = "xxx·xxx·xxx·xxx∙xxx·xxx·xxx·xxx ";
  47.  
  48. static char flset[] = "VMRF  NT    OFDNIETFMIZR  AC  PE  CY";
  49. static char floff[] = "              UPID  PLNZ      PO  NC";
  50. static char fluse[] = {1,1,0,1,0,0,1,1,1,1,1,1,0,1,0,1,0,1};
  51. static NPX npx;
  52.  
  53. static void save_npx(void)
  54. {
  55. asm(                                       "\n\
  56.     inb    $0xa0,%al                        \n\
  57.     testb    $0x20,%al                        \n\
  58.     jz    1f                            \n\
  59.     xorl    %eax,%eax                        \n\
  60.     outb    %al,$0xf0                        \n\
  61.     movb    $0x20,%al                        \n\
  62.     outb    %al,$0xa0                        \n\
  63.     outb    %al,$0x20                        \n\
  64. 1:                                    \n\
  65.     movl    $_npx, %eax                        \n\
  66.     fnsave    (%eax)                            \n\
  67.     fwait                                "
  68. );
  69. }
  70.  
  71. static void load_npx(void)
  72. {
  73. asm(                                       "\n\
  74.     movl    $_npx, %eax                        \n\
  75.     movb    $0,4(%eax)                        \n\
  76.     frstor    (%eax)                            "
  77. );
  78. }
  79.  
  80. static void tssprint(TSS *t)
  81. {
  82.   int i;
  83.   printf("eax=%08lx  ebx=%08lx  ecx=%08lx  edx=%08lx\n",
  84.     t->tss_eax, t->tss_ebx, t->tss_ecx, t->tss_edx);
  85.   printf("esi=%08lx  edi=%08lx  ebp=%08lx ",
  86.     t->tss_esi, t->tss_edi, t->tss_ebp);
  87.   for (i=0; i<18; i++)
  88.     if (fluse[i])
  89.       if (t->tss_eflags & (1<<(17-i)))
  90.         printf(" %2.2s", flset+i*2);
  91.       else
  92.         printf(" %2.2s", floff+i*2);
  93.   printf("\nds=%04x es=%04x fs=%04x gs=%04x ss:esp=%04x:%08lx cs=%04x\n",
  94.     t->tss_ds, t->tss_es, t->tss_fs, t->tss_gs, t->tss_ss, t->tss_esp, t->tss_cs);
  95. }
  96.  
  97. static void my_getline(char *buf, const char *lasttoken)
  98. {
  99.   int idx, i, ch, erase_it=1;
  100.  
  101.   ansi(A_green);
  102.   printf(">>");
  103.   ansi(A_green | A_bold);
  104.   printf(" %s", lasttoken);
  105.   for (i=0; lasttoken[i]; i++)
  106.     putchar(8);
  107.   ansi(A_white);
  108.   fflush(stdout);
  109.   idx = 0;
  110.  
  111.   while (1)
  112.   {
  113.     ch = getkey();
  114.     if (erase_it)
  115.     {
  116.       for (i=0; lasttoken[i]; i++)
  117.         putchar(' ');
  118.       for (i=0; lasttoken[i]; i++)
  119.         putchar(8);
  120.     }
  121.     switch (ch)
  122.     {
  123.       case 10:
  124.       case 13:
  125.         buf[idx] = 0;
  126.         if (!idx && lasttoken[0])
  127.           printf("\r  \r");
  128.         else
  129.           putchar('\n');
  130.         ansi(A_grey);
  131.         fflush(stdout);
  132.         return;
  133.       case 27:
  134.       case 21:
  135.         while (idx)
  136.         {
  137.           printf("\b \b");
  138.           idx--;
  139.         }
  140.         fflush(stdout);
  141.         break;
  142.       case 8:
  143.         if (idx)
  144.         {
  145.           printf("\b \b");
  146.           fflush(stdout);
  147.           idx--;
  148.         }
  149.         break;
  150.       default:
  151.         putchar(ch);
  152.         fflush(stdout);
  153.         buf[idx++] = ch;
  154.         break;
  155.     }
  156.   }
  157. }
  158.  
  159. typedef enum { Zero, Unknown, CONT, STEP, NEXT, REGS, SET, HELP, LIST,
  160. DUMP, PRINT, QUIT, BREAK, STATUS, WHERE, DUMP_A, DUMP_B, DUMP_W, WHEREIS, XNPX,
  161. CLS } COMMAND_TYPES;
  162.  
  163. extern struct {
  164.   char *name;
  165.   int size;
  166.   int ofs;
  167.   } regs[];
  168.  
  169.  
  170. typedef struct {
  171.         const char *cp;
  172.         int t;
  173.         } item;
  174.  
  175. const item cmds[] = {
  176.         {"g", CONT},
  177.         {"go", CONT},
  178.         {"cont", CONT},
  179.         {"c", CONT},
  180.         {"step", STEP},
  181.         {"s", STEP},
  182.         {"next", NEXT},
  183.         {"n", NEXT},
  184.         {"regs", REGS},
  185.         {"r", REGS},
  186.         {"set", SET},
  187.         {"help", HELP},
  188.         {"h", HELP},
  189.         {"?", HELP},
  190.         {"list", LIST},
  191.         {"l", LIST},
  192.         {"u", LIST},
  193.         {"dump", DUMP},
  194.         {"d", DUMP},
  195.         {"da", DUMP_A},
  196.         {"db", DUMP_B},
  197.         {"dw", DUMP_W},
  198.         {"dd", DUMP},
  199.         {"p", PRINT},
  200.         {"print", PRINT},
  201.         {"quit", QUIT},
  202.         {"q", QUIT},
  203.         {"break", BREAK},
  204.         {"b", BREAK},
  205.         {"bl", STATUS},
  206.         {"status", STATUS},
  207.         {"where", WHERE},
  208.         {"whereis", WHEREIS},
  209.         {"npx", XNPX},
  210.         {"cls", CLS},
  211.         {0, 0}
  212.         };
  213.  
  214. #define dr0 edi.dr[0]
  215. #define dr1 edi.dr[1]
  216. #define dr2 edi.dr[2]
  217. #define dr3 edi.dr[3]
  218. #define dr4 edi.dr[4]
  219. #define dr5 edi.dr[5]
  220. #define dr6 edi.dr[6]
  221. #define dr7 edi.dr[7]
  222.  
  223. int can_longjmp = 0;
  224. jmp_buf debugger_jmpbuf;
  225.  
  226. static int do_where(word32 vaddr)
  227. {
  228.   int i;
  229.   int32 delta;
  230.   char *name;
  231.   printf("0x%08lx %s", vaddr, syms_val2name(vaddr, &delta));
  232.   name = syms_val2line(vaddr, &i, 0);
  233.   if (name)
  234.     printf(", line %d in file %s", i, name);
  235.   else if (delta)
  236.     printf("%+ld", delta);
  237.   putchar('\n');
  238.   return delta;
  239. }
  240.  
  241. static int print_reason(void)
  242. {
  243.   int n, i, rv=0;
  244.   i = a_tss.tss_irqn;
  245.   if ((i == 0x21) && ((a_tss.tss_eax & 0xff00) == 0x4c00))
  246.   {
  247.     ansi(A_green|A_bold);
  248.     printf("Program terminated normally, exit code is %d\n", (word8)a_tss.tss_eax);
  249.     a_tss.tss_eip -= 2; /* point to int 21h */
  250.     return 1;
  251.   }
  252.   ansi(A_red | A_bold);
  253.   if (i != 1)
  254.   {
  255.     tssprint(&a_tss);
  256.     if (i == 0x79)
  257.       printf("Keyboard interrupt\n");
  258.     else if (i == 0x75)
  259.     {
  260.       save_npx();
  261.       printf("Numeric Exception (");
  262.       if ((npx.status & 0x0241) == 0x0241)
  263.         printf("stack overflow");
  264.       else if ((npx.status & 0x0241) == 0x0041)
  265.         printf("stack underflow");
  266.       else if (npx.status & 1)
  267.         printf("invalid operation");
  268.       else if (npx.status & 2)
  269.         printf("denormal operand");
  270.       else if (npx.status & 4)
  271.         printf("divide by zero");
  272.       else if (npx.status & 8)
  273.         printf("overflow");
  274.       else if (npx.status & 16)
  275.         printf("underflow");
  276.       else if (npx.status & 32)
  277.         printf("loss of precision");
  278.       printf(") at eip=0x%08lx\n", npx.eip);
  279.       unassemble(npx.eip, 0);
  280.       load_npx();
  281.     }
  282.     else
  283.     {
  284.       printf("exception %d (%#02x) occurred", i, i);
  285.       if ((i == 8) || ((i>=10) && (i<=14)))
  286.         printf(", error code=%#lx", a_tss.tss_error);
  287.       putchar('\n');
  288.       rv = 1;
  289.     }
  290.   }
  291.   ansi(A_cyan | A_bold);
  292.   for (n=0; n<3; n++)
  293.     if ((dr6 & (1<<n)) && (dr7 & (3<<(n*2))))
  294.     {
  295.       printf("breakpoint %d hit\n", n);
  296.       rv = 1;
  297.     }
  298.   return rv;
  299. }
  300.  
  301. static int wildlines;
  302.  
  303. static void print_wildmatch(word32 addr, char type_c, char *name, char *name2, int lnum)
  304. {
  305.   int key;
  306.  
  307.   if(wildlines < 0)
  308.     return;
  309.   if(++wildlines > 20)
  310.   {
  311.     printf("--- More ---");
  312.     fflush(stdout);
  313.     key = getkey();
  314.     printf("\r            \r");
  315.     switch (key)
  316.     {
  317.       case ' ':
  318.         wildlines = 0;
  319.         break;
  320.       case 13:
  321.         wildlines--;
  322.         break;
  323.       case 'q':
  324.       case 27:
  325.         wildlines = -1;
  326.         return;
  327.     }
  328.   }
  329.   printf("0x%08lx %c %s", addr, type_c, name);
  330.   if (name2)
  331.     printf(", line %d of %s", lnum, name2);
  332.   putchar('\n');
  333. }
  334.  
  335. void debugger(void)
  336. {
  337.   char buf[140], token[10];
  338.   char buf2[140], *name, lasttoken[140];
  339.   int i, n, s, len, rem_cmd, cmd;
  340.   word32 vaddr, v, rem_v, olddr7;
  341.   int32 delta;
  342.  
  343.   syms_printwhy = 1;
  344.   dr0 = dr1 = dr2 = edi.app_base;
  345.   dr3 = syms_name2val("_main") + edi.app_base;
  346.   if (undefined_symbol)
  347.     dr3 = a_tss.tss_eip + edi.app_base;
  348.   can_longjmp = 1;
  349.   setjmp(debugger_jmpbuf);
  350.   rem_cmd = Zero;
  351.   lasttoken[0] = 0;
  352.   while (1)
  353.   {
  354.     int found;
  355.     undefined_symbol = 0;
  356.     my_getline(buf, lasttoken);
  357.     token[0] = 0;
  358.     if (sscanf(buf, "%s %[^\n]", token, buf) < 2)
  359.       buf[0] = 0;
  360.     if (token[0])
  361.       strcpy(lasttoken, token);
  362.     cmd = rem_cmd;
  363.     found = 0;
  364.     for (i=0; cmds[i].cp; i++)
  365.       if (strcmp(cmds[i].cp, token) == 0)
  366.       {
  367.         cmd = cmds[i].t;
  368.         found = 1;
  369.       }
  370.     if (!found && token[0])
  371.       cmd = Unknown;
  372.     if (rem_cmd != cmd)
  373.       vaddr = a_tss.tss_eip;
  374.  
  375.     switch (cmd)
  376.     {
  377.       case HELP:
  378.         printf("Commands:\n");
  379.         printf("go <v>\tg\tgo, stop at <v>\n");
  380.         printf("cont\tc\tcontinue execution\n");
  381.         printf("step\ts\tstep through current instruction\n");
  382.         printf("next\tn\tstep to next instruction\n");
  383.         printf("list\tl u\tlist instructions (takes addr, count)\n");
  384.         printf("dump\td\tdump memory (takes addr, count)\n");
  385.         printf("print\tp\tprint value of expression (takes expr)\n");
  386.         printf("break\tb\tset breakpoint (takes which, addr)\n");
  387.         printf("status\t\tbreakpoint status\n");
  388.         printf("regs\tr\tprint registers\n");
  389.         printf("set\t\tset register/memory\n");
  390.         printf("npx\t\tdisplay 80387 contents\n");
  391.         printf("where\t\tdisplay list of active functions\n");
  392.         printf("whereis\t\tfind a symbol/location (takes wildcard or value)\n");
  393.         printf("cls\t\tclear screen\n");
  394.         printf("help\th,?\tprint help\n");
  395.         printf("quit\tq\tquit\n");
  396.         break;
  397.  
  398.       case CONT:
  399.         sscanf(buf, "%s", buf);
  400.         if (buf[0])
  401.         {
  402.           v = syms_name2val(buf);
  403.           if (undefined_symbol)
  404.             break;
  405.           dr3 = v + edi.app_base;
  406.           dr7 |= 0xc0;
  407.         }
  408.         else
  409.           dr7 &= ~0xc0;
  410.         olddr7 = dr7;
  411.         dr7 = 0;
  412.         a_tss.tss_eflags |= 0x0100;
  413.         run_child();
  414.         dr7 = olddr7;
  415.         if (a_tss.tss_irqn == 1)
  416.         {
  417.           a_tss.tss_eflags &= ~0x0100;
  418.           a_tss.tss_eflags |= 0x10000;
  419.           run_child();
  420.           if (a_tss.tss_irqn == 1)
  421.             tssprint(&a_tss);
  422.         }
  423.         print_reason();
  424.         dr3 = unassemble(a_tss.tss_eip, 1) + edi.app_base;
  425.         break;
  426.  
  427.       case STEP:
  428.         if (rem_cmd != cmd)
  429.           n = 1;
  430.         sscanf(buf, "%d", &n);
  431.         a_tss.tss_eflags |= 0x0100;
  432.         for (i=0; i<n; i++)
  433.         {
  434.           int q;
  435.           olddr7 = dr7;
  436.           dr7 = 0;
  437.           run_child();
  438.           dr7 = olddr7;
  439.           q = print_reason();
  440.           dr3 = unassemble(a_tss.tss_eip, 1) + edi.app_base;
  441.           if ((a_tss.tss_irqn != 1) || q)
  442.             break;
  443.         }
  444.         a_tss.tss_eflags &= ~0x0100;
  445.         break;
  446.  
  447.       case NEXT:
  448.         if (rem_cmd != cmd)
  449.           n = 1;
  450.         sscanf(buf, "%d", &n);
  451.         for (i=0; i<n; i++)
  452.         {
  453.           olddr7 = dr7;
  454.           dr7 &= ~0xc0;
  455.           dr7 |= 0xc0;
  456.           if (last_unassemble_unconditional ||
  457.               last_unassemble_jump)
  458.             a_tss.tss_eflags |= 0x0100; /* step */
  459.           else
  460.             a_tss.tss_eflags &= ~0x0100;
  461.           run_child();
  462.           dr7 = olddr7;
  463.           print_reason();
  464.           dr3 = unassemble(a_tss.tss_eip, 1) + edi.app_base;
  465.           if (a_tss.tss_irqn != 1)
  466.             break;
  467.         }
  468.         a_tss.tss_eflags &= ~0x0100;
  469.         break;
  470.  
  471.       case WHERE:
  472.         lasttoken[0] = 0;
  473.         v = a_tss.tss_ebp;
  474.         vaddr = a_tss.tss_eip;
  475.         delta = do_where(vaddr);
  476.         if (delta == 0) /* try to find out where we just came from */
  477.         {
  478.           read_child(a_tss.tss_esp, &rem_v, 4);
  479.           if (rem_v)
  480.             do_where(rem_v);
  481.         }
  482.         do {
  483.           if (v == 0)
  484.             break;
  485.           if (read_child(v, &rem_v, 4))
  486.             break;
  487.           if (rem_v == 0)
  488.             break;
  489.           if (read_child(v+4, &vaddr, 4))
  490.             break;
  491.           do_where(vaddr);
  492.           v = rem_v;
  493.         } while ((v>=a_tss.tss_esp) && (v<0x80000000UL));
  494.         break;
  495.  
  496.       case WHEREIS:
  497.         lasttoken[0] = 0;
  498.         sscanf(buf, "%s", buf2);
  499.         if (strpbrk(buf2, "*?"))
  500.         {
  501.           wildlines = 0;
  502.           syms_listwild(buf2, print_wildmatch);
  503.           break;
  504.         }
  505.         if (buf2[0])
  506.           vaddr = syms_name2val(buf2);
  507.         if (undefined_symbol)
  508.           break;
  509.         name = syms_val2name(vaddr, &delta);
  510.         printf("0x%08lx %s", vaddr, name);
  511.         if (delta)
  512.           printf("+%lx", delta);
  513.         name = syms_val2line(vaddr, &i, 0);
  514.         if (name)
  515.           printf(", line %d in file %s", i, name);
  516.         putchar('\n');
  517.         break;
  518.  
  519.       case LIST:
  520.         if (rem_cmd != cmd)
  521.           n = 10;
  522.         buf2[0] = 0;
  523.         sscanf(buf, "%s %d", buf2, &n);
  524.         if (buf2[0] && strcmp(buf2, "."))
  525.           vaddr = syms_name2val(buf2);
  526.         if (undefined_symbol)
  527.           break;
  528.         for (i=0; i<n; i++)
  529.         {
  530.           vaddr = unassemble(vaddr, 0);
  531.           i += last_unassemble_extra_lines;
  532.         }
  533.         break;
  534.  
  535.       case DUMP_A:
  536.         buf2[0] = 0;
  537.         sscanf(buf, "%s %d", buf2, &n);
  538.         if (buf2[0])
  539.           vaddr = syms_name2val(buf2);
  540.         if (undefined_symbol)
  541.           break;
  542.         while (1)
  543.         {
  544.           word8 ch;
  545.           if (vaddr == 0)
  546.           {
  547.             printf("<bad address>\n");
  548.             break;
  549.           }
  550.           if (read_child(vaddr, &ch, 1))
  551.             break;
  552.           if (ch == 0)
  553.           {
  554.             putchar('\n');
  555.             break;
  556.           }
  557.           if (ch < ' ')
  558.             printf("^%c", ch+'@');
  559.           else if ((ch >= ' ') && (ch < 0x7f))
  560.             putchar(ch);
  561.           else if (ch == 0x7f)
  562.             printf("^?");
  563.           else if ((ch >= 0x80) && (ch < 0xa0))
  564.             printf("M-^%c", ch-0x80+'@');
  565.           else if (ch >= 0xa0)
  566.             printf("M-%c", ch-0x80);
  567.           vaddr++;
  568.         }
  569.         break;
  570.       case DUMP:
  571.       case DUMP_B:
  572.       case DUMP_W:
  573.         if (rem_cmd != cmd)
  574.           n = 4;
  575.         buf2[0] = 0;
  576.         sscanf(buf, "%s %d", buf2, &n);
  577.         if (buf2[0])
  578.           vaddr = syms_name2val(buf2);
  579.         if (undefined_symbol)
  580.         {
  581.           printf("undefined symbol\n");
  582.           break;
  583.         }
  584.         s = 0;
  585.         len = n + (~((vaddr&15)/4-1) & 3);
  586.         for (i=-((vaddr&15)/4); i<len; i++)
  587.         {
  588.           if ((s&3) == 0)
  589.             printf("0x%08lx:", vaddr+i*4);
  590.           if ((i>=0) && (i<n))
  591.           {
  592.             word32 v1;
  593.             if (read_child(vaddr+i*4, &v1, 4))
  594.               break;
  595.             printf(" 0x%08lx", v1);
  596.           }
  597.           else
  598.             printf("           ");
  599.           if ((s & 3) == 3)
  600.           {
  601.             int j, c;
  602.             printf("  ");
  603.             for (j=0; j<16; j++)
  604.               if ((j+i*4-12>=0) && (j+i*4-12 < n*4))
  605.               {
  606.                 if (read_child(vaddr+j+i*4-12, &c, 1))
  607.                   break;
  608.                 if (c<' ')
  609.                   putchar('.');
  610.                 else
  611.                   putchar(c);
  612.               }
  613.               else
  614.                 putchar(' ');
  615.             printf("\n");
  616.           }
  617.           s++;
  618.         }
  619.         if (s & 3)
  620.           printf("\n");
  621.         vaddr += n*4;
  622.         break;
  623.  
  624.       case PRINT:
  625.         lasttoken[0] = 0;
  626.         sscanf(buf, "%s", buf2);
  627.         if (buf2[0])
  628.           vaddr = syms_name2val(buf2);
  629.         if (undefined_symbol)
  630.           break;
  631.         name = syms_val2name(vaddr, &delta);
  632.         printf("0x%08lx %ld", vaddr, (long)vaddr);
  633.         for (i=31; i>=0; i--)
  634.         {
  635.           if (char32spc[i] != 'x')
  636.             putchar(char32spc[i]);
  637.           printf("%d", (int)((vaddr>>i)&1));
  638.         }
  639.         printf("\n");
  640.         break;
  641.  
  642.       case BREAK:
  643.         vaddr = n = 0;
  644.         buf2[0] = 0;
  645.         sscanf(buf, "%d %s", &n, buf2);
  646.         if (buf2[0])
  647.           vaddr = syms_name2val(buf2);
  648.         if (undefined_symbol)
  649.           break;
  650.         edi.dr[n] = vaddr + edi.app_base;
  651.         if (vaddr == 0)
  652.           dr7 &= ~(2 << (n*2));
  653.         else
  654.           dr7 |= 2 << (n*2);
  655.  
  656.       case STATUS:
  657.         s = 0;
  658.         for (n=0; n<4; n++)
  659.         {
  660.           s = 1;
  661.           name = syms_val2name(edi.dr[n] - edi.app_base, &delta);
  662.           printf("  dr%d  %s", n, name);
  663.           if (delta)
  664.             printf("+%#lx", delta);
  665.           if (name[0] != '0')
  666.             printf(" (0x%lx)", edi.dr[n] - edi.app_base);
  667.           if (!(dr7 & (3 << (n*2))))
  668.             printf(" (disabled)");
  669.           putchar('\n');
  670.         }
  671.         if (s == 0)
  672.           printf("  No breakpoints set\n");
  673.         break;
  674.  
  675.       case REGS:
  676.         tssprint(&a_tss);
  677.         unassemble(a_tss.tss_eip, 0);
  678.         break;
  679.  
  680.       case SET:
  681.         cmd = Zero;
  682.         lasttoken[0] = 0;
  683.         buf2[0] = 0;
  684.         len = sscanf(buf, "%s %s", buf2, buf);
  685.         if (buf2[0] == 0)
  686.         {
  687.           break;
  688.         }
  689.         if (len > 1)
  690.         {
  691.           v = syms_name2val(buf);
  692.           if (undefined_symbol)
  693.             break;
  694.         }
  695.         found = 0;
  696.         for (i=0; regs[i].name; i++)
  697.           if (strcmp(regs[i].name, buf2) == 0)
  698.           {
  699.             TSS *tss_ptr = &a_tss;
  700.             found = 1;
  701.             if (len > 1)
  702.             {
  703.               switch (regs[i].size)
  704.               {
  705.                 case 1:
  706.                   *(word8 *)((word8 *)tss_ptr + regs[i].ofs) = v;
  707.                   break;
  708.                 case 2:
  709.                   *(word16 *)((word8 *)tss_ptr + regs[i].ofs) = v;
  710.                   break;
  711.                 case 4:
  712.                   *(word32 *)((word8 *)tss_ptr + regs[i].ofs) = v;
  713.                   break;
  714.               }
  715.             }
  716.             else
  717.             {
  718.               switch (regs[i].size)
  719.               {
  720.                 case 1:
  721.                   printf("%02x ", *(word8 *)((word8 *)tss_ptr + regs[i].ofs));
  722.                   my_getline(buf, "");
  723.                   if (buf[0])
  724.                   {
  725.                     v = syms_name2val(buf);
  726.                     if (undefined_symbol)
  727.                       break;
  728.                     *(word8 *)((word8 *)tss_ptr + regs[i].ofs) = v;
  729.                   }
  730.                   break;
  731.                 case 2:
  732.                   printf("%04x ", *(word16 *)((word16 *)tss_ptr + regs[i].ofs));
  733.                   my_getline(buf, "");
  734.                   if (buf[0])
  735.                   {
  736.                     v = syms_name2val(buf);
  737.                     if (undefined_symbol)
  738.                       break;
  739.                     *(word16 *)((word16 *)tss_ptr + regs[i].ofs) = v;
  740.                   }
  741.                   break;
  742.                 case 4:
  743.                   printf("%08lx ", *(word32 *)((word32 *)tss_ptr + regs[i].ofs));
  744.                   my_getline(buf, "");
  745.                   if (buf[0])
  746.                   {
  747.                     v = syms_name2val(buf);
  748.                     if (undefined_symbol)
  749.                       break;
  750.                     *(word32 *)((word32 *)tss_ptr + regs[i].ofs) = v;
  751.                   }
  752.                   break;
  753.               }
  754.             }
  755.             break;
  756.           }
  757.         if (found)
  758.           break;
  759.         vaddr = syms_name2val(buf2);
  760.         if (undefined_symbol)
  761.           break;
  762.         if (len < 2)
  763.         {
  764.           v = syms_name2val(buf);
  765.           if (undefined_symbol)
  766.             break;
  767.           write_child(vaddr, &v, 4);
  768.         }
  769.         while (1)
  770.         {
  771.           word32 vv;
  772.           if (read_child(vaddr, &vv,4))
  773.             break;
  774.           printf("0x%08lx 0x%08lx", vaddr, vv);
  775.           my_getline(buf, "");
  776.           if (buf[0])
  777.           {
  778.             if (strcmp(buf, ".") == 0)
  779.               break;
  780.             vv = syms_name2val(buf);
  781.             if (write_child(vaddr, &vv, 4))
  782.               break;
  783.           }
  784.           vaddr += 4;
  785.         }
  786.         break;
  787.       case XNPX:
  788.         save_npx();
  789.         printf("Control: 0x%04lx  Status: 0x%04lx  Tag: 0x%04lx\n",
  790.                npx.control & 0xffff, npx.status & 0xffff, npx.tag & 0xffff);
  791.         for (i=0; i<8; i++)
  792.         {
  793.           double d;
  794.           int tag;
  795.           int tos = (npx.status >> 11) & 7;
  796.           printf("st(%d)  ", i);
  797.           if (npx.reg[i].sign)
  798.             putchar('-');
  799.           else
  800.             putchar('+');
  801.           printf(" %04x %04x %04x %04x e %04x    ",
  802.                  npx.reg[i].sig3,
  803.                  npx.reg[i].sig2,
  804.                  npx.reg[i].sig1,
  805.                  npx.reg[i].sig0,
  806.                  npx.reg[i].exponent);
  807.           tag = (npx.tag >> (((i+tos)%8)*2)) & 3;
  808.           switch (tag)
  809.           {
  810.             case 0:
  811.               printf("Valid");
  812.               if (((int)npx.reg[i].exponent-16382 < 1000) &&
  813.                   ((int)npx.reg[i].exponent-16382 > -1000))
  814.               {
  815.                 d = npx.reg[i].sig3/65536.0 + npx.reg[i].sig2/65536.0/65536.0
  816.                   + npx.reg[i].sig1/65536.0/65536.0/65536.0;
  817.                 d = ldexp(d,(int)npx.reg[i].exponent-16382);
  818.                 if (npx.reg[i].sign)
  819.                   d = -d;
  820.                 printf("  %.16g", d);
  821.               }
  822.               else
  823.                 printf("  (too big to display)");
  824.               putchar('\n');
  825.               break;
  826.             case 1:
  827.               printf("Zero\n");
  828.               break;
  829.             case 2:
  830.               printf("Special\n");
  831.               break;
  832.             case 3:
  833.               printf("Empty\n");
  834.               break;
  835.           }
  836.         }
  837.         load_npx();
  838.         break;
  839.  
  840.       case QUIT:
  841.         return;
  842.  
  843.       case Zero:
  844.         break;
  845.  
  846.       case CLS:
  847.     asm volatile("pusha; movb $15,%ah; int $0x10; movb $0,%ah; int $0x10; popa");
  848.     break;
  849.  
  850.       default:
  851.         printf("Unknown command\n");
  852.         lasttoken[0] = 0;
  853.         cmd = Zero;
  854.         break;
  855.     }
  856.     if (undefined_symbol)
  857.     {
  858.       lasttoken[0] = 0;
  859.       cmd = Zero;
  860.       undefined_symbol = 0;
  861.     }
  862.     rem_cmd = cmd;
  863.   }
  864. }
  865.