home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / szadb21b / source / src / adb.c next >
C/C++ Source or Header  |  1992-01-08  |  23KB  |  1,171 lines

  1. /* Copyright (c) 1990 by Sozobon, Limited.  Authors: Johann Ruegg, Don Dugger
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    adb.c
  12.  */
  13. /* 
  14.  * Modified to allow adb execute strings of commands stored in memory.
  15.  * Added buffered transcript output to named files.
  16.  * Changes in accepted request syntax.
  17.  * More elaborate command line.
  18.  *
  19.  *    Michal Jaegermann, May 1990
  20.  *
  21.  * Symbol table display is now paging - it was just too fast for TT.
  22.  * ('q', 'Q' or CNTLC will get you out - any other key continues)
  23.  *    Michal Jaegermann, July 1991
  24.  *
  25.  */
  26.  
  27. #include <setjmp.h>
  28. #include <fcntl.h>
  29. #include "adb.h"
  30.  
  31. #define IN_ADB
  32. #include "lang.h"
  33.  
  34. #define CNTLC    3
  35. #define CNTLS    0x13
  36. #define CNTLW    0x17
  37.  
  38. #define CHUNK   0x4000L;
  39. long _BLKSIZ = CHUNK;         /* granularity of memory allocation */
  40.  
  41. struct file     binary;
  42. int             swidth;      /* max width of symbol name - unknown so far */
  43.  
  44. long            dot;
  45. int             dotoff;
  46. long            olddot;
  47.  
  48. #define DOT    (dot+dotoff)
  49.  
  50. int             dotset;
  51. long            maxoff = 0x400;
  52. int             ibase = 10;
  53.  
  54. int             lastc = 0;
  55. char            sign = 0;
  56. long            bcount;
  57.  
  58. int             click = 0;    /* flag for cmdcol */
  59. extern int      write (), bf_write ();
  60. char            trname[LINESZ + 2];    /* transcript file name */
  61. int             trid = NO_TRANS;/* its descriptor       */
  62. w_buf          *trbuf = (w_buf *) 0;    /* pointer to its buffer */
  63. int             (*trout) () = write;
  64.  
  65. unsigned long   regbuf[19];
  66.  
  67. struct regs     regs[] = {
  68.               "pc", ®buf[16],
  69.               "sr", ®buf[17],
  70.               "xsp", ®buf[18],
  71.               "d0", ®buf[0],
  72.               "d1", ®buf[1],
  73.               "d2", ®buf[2],
  74.               "d3", ®buf[3],
  75.               "d4", ®buf[4],
  76.               "d5", ®buf[5],
  77.               "d6", ®buf[6],
  78.               "d7", ®buf[7],
  79.               "a0", ®buf[8],
  80.               "a1", ®buf[9],
  81.               "a2", ®buf[10],
  82.               "a3", ®buf[11],
  83.               "a4", ®buf[12],
  84.               "a5", ®buf[13],
  85.               "a6", ®buf[14],
  86.               "sp", ®buf[15],
  87.               "", 0,
  88. };
  89.  
  90. #define NREGS    19
  91.  
  92. jmp_buf         jmpb, trp_buf;
  93.  
  94. static char    cnbuf[LINESZ + 2];
  95. #define CONSOLE &cnbuf[0]
  96.  
  97. int             l_restart, w_restart, lb_cur, lb_fill;
  98. char           *lbuf = CONSOLE;
  99.  
  100. int             getkchr (), getschr ();
  101. static char    *csource;    /* location read by a function getschr() */
  102. static int      (*getachr) () = getkchr;
  103. extern int      print_regs;
  104. extern struct window w;
  105.  
  106. char          **bpt_cmds;
  107. char          **ftable;
  108.  
  109. _main ()
  110. {
  111.     extern int      _argc;
  112.     extern char   **_argv;
  113.  
  114.     main (_argc, _argv);
  115.     exit (0);
  116. }
  117.  
  118. main (argc, argv)
  119.     int             argc;
  120.     char           *argv[];
  121. {
  122.     char           *cp, c;
  123.     extern long     ossp;
  124.     int             i, no_cmds, no_buf;
  125.     void            adb (), copyargs (), kdefs (), free (), usage ();
  126.     char           *malloc ();
  127.  
  128.     winopen ();
  129.     *argv++;            /* skip starting argument */
  130.  
  131.     no_cmds = no_buf = 0;
  132.     while ('-' == **argv) {
  133.     (*argv)++;        /* skip dash */
  134.     while ('\0' != (c = ~' ' & **argv)) {
  135.         (*argv)++;        /* skip leading letter */
  136.         if ('N' == c) {
  137.         while ('\0' != (c = ~' ' & **argv)) {
  138.             if ('C' == c)
  139.             no_cmds = 1;
  140.             else if ('B' == c)
  141.             no_buf = 1;
  142.             else
  143.             usage ();
  144.             (*argv)++;    /* to next character */
  145.         }
  146.         break;        /* done with option */
  147.         }
  148.         else if ('K' == c) {
  149.         if ('\0' == **argv) {
  150.             if (0 == --argc)    /* out of arguments? */
  151.             usage ();
  152.             *argv++;
  153.         }
  154.         kdefs (*argv);    /* load definitions of fuction keys */
  155.         break;
  156.         }
  157.         else if ('O' == c) { /* tell which object format */
  158.         if ('\0' == **argv) {
  159.             if (0 == --argc)    /* out of arguments? */
  160.             usage ();
  161.             *argv++;
  162.         }
  163.         if ('M' == (~' ' & **argv))
  164.             swidth = 16;    /* this is MWC symbol table */
  165.         else
  166.             swidth = 8;        /* we'll take anything else for DRI */
  167.         break;
  168.         }
  169.         else
  170.         usage ();
  171.     }            /* while ('\0' != (c = ~' ' & **argv)) */
  172.     if (0 == --argc)
  173.         usage ();
  174.     *argv++;        /* to next argument */
  175.     }                /* while ('-' == **argv) */
  176.     ibase = 16;
  177.  
  178.     if (0 == no_cmds) {
  179.     i = 0;
  180.     if ((char **) 0 != (bpt_cmds =
  181.                 (char **) malloc (MAXBPTS * sizeof(char *)))) {
  182.         while (i < MAXBPTS) {
  183.         if ((char *) 0 == (bpt_cmds[i] = malloc (LINESZ + 3)))
  184.             break;
  185.         i++;
  186.         }
  187.     }
  188.     if (i < MAXBPTS) {
  189.         prt ("not enough memory for breakpoint requests\n");
  190.         while (i > 0) {
  191.         --i;
  192.         free (bpt_cmds[i]);
  193.         }
  194.         if ((char **) 0 != bpt_cmds)
  195.         free (bpt_cmds);
  196.     }
  197.     }
  198.  
  199.     if (0 == no_buf) {        /* set write-to-file function to unbuffered
  200.                  * write */
  201.     if ((w_buf *) 0 ==
  202.         (trbuf = (w_buf *) malloc (sizeof (w_buf)))) {
  203.         prt (M7);        /* warning - transcript unbuffered */
  204.     }
  205.     else {
  206.         trbuf->buf_len = TRBUFSZ;
  207.         trbuf->buffered = 0;
  208.         trout = bf_write;
  209.     }
  210.     }
  211.  
  212.     binary.symptr = 0;
  213. /*    binary.flags = 0; */
  214.     if (0 == --argc) {
  215.     usage ();
  216.     }
  217.     binary.name = *argv++;
  218.  
  219.     if ((binary.fid = open (binary.name, 0)) < 0) {
  220. /*        prtf("%s:cannot open\n", binary.name);    */
  221.     prtf (M1, binary.name);
  222.     seeerr ();
  223.     exit (2);
  224.     }
  225.     if (setobj () != 0) {
  226. /*        prtf("%s:bad format\n", binary.name);    */
  227.     prtf (M2, binary.name);
  228.     seeerr ();
  229.     exit (3);
  230.     }
  231.     if (loadpcs () != 0) {
  232. /*        prtf("%s:bad pexec\n", binary.name);    */
  233.     prtf (M3, binary.name);
  234.     seeerr ();
  235.     exit (4);
  236.     }
  237.     close (binary.fid);
  238.     copyargs (--argc, argv);    /* if any left - copy for a process to debug */
  239.  
  240.     relsym ();
  241.     vects ();
  242. /*    prt("Szadb version 1.2 (english)\n");    */
  243.     prt (M4);
  244.     if (setjmp (trp_buf)) {
  245.     seeerr ();
  246.     exit (0);
  247.     }
  248.     adb (1);
  249. }
  250.  
  251. void
  252. usage ()
  253. {
  254. /*    prtf ("Usage: adb [-nb] [-nc] [-k kdefs] [-o(s|m)] binary [args]\n"); */
  255.     prtf (M_USE);
  256.     seeerr ();
  257.     exit (1);
  258. }
  259.  
  260. exit (n)
  261. {
  262.     void            trclose ();
  263.  
  264.     oldvects ();
  265.     winclose ();
  266.     trclose ();
  267.     _exit (n);
  268. }
  269.  
  270. seeerr ()
  271. {
  272. /*    prt("(hit any key)");    */
  273.     prt (M5);
  274.     gemdos (7);
  275. }
  276.  
  277. #define MWC_START   0x2a6f0004
  278.  
  279. setobj ()
  280. {
  281.     struct fheader  hdr;
  282.     long            guess;
  283.     int             fid = binary.fid;
  284.  
  285.     if ((read (fid, &hdr, sizeof (hdr)) != sizeof (hdr)) &&
  286.                         (MAGIC != hdr.magic))
  287.     return -1;
  288.     /* an empty MWC symbol table may use 0x30 bytes for something (?) */
  289.     if ((hdr.ssize) && (0x30L != hdr.ssize)) {
  290.         if (sizeof(long) != read(fid, &guess, sizeof(long)))
  291.         return -1;
  292.     if (0 == swidth) { /* nobody told what is the format */
  293.         swidth = (MWC_START == guess ? 16 : 8);
  294.     }
  295.     lseek (fid, hdr.tsize + hdr.dsize - (long)(sizeof(long)), 1);
  296.     if (16 == swidth)
  297.         return mwsetsym (fid, hdr.ssize);
  298.     else {
  299.         if (extndsymb(fid, hdr.ssize))
  300.         swidth = 22;
  301.         return setsym (fid, hdr.ssize);
  302.     }
  303.     }
  304.     return 0;
  305. }
  306.  
  307. void
  308. adb (top)
  309.     int             top;
  310. {
  311.     int             cmddol (), cmdcol (), cmdprt ();
  312.     int             cmdwrt (), cmdsreg (), null ();
  313.     long            getn (), getdot ();
  314.     long            expr ();
  315.     int             intr ();
  316.     register int    c, lc;
  317.     register long   count;
  318.     int             (*f) ();
  319.     long            (*g) ();
  320.     char            fmt[LINESZ];
  321.  
  322.     if (top) {
  323.     f = cmdprt;
  324.     g = getdot;
  325.     lc = '=';
  326.     fmt[0] = 'a';
  327.     fmt[1] = '\n';
  328.     fmt[2] = '\0';
  329.     setjmp (jmpb);
  330.     }
  331.  
  332.     for (;;) {
  333.     dotoff = 0;
  334.     if (type (c = PEEKC) & (ALPHANUM | SPECX)) {
  335.         dot = expr ();
  336.         olddot = dot;
  337.         dotset = 1;
  338.     }
  339.     else
  340.         dotset = 0;
  341.     if (PEEKC == ',') {
  342.         nb ();        /* consume pushed comma */
  343.         count = expr ();
  344.     }
  345.     else
  346.         count = 1L;
  347.  
  348.     switch (c = nb ()) {
  349.     case '>':
  350.         f = cmdsreg;
  351.         break;
  352.     case '$':
  353.         c = nb ();
  354.         f = cmddol;
  355.         break;
  356.     case ':':
  357.         c = nb ();
  358.         f = cmdcol;
  359.         if (':' == c) {
  360.         c = nb ();
  361.         click = 1;    /* turned off by cmdcol */
  362.         }
  363.         if ('b' == c) {
  364.         bcount = count;
  365.         count = 1L;
  366.         }
  367.         break;
  368.     case '?':
  369.     case '/':
  370.         g = getn;
  371.         switch (PEEKC) {
  372.  
  373.         case 'w':
  374.         case 'W':
  375.         f = cmdwrt;
  376.         break;
  377.         default:
  378.         getfmt (fmt);
  379.         case '\n':        /* FALLTHROUGH */
  380.         f = cmdprt;
  381.         break;
  382.  
  383.         }
  384.         break;
  385.     case '=':
  386.         f = cmdprt;
  387.         g = getdot;
  388.         if (PEEKC != '\n')
  389.         getfmt (fmt);
  390.         break;
  391.     case '\r':
  392.     case '\n':
  393.         c = lc;
  394.         break;
  395.     default:
  396.         f = null;
  397.         count = 1;
  398.         break;
  399.     }
  400.  
  401.     dotoff = 0;
  402.     if (f == cmdprt && g != getdot && 'a' != *fmt) {
  403.         prtad (DOT);
  404.         putchr (':');
  405.         putchr ('\n');
  406.     }
  407.     while (count--) {
  408.         (*f) (c, fmt, g);
  409.         if (chkbrk ())
  410.         break;
  411.     }
  412.     if (f == cmdprt && g != getdot)
  413.         dot += dotoff;
  414.     lc = c;
  415.     if (f == cmdcol) {    /* change 'jumps' to 'nexts' */
  416.         if ('j' == lc || 'J' == lc)
  417.         lc += ('n' - 'j');
  418.     }
  419.     while (getchr (0) != '\n');
  420.  
  421.     if ((!top) && (lb_cur >= lb_fill)) {
  422.         optnl ();
  423.         break;
  424.     }
  425.     }                /* for (;;) */
  426.     return;
  427. }
  428.  
  429. getchr (in_string)
  430.     int             in_string;
  431. {
  432.     char            c;
  433.  
  434.     if (lastc) {
  435.     c = lastc;
  436.     lastc = 0;
  437.     }
  438.     else {
  439.     if (lb_cur >= lb_fill) {
  440.         getline ();
  441.     }
  442.     c = lbuf[lb_cur++];
  443.     if (!in_string) {
  444.         if (';' == c)
  445.         c = '\n';
  446.     }
  447.     }
  448.     return c;
  449. }
  450.  
  451. getline ()
  452. /*
  453.  * Get keyboard input if we run out of  characters from a console buffer
  454.  * - echo received characters
  455.  */
  456. {
  457.     char            c;
  458.  
  459.     optnl ();
  460.     prt ("> ");            /* print prompt character */
  461.     l_restart = lb_fill = lb_cur = 0;
  462.     w_restart = 2;        /* printing starts after prompt */
  463.     while (lb_fill <= LINESZ) {
  464.     if (lb_fill > (LINESZ - 2)) {
  465.         getachr = getkchr;
  466.     }
  467.     if (0 == (c = (*getachr) ()))
  468.         continue;
  469.     if (c == '\b') {
  470.         if (lb_fill > l_restart) {
  471.         --lb_fill;
  472.         }
  473.         lbuf[lb_fill] = '\0';
  474.     }
  475.     else {
  476.         if (LINESZ == lb_fill)
  477.         c = '\n';
  478.         lbuf[lb_fill++] = c;
  479.     }
  480.     putchr (c);        /* putchr handles '\b' in a special way */
  481.     if (c == '\n')
  482.         break;
  483.     }
  484.     return;
  485. }
  486.  
  487. void
  488. src_line (buf)
  489.     char           *buf;
  490. /*
  491.  * Source adb commands from a buffer buf - buf has to be terminated
  492.  * by a newline character.  Bad things will happen if this is not true.
  493.  */
  494. {
  495.  
  496.     register char  *loc;
  497.     void            adb ();
  498.     char           *sv_lbuf;
  499.     int             sv_cur;
  500.     int             sv_fill;
  501.     int             sv_lc;
  502.  
  503.     if ((char *) 0 == buf)
  504.     return;
  505.  
  506.     sv_lbuf = lbuf;
  507.     sv_cur = lb_cur;
  508.     sv_fill = lb_fill;
  509.     sv_lc = lastc;
  510.     /* count characters in a new input buffer - newline inclusive */
  511.     loc = buf;
  512.     while ('\n' != *loc)
  513.     loc++;
  514.     loc++;
  515.  
  516.     lastc = 0;
  517.     lbuf = buf;
  518.     lb_cur = 0;
  519.     lb_fill = loc - buf;
  520.     /* execute comands - if not at the top adb will return at EOBuf */
  521.     adb (0);
  522.     /* restore previous input stream */
  523.     lastc = sv_lc;
  524.     lbuf = sv_lbuf;
  525.     lb_cur = sv_cur;
  526.     lb_fill = sv_fill;
  527.     return;
  528. }
  529.  
  530. int
  531. getkchr ()
  532. /*
  533.  * Read one character from a console - no echo.
  534.  */
  535. {
  536.     long            gemdos ();
  537.     union {
  538.     long            full;
  539.     struct {
  540.         short           high;
  541.         short           low;
  542.     }               part;
  543.     }               kcode;
  544.     register int    c;
  545.     void            fkey ();
  546. #ifdef HELP
  547.     void            help ();
  548. #endif
  549.  
  550.     for (;;) {
  551.     kcode.full = gemdos (7);
  552.  
  553.     if (0 == (c = (short) kcode.full & 0xff)) {    /* hack attack!! */
  554.         c = kcode.part.high;
  555.  
  556.         if (c >= 0x3b && c <= 0x44) {    /* unshifted function key */
  557.         fkey (c - 0x3b);
  558.         return (0);
  559.         }
  560.         else if (c >= 0x54 && c <= 0x5d) {    /* shifted function key */
  561.         fkey (c - (0x54 - 0x0a));
  562.         return (0);
  563.         }
  564. #ifdef HELP
  565.         else if (c == 0x62) {    /* help key */
  566.         help ();
  567.         }
  568. #endif
  569.         continue;        /* ignore other */
  570.     }
  571.     else {            /* low part code non-zero */
  572.         if (c == CNTLW) {
  573.         winswtch ();
  574.         c = gemdos (7);
  575.         winswtch ();
  576.         continue;
  577.         }
  578.         else if (c == CNTLC || c == CNTLS)
  579.         continue;
  580.     }
  581.     break;            /* any other key not matched so far */
  582.     }                /* for (;;) */
  583.  
  584.     if (c == '\r')
  585.     c = '\n';
  586.  
  587.     return (c);
  588. }
  589.  
  590. int
  591. getschr ()
  592. /*
  593.  * Return one character from a location 'csource' and advance.
  594.  * Revert input to console when found '\n' or '\0'.
  595.  * Used to insert stored strings into a CONSOLE buffer.
  596.  */
  597. {
  598.     int             c;
  599.  
  600.     if ('\n' == (c = *csource++))
  601.     c = 0;
  602.     if (0 == c)
  603.     getachr = getkchr;
  604.     return (c);
  605. }
  606.  
  607. void
  608. fkey (num)
  609.     int             num;
  610. /*
  611.  * If buffer number num non-empty set input reader to use it.
  612.  */
  613. {
  614.     if (ftable && 0 != (csource = ftable[num])) {
  615.     getachr = getschr;
  616.     }
  617. }
  618.  
  619. chkbrk ()
  620. {
  621.     char            c;
  622.  
  623.     if (gemdos (11) == 0)    /* any chars pending ? */
  624.     return 0;
  625.     c = gemdos (7) & 0xff;
  626.     if (c == CNTLC)
  627.     return 1;
  628.     else if (c == CNTLS) {
  629.     c = gemdos (7) & 0xff;
  630.     if (c == CNTLC)
  631.         return 1;
  632.     }
  633.     return 0;
  634. }
  635.  
  636. #ifdef GONER
  637. int
  638. pushc (c)
  639.     int             c;
  640. {
  641.     lastc = c;
  642. }
  643.  
  644. peekc ()
  645. {
  646.  
  647.     return (pushc (nb ()));
  648. }
  649.  
  650. #endif                /* GONER */
  651.  
  652. nb ()
  653. {
  654.     register int    c;
  655.  
  656.     while ((c = getchr (0)) == ' ' || c == '\t');
  657.     if (c == '\n')
  658.     PUSHC (c);
  659.     return (c);
  660. }
  661.  
  662. type (c)
  663.     char            c;
  664. {
  665.  
  666.     if (c >= '0' && c <= '9')
  667.     return (NUMERIC);
  668.     if (c >= 'a' && c <= 'f')
  669.     return (HEX);
  670.     if (c >= 'A' && c <= 'F')
  671.     return (HEX);
  672.     if (c >= 'g' && c <= 'z')
  673.     return (ALPHA);
  674.     if (c >= 'G' && c <= 'Z')
  675.     return (ALPHA);
  676.     if (c == '_')
  677.     return (ALPHA);
  678.     switch (c) {
  679.     case '$':
  680.     case ':':
  681.     case '?':
  682.     case '/':
  683.     case '=':
  684.     case ',':
  685.     case '>':
  686.     case '\r':
  687.     case '\n':
  688.     return (SPECCMD);
  689.     }
  690.     return (SPECX);
  691. }
  692.  
  693. long
  694. expr ()
  695. {
  696.     long            term ();
  697.     long            r;
  698.     int             c;
  699.  
  700.     r = term ();
  701.     for (;;)
  702.     switch (c = nb ()) {
  703.     case '+':
  704.         r += term ();
  705.         break;
  706.     case '-':
  707.         r -= term ();
  708.         break;
  709.     case '*':
  710.         r *= term ();
  711.         break;
  712.     case '%':
  713.         r /= term ();
  714.         break;
  715.     case '&':
  716.         r &= term ();
  717.         break;
  718.     case '|':
  719.         r |= term ();
  720.         break;
  721.     case ')':
  722.     default:
  723.         PUSHC (c);
  724.         return (r);
  725.     }
  726. }
  727.  
  728. long
  729. term ()
  730. {
  731.     long            n;
  732.     long            getn (), findval (), atonum ();
  733.     register int    c;
  734.     char           *cp, buf[80];
  735.     struct symbol  *sp, *findnam ();
  736.     struct regs    *rp, *findreg ();
  737.     int             erridx;
  738.  
  739.     if ((c = nb ()) == '(') {
  740.     n = expr ();
  741.     if (nb () != ')')
  742.         error (UNBAL);
  743.     return (n);
  744.     }
  745.     else if (c == '\'') {
  746.     n = 0;
  747.     while ((c = getchr (1)) != '\'')
  748.         if (c == '\n') {
  749.         PUSHC (c);
  750.         break;
  751.         }
  752.         else
  753.         n = (n << 8) | c;
  754.     return (n);
  755.     }
  756.     else if (c == '-') {
  757.     n = term ();
  758.     return -n;
  759.     }
  760.     else if (c == '~') {
  761.     n = term ();
  762.     return ~n;
  763.     }
  764.     else if (c == '<') {
  765.     cp = buf;
  766.     while (type (c = getchr (0)) & ALPHANUM)
  767.         *cp++ = c;
  768.     *cp = '\0';
  769.     PUSHC (c);
  770.     if (rp = findreg (buf))
  771.         return *rp->value;
  772.     n = findval (buf, &erridx);    /* no register? - try read-only
  773.                      * variable */
  774.     if (0 != erridx) {
  775.         error (BADRNAME);
  776.     }
  777.     return n;
  778.     }
  779.     else if (c == '*') {
  780.     n = term ();
  781.     n = getn (n, 4);
  782.     return n;
  783.     }
  784.     else if (c == '@') {
  785.     n = term ();
  786.     n = getn (n, 2);
  787.     return n;
  788.     }
  789.     else if (c == '.') {
  790.     return dot;
  791.     }
  792.     else if (c == '&') {
  793.     return olddot;
  794.     }
  795.     else {            /* get the whole term into a buffer */
  796.     cp = buf;
  797.     if (16 != swidth && '_' != c) {    /* standard symbol name - not MWC */
  798.         *cp++ = '_';
  799.     }
  800.     *cp++ = c;
  801.     while (type (c = getchr (0)) & ALPHANUM)
  802.         *cp++ = c;
  803.     *cp = '\0';
  804.     PUSHC (c);
  805.     if (type (*(buf + 1)) & ALPHAONLY) {
  806.         /* don't search if number for sure */
  807.         if (sp = findnam (buf, binary.symptr))
  808.         return (sp->value);
  809.         if (16 != swidth) { /* if not MWC */
  810.         if (sp = findnam (buf + 1, binary.symptr))
  811.             return (sp->value);
  812.         }
  813.         else { /* not found so far and MWC */
  814.         *cp++ = '_';
  815.         *cp = '\0';
  816.         if (sp = findnam (buf, binary.symptr))
  817.             return (sp->value);
  818.         *(cp - 1) = '\0'; /* we will try a number */
  819.         }
  820.     }
  821.     /* if not symbol or not found - try convert to a number */
  822.     n = atonum (buf + (16 != swidth ? 1 : 0), ibase, &erridx);
  823.     if (0 != erridx) {
  824.         error (BADNAME);
  825.     }
  826.     return (n);
  827.     }
  828. }
  829.  
  830. null (c, fmt, get)
  831.     int             c;
  832.     char           *fmt;
  833.     long            (*get) ();
  834. {
  835. /*    prtf("unknown command\n");    */
  836.     prtf (M6);
  837.     return (0);
  838. }
  839.  
  840. cmddol (c, fmt, get)
  841.     int             c;
  842.     char           *fmt;
  843.     long            (*get) ();
  844. {
  845.     extern struct regs regs[];
  846.     int             i;
  847.     void            tofile (), hndlfkey ();
  848.  
  849.     switch (c) {
  850.     case 'q':
  851.     exit (0);
  852.     case 'd':
  853.     ibase = 10;
  854.     break;
  855.     case 'o':
  856.     ibase = 8;
  857.     break;
  858.     case 'x':
  859.     ibase = 16;
  860.     break;
  861.     case 's':
  862.     maxoff = dot;
  863.     break;
  864.     case 'e':
  865.     prtstbl (binary.symptr);
  866.     break;
  867.     case 'b':
  868.     PrBptList ();
  869.     break;
  870.     case 'r':
  871.     prregs ();
  872.     prbpt (*(regs[PC].value));
  873.     putchr ('\n');
  874.     break;
  875.     case 'p':
  876.     prbasepg ();
  877.     break;
  878.     case 'c':
  879.     case 'C':
  880.     prstack (c == 'C');
  881.     break;
  882.     case 'k':
  883.     hndlfkey ();
  884.     break;
  885.     case '>':
  886.     tofile ();
  887.     break;
  888.     default:
  889.     error (UNKNOWN);
  890.     break;
  891.     }
  892.     return (0);
  893. }
  894.  
  895. prregs ()
  896. {
  897.     struct regs    *rp;
  898.  
  899.     prtreg (®s[PC]);
  900.     prtreg (®s[XSP]);
  901.     prt_sr ();
  902.     optnl ();
  903.  
  904.     rp = ®s[D0];
  905.     while (rp < ®s[NREGS])
  906.     prtreg (rp++);
  907.     optnl ();
  908. }
  909.  
  910. prtreg (rp)
  911.     struct regs    *rp;
  912. {
  913.     int             i;
  914.  
  915.     i = strlen (rp->name);
  916.     prt (rp->name);
  917.     prtn (*(rp->value), 15 - i);
  918.     prt ("    ");
  919.     return;
  920. }
  921.  
  922. prtstbl (sp)
  923. struct symbol  *sp;
  924. {
  925.     register int lcount, wsz;
  926.     int key;
  927.  
  928.     if (sp) {
  929.     wsz = w.lines - 1;
  930.     lcount = wsz--;
  931.     for(;;) {
  932.         prt (sp->name);
  933.         prt (": ");
  934.         prtn (sp->value, 0);
  935.         putchr ('\n');
  936.         if (!(sp = sp->next))
  937.         break;
  938.         if (0 == --lcount) {
  939.         key = gemdos(7) & 0xff;
  940.         if ('q' == key || CNTLC == key || 'Q' == key)
  941.             break;
  942.         lcount = wsz;
  943.         }
  944.         if (chkbrk ())
  945.         break;
  946.     }
  947.     }
  948.     return;
  949. }
  950.  
  951. cmdwrt (c, fmt, get)
  952.     char            c;
  953.     char           *fmt;
  954.     long            (*get) ();
  955. {
  956.     long            l;
  957.  
  958.     c = nb ();
  959.     l = expr ();
  960.     putn (l, DOT, c == 'w' ? 2 : 4, 1);
  961.     return;
  962. }
  963.  
  964. cmdprt (c, fmt, get)
  965.     int             c;
  966.     char           *fmt;
  967.     long            (*get) ();
  968. {
  969.     register int    c1;
  970.     long           *ip;
  971.     struct symbol  *sp;
  972.     long            getdot ();
  973.     int             rep, incr, oldoff;
  974.  
  975.     incr = 0;
  976.     while (c = *fmt++) {
  977.     if (c >= '0' && c <= '9') {
  978.         rep = c - '0';
  979.         while ((c = *fmt++) >= '0' && c <= '9')
  980.         rep = 10 * rep + (c - '0');
  981.     }
  982.     else
  983.         rep = 1;
  984.  
  985.     if (c == 't')
  986.         tab (rep);
  987.     else if (c == '^')
  988.         dotoff -= rep * incr;
  989.     else
  990.         while (rep--) {
  991.  
  992.         oldoff = dotoff;
  993.  
  994.         switch (c) {
  995.         case 'a':
  996.         case 'p':
  997.             prtad (DOT);
  998.             if (c == 'a')
  999.             putchr (':');
  1000.             tab (ALIGN_A);
  1001.             break;
  1002.         case 'i':
  1003.             if (get == getdot)
  1004.             error (BADCMD);
  1005.             puti ();
  1006.             putchr ('\n');
  1007.             break;
  1008.         case 'o':
  1009.             puto ((*get) (DOT, 2) & 0xffff, 9);
  1010.             break;
  1011.         case 'O':
  1012.             puto ((*get) (DOT, 4), 19);
  1013.             break;
  1014.         case 'd':
  1015.             putd ((*get) (DOT, 2), 9);
  1016.             break;
  1017.         case 'D':
  1018.             putd ((*get) (DOT, 4), 19);
  1019.             break;
  1020.         case 'x':
  1021.             putx ((*get) (DOT, 2) & 0xffff, 9);
  1022.             break;
  1023.         case 'X':
  1024.             putx ((*get) (DOT, 4), 19);
  1025.             break;
  1026.         case 'b':
  1027.             puto ((*get) (DOT, 1) & 0xff, 4);
  1028.             break;
  1029.         case 'c':
  1030.             w_curs (0);
  1031.             w_put  ((char) (*get) (DOT, 1));
  1032.             w_curs (1);
  1033.             break;
  1034.         case 'S':
  1035.         case 's':
  1036.             if (get == getdot)
  1037.             error (BADCMD);
  1038.             while (c1 = (char) (*get) (DOT, 1)) {
  1039.             if ((c == 'S') && (c1 < ' ' || c1 > 127))
  1040.                 c1 = '.';
  1041.             putchr (c1);
  1042.             }
  1043.             break;
  1044.         case '"':
  1045.             while ((c = *fmt++) != '"' && c)
  1046.             putchr (c);
  1047.             if (c != '"')
  1048.             fmt--;
  1049.             break;
  1050.         case 'r':
  1051.             putchr (' ');
  1052.             break;
  1053.         case 'n':
  1054.             putchr ('\n');
  1055.             break;
  1056.         case '+':
  1057.             dotoff++;
  1058.             break;
  1059.         case '-':
  1060.             dotoff--;
  1061.             break;
  1062.         default:
  1063.             putchr (c);
  1064.             break;
  1065.         }
  1066.         incr = dotoff - oldoff;
  1067.         }
  1068.     }
  1069.     return;
  1070. }
  1071.  
  1072. error (why)
  1073. {
  1074.     lb_cur = lb_fill;        /* skip the rest of an input buffer */
  1075.     prt (errwhy[why]);
  1076.     lbuf = CONSOLE;
  1077.     lastc = 0;
  1078.     longjmp (jmpb, 1);
  1079. }
  1080.  
  1081. prtad (where)
  1082.     long            where;
  1083. {
  1084.     struct symbol  *sp, *findsym ();
  1085.  
  1086.     if ((sp = findsym (where, binary.symptr)))
  1087.     prtsym (where, sp);
  1088.     else
  1089.     prtn (where, 0);
  1090.     return;
  1091. }
  1092.  
  1093. prt_sr ()
  1094. {
  1095.     long            sr;
  1096.     int             i;
  1097.  
  1098.     sr = *regs[SR].value;
  1099.     prtf ("sr %I -> ", sr);
  1100.     if (sr & 0x2000)
  1101.     prt ("Supv");
  1102.     else
  1103.     prt ("User");
  1104.  
  1105.     prtf (" pri%I ", (sr >> 8) & 7);
  1106.  
  1107.     for (i = 4; i >= 0; i--)
  1108.     if (sr & (1 << i))
  1109.         putchr ("CVZNX"[i]);
  1110.     putchr ('\n');
  1111. }
  1112.  
  1113. struct regs    *
  1114. findreg (s)
  1115.     char           *s;
  1116. {
  1117.     struct regs    *rp;
  1118.  
  1119.     if (strcmp (s, "a7") == 0)
  1120.     s = "sp";
  1121.     for (rp = regs; rp->value; rp++)
  1122.     if (strcmp (s, rp->name) == 0)
  1123.         return rp;
  1124.  
  1125.     return 0;
  1126. }
  1127.  
  1128. void
  1129. tofile ()
  1130. {
  1131.     void            trclose ();
  1132.  
  1133.     trclose ();
  1134.     if (PEEKC != '\n') {
  1135.     getfmt (trname);
  1136.     if ((trid = (access (trname, 0x00) ?
  1137.              open (trname, O_WRONLY | O_CREAT, 0) :
  1138.              open (trname, O_WRONLY | O_APPEND))) < -3) {
  1139.         /* prtf("%s:cannot open\n", trname);     */
  1140.         prtf (M1, trname);
  1141. #ifdef DEBUG
  1142.         prtf ("error number = ");
  1143.         putd ((long) trid, 0);
  1144.         prtf ("\n");
  1145. #endif
  1146.         trid = NO_TRANS;
  1147.     }
  1148. #ifdef DEBUG
  1149.     else {
  1150.         prtf ("opened file %s with id = ", trname);
  1151.         prtn ((long) trid, 0);
  1152.         prtf ("\n");
  1153.     }
  1154. #endif
  1155.     }
  1156.     return;
  1157. }
  1158.  
  1159. void
  1160. trclose ()
  1161. {
  1162.     extern void     trflush ();
  1163.  
  1164.     if (trid != NO_TRANS) {
  1165.     trflush ();
  1166.     close (trid);
  1167.     trid = NO_TRANS;
  1168.     }
  1169.     return;
  1170. }
  1171.