home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / szadb / adb.c next >
C/C++ Source or Header  |  1991-03-01  |  12KB  |  801 lines

  1. /* Copyright (c) 1990,91 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. #include <setjmp.h>
  15. #include "adb.h"
  16.  
  17. #define IN_ADB
  18. #include "lang.h"
  19.  
  20. #define CNTLC    3
  21. #define CNTLS    0x13
  22. #define CNTLW    0x17
  23.  
  24. struct file binary;
  25.  
  26. long dot;
  27. int dotoff;
  28. long olddot;
  29.  
  30. #define DOT    (dot+dotoff)
  31.  
  32. int dotset;
  33. long maxoff = 256;
  34. int ibase = 16;
  35.  
  36. int lastc = 0;
  37. char sign = 0;
  38.  
  39. unsigned long regbuf[19];
  40.  
  41. struct regs regs[] = {
  42.     "pc",    ®buf[16],
  43.     "sr",    ®buf[17],
  44.     "xsp",    ®buf[18],
  45.     "d0",    ®buf[0],
  46.     "d1",    ®buf[1],
  47.     "d2",    ®buf[2],
  48.     "d3",    ®buf[3],
  49.     "d4",    ®buf[4],
  50.     "d5",    ®buf[5],
  51.     "d6",    ®buf[6],
  52.     "d7",    ®buf[7],
  53.     "a0",    ®buf[8],
  54.     "a1",    ®buf[9],
  55.     "a2",    ®buf[10],
  56.     "a3",    ®buf[11],
  57.     "a4",    ®buf[12],
  58.     "a5",    ®buf[13],
  59.     "a6",    ®buf[14],
  60.     "sp",    ®buf[15],
  61.     "", 0,
  62. };
  63.  
  64. #define NREGS    19
  65.  
  66. jmp_buf jmpb, trp_buf;
  67.  
  68. _main()
  69. {
  70.     extern int _argc;
  71.     extern char **_argv;
  72.  
  73.     main(_argc, _argv);
  74.     exit(0);
  75. }
  76.  
  77. main(argc, argv)
  78. int argc;
  79. char *argv[];
  80. {
  81.     char *cp;
  82.     extern long ossp;
  83.  
  84.     winopen();
  85.     binary.symptr = 0;
  86.     binary.flags = 0;
  87.     if (argc != 2) {
  88.         prtf("Usage: adb binary\n");
  89.         seeerr();
  90.         exit(1);
  91.     }
  92.     binary.name = argv[1];
  93.  
  94.     if ((binary.fid = open(binary.name, 0)) < 0) {
  95. /*        prtf("%s:cannot open\n", binary.name);    */
  96.         prtf(M1, binary.name);
  97.         seeerr();
  98.         exit(2);
  99.     }
  100.     if (setobj(&binary) != 0) {
  101. /*        prtf("%s:bad format\n", binary.name);    */
  102.         prtf(M2, binary.name);
  103.         seeerr();
  104.         exit(3);
  105.     }
  106.     if (loadpcs() != 0) {
  107. /*        prtf("%s:bad pexec\n", binary.name);    */
  108.         prtf(M3, binary.name);
  109.         seeerr();
  110.         exit(4);
  111.     }
  112.     close(binary.fid);
  113.     relsym();
  114.     vects();
  115. /*    prt("Szadb version 2.0 (english)\n");    */
  116.     prt(M4);
  117.     if (setjmp(trp_buf)) {
  118.         seeerr();
  119.         exit(0);
  120.     }
  121.     adb();
  122. }
  123.  
  124. exit(n)
  125. {
  126.     oldvects();
  127.     winclose();
  128.     _exit(n);
  129. }
  130.  
  131. seeerr()
  132. {
  133. /*    prt("(hit any key)");    */
  134.     prt(M5);
  135.     gemdos(7);
  136. }
  137.  
  138. setobj(fp)
  139. struct file *fp;
  140. {
  141.     struct fheader hdr;
  142.  
  143.     if (read(fp->fid, &hdr, sizeof(hdr)) != sizeof(hdr))
  144.         return -1;
  145.     if (hdr.magic != MAGIC)
  146.         return -1;
  147.     if (hdr.ssize) {
  148.         lseek(fp->fid, hdr.tsize + hdr.dsize, 1);
  149.         return setsym(fp, (int)(hdr.ssize/sizeof(struct filsym)));
  150.     }
  151.     return 0;
  152. }
  153.  
  154. adb()
  155. {
  156.     int cmddol(), cmdcol(), cmdprt(), cmdwrt(), cmdsreg(), null();
  157.     long getn(), getdot();
  158.     long expr();
  159.     int intr();
  160.     register int c, lc, count;
  161.     int (*f)();
  162.     long (*g)();
  163.     char fmt[128];
  164.  
  165.     f = cmdprt;
  166.     g = getdot;
  167.     lc = '=';
  168.     dot = 0;
  169.     dotoff = 0;
  170.     setjmp(jmpb);
  171.  
  172.     for (;;) {
  173.         prt("> ");
  174.         dotoff = 0;
  175.         c = peekc();
  176.         if (type(c) & (ALPHANUM | SPECX)) {
  177.             dot = expr();
  178.             olddot = dot;
  179.             dotset = 1;
  180.         } else
  181.             dotset = 0;
  182.         if (peekc() == ',') {
  183.             nb();
  184.             count = expr();
  185.         } else
  186.             count = 1;
  187.  
  188.         switch (c = nb()) {
  189.         case '>':
  190.             f = cmdsreg;
  191.             break;
  192.         case '$':
  193.             c = nb();
  194.             f = cmddol;
  195.             break;
  196.         case ':':
  197.             c = nb();
  198.             f = cmdcol;
  199.             break;
  200.         case '?':
  201.         case '/':
  202.             g = getn;
  203.             switch (peekc()) {
  204.  
  205.             case 'w':
  206.             case 'W':
  207.                 f = cmdwrt;
  208.                 break;
  209.             default:
  210.                 f = cmdprt;
  211.                 getfmt(fmt);
  212.             case '\n':
  213.                 f = cmdprt;
  214.                 break;
  215.  
  216.             }
  217.             break;
  218.         case '=':
  219.             f = cmdprt;
  220.             g = getdot;
  221.             if (peekc() != '\n')
  222.                 getfmt(fmt);
  223.             break;
  224.         case '\r':
  225.         case '\n':
  226.             c = lc;
  227.             break;
  228.         default:
  229.             f = null;
  230.             count = 1;
  231.             break;
  232.         }
  233.  
  234.         dotoff = 0;
  235.         if (f == cmdprt && g != getdot) {
  236.             prtad(DOT);
  237.             putchr(':');
  238.             putchr('\n');
  239.         }
  240.         while (count--) {
  241.             (*f)(c, fmt, g);
  242.             if (chkbrk())
  243.                 break;
  244.         }
  245.         if (f == cmdprt && g != getdot)
  246.             dot += dotoff;
  247.         lc = c;
  248.         while (getchr() != '\n')
  249.             ;
  250.     }
  251. }
  252.  
  253. #define LINESZ    80
  254. static char lbuf[LINESZ+1];
  255. static int lb_cur, lb_fill;
  256.  
  257. getchr()
  258. {
  259.     char c;
  260.  
  261.     if (lastc) {
  262.         c = lastc;
  263.         lastc = 0;
  264.         return c;
  265.     }
  266.  
  267.     if (lb_cur >= lb_fill)
  268.         getline();
  269.     c = lbuf[lb_cur++];
  270.     return c;
  271. }
  272.  
  273. getline()
  274. {
  275.     char c;
  276.  
  277.     lb_fill = lb_cur = 0;
  278.     while (lb_fill < LINESZ) {
  279.         c = getachr();
  280.         if (c == '\b') {
  281.             if (lb_fill) {
  282.                 putchr(c);
  283.                 lb_fill--;
  284.             }
  285.         } else
  286.             lbuf[lb_fill++] = c;
  287.         if (c == '\n')
  288.             return;
  289.     }
  290.     lbuf[lb_fill++] = '\n';
  291.     return;
  292. }
  293.  
  294. getachr()
  295. {
  296.     long gemdos(), l;
  297.     register int c;
  298.  
  299. again:
  300.     l = gemdos(7);
  301.  
  302.     if (l == 0x620000L) {
  303.         help();
  304.         goto again;
  305.     }
  306.     
  307.     c = l & 0xff;
  308.     if (c == CNTLW) {
  309.         winswtch();
  310.         c = gemdos(7);
  311.         winswtch();
  312.         goto again;
  313.     } else if (c == CNTLC || c == CNTLS)
  314.         goto again;
  315.  
  316.     if (c == '\r')
  317.         c = '\n';
  318.     if (c != '\b')    /* getline will echo \b if not at sol */
  319.         putchr(c);
  320.  
  321.     return(c);
  322. }
  323.  
  324. chkbrk()
  325. {
  326.     char c;
  327.  
  328.     if (gemdos(11) == 0)    /* any chars pending ? */
  329.         return 0;
  330.     c = gemdos(7) & 0xff;
  331.     if (c == CNTLC)
  332.         return 1;
  333.     else if (c == CNTLS) {
  334.         c = gemdos(7) & 0xff;
  335.         if (c == CNTLC)
  336.             return 1;
  337.     }
  338.     return 0;
  339. }
  340.  
  341. pushc(c)
  342. int c;
  343. {
  344.  
  345.     lastc = c;
  346.     return(c);
  347. }
  348.  
  349. peekc()
  350. {
  351.  
  352.     return(pushc(nb()));
  353. }
  354.  
  355. nb()
  356. {
  357.     register int c;
  358.  
  359.     while ((c = getchr()) == ' ' || c == '\t')
  360.         ;
  361.     if (c == '\n')
  362.         pushc(c);
  363.     return(c);
  364. }
  365.  
  366. type(c)
  367. char c;
  368. {
  369.  
  370.     if (c >= '0' && c <= '9')
  371.         return(NUMERIC);
  372.     if (c >= 'a' && c <= 'f')
  373.         return(HEX);
  374.     if (c >= 'A' && c <= 'F')
  375.         return(HEX);
  376.     if (c >= 'g' && c <= 'z')
  377.         return(ALPHA);
  378.     if (c >= 'G' && c <= 'Z')
  379.         return(ALPHA);
  380.     if (c == '_')
  381.         return(ALPHA);
  382.     switch (c) {
  383.     case '$':
  384.     case ':':
  385.     case '?':
  386.     case '/':
  387.     case '=':
  388.     case ',':
  389.     case '>':
  390.     case '\r':
  391.     case '\n':
  392.         return (SPECCMD);
  393.     }
  394.     return(SPECX);
  395. }
  396.  
  397. long
  398. expr()
  399. {
  400.     long term();
  401.     long r;
  402.     int c;
  403.  
  404.     r = term();
  405.     for (;;)
  406.         switch (c = nb()) {
  407.         case '+':
  408.             r += term();
  409.             break;
  410.         case '-':
  411.             r -= term();
  412.             break;
  413.         case '*':
  414.             r *= term();
  415.             break;
  416.         case '%':
  417.             r /= term();
  418.             break;
  419.         case '&':
  420.             r &= term();
  421.             break;
  422.         case '|':
  423.             r |= term();
  424.             break;
  425.         case ')':
  426.         default:
  427.             pushc(c);
  428.             return(r);
  429.         }
  430. }
  431.  
  432. long
  433. term()
  434. {
  435.     long n, getn();
  436.     register int c, base;
  437.     char *cp, buf[NAMEMAX+1];
  438.     struct symbol *sp, *findnam();
  439.     struct regs *rp, *findreg();
  440.  
  441.     if ((c = nb()) == '(') {
  442.         n = expr();
  443.         if (nb() != ')')
  444.             error(UNBAL);
  445.         return(n);
  446.     } else if (c == '\'') {
  447.         n = 0;
  448.         while ((c = getchr()) != '\'')
  449.             if (c == '\n') {
  450.                 pushc(c);
  451.                 break;
  452.             } else
  453.                 n = (n << 8) | c;
  454.         return(n);
  455.     } else if (c == '-') {
  456.         n = term();
  457.         return -n;
  458.     } else if (c == '~') {
  459.         n = term();
  460.         return ~n;
  461.     } else if (c == '<') {
  462.         cp = buf;
  463.         while (type(c = getchr()) & ALPHANUM)
  464.             *cp++ = c;
  465.         *cp = '\0';
  466.         pushc(c);
  467.         if (rp = findreg(buf))
  468.             return *rp->value;
  469.         error(BADRNAME);
  470.     } else if (c == '*') {
  471.         n = term();
  472.         n = getn(n, 4);
  473.         return n;
  474.     } else if (c == '@') {
  475.         n = term();
  476.         n = getn(n, 2);
  477.         return n;
  478.     } else if (c == '.') {
  479.         return dot;
  480.     } else if (c == '&') {
  481.         return olddot;
  482.     } else if (type(c) & ALPHAONLY) {
  483.         cp = buf;
  484.         *cp++ = '_';
  485.         *cp++ = c;
  486.         while (type(c = getchr()) & ALPHANUM)
  487.             *cp++ = c;
  488.         *cp = '\0';
  489.         pushc(c);
  490.         if (sp = findnam(buf + 1, binary.symptr))
  491.             return(sp->value);
  492.         else if (sp = findnam(buf, binary.symptr))
  493.             return(sp->value);
  494.         error(BADNAME);
  495.     }
  496.     n = 0;
  497.     base = ibase;
  498.     if (c == '0') {
  499.         base = 8;
  500.         switch (pushc(getchr())) {
  501.         case 'x':
  502.             base += 6;
  503.         case 't':
  504.             base += 2;
  505.         case 'o':
  506.             getchr();
  507.             c = getchr();
  508.             break;
  509.         default:
  510.             base = ibase;
  511.             break;
  512.         }
  513.     }
  514.     while (type(c) & HEXDIG) {
  515.         if (c >= 'a' && c <= 'f')
  516.             c -= 'a' - '9' - 1;
  517.         if (c >= 'A' && c <= 'F')
  518.             c -= 'A' - '9' - 1;
  519.         n = (n * base) + (c - '0');
  520.         c = getchr();
  521.     }
  522.     pushc(c);
  523.     return(n);
  524. }
  525.  
  526. null(c, fmt, get)
  527. int c;
  528. char *fmt;
  529. long (*get)();
  530. {
  531. /*    prtf("unknown command\n");    */
  532.     prtf(M6);
  533.     return(0);
  534. }
  535.  
  536. cmddol(c, fmt, get)
  537. int c;
  538. char *fmt;
  539. long (*get)();
  540. {
  541.     extern struct regs regs[];
  542.     extern struct bpt bpt[];
  543.     int i;
  544.  
  545.     switch (c) {
  546.     case 'q':
  547.         exit(0);
  548.     case 'd':
  549.         ibase = 10;
  550.         break;
  551.     case 'o':
  552.         ibase = 8;
  553.         break;
  554.     case 'x':
  555.         ibase = 16;
  556.         break;
  557.     case 's':
  558.         maxoff = dot;
  559.         break;
  560.     case 'e':
  561.         prtstbl(binary.symptr);
  562.         break;
  563.     case 'b':
  564.         for (i = 0; i < MAXBPTS; i++)
  565.             if (bpt[i].flag & BP_VALID)
  566.                 prbpt(bpt[i].addr);
  567.         break;
  568.     case 'r':
  569.         prregs();
  570.         prbpt(*(regs[PC].value));
  571.         break;
  572.     case 'p':
  573.         prbasepg();
  574.         break;
  575.     case 'c':
  576.     case 'C':
  577.         prstack(c == 'C');
  578.         break;
  579.     default:
  580.         error(UNKNOWN);
  581.         break;
  582.     }
  583.     return(0);
  584. }
  585.  
  586. prregs()
  587. {
  588.     struct regs *rp;
  589.  
  590.     prtreg(®s[PC]);
  591.     prtreg(®s[XSP]);
  592.     prt_sr();
  593.     optnl();
  594.  
  595.     rp = ®s[D0];
  596.     while (rp < ®s[NREGS])
  597.         prtreg(rp++);
  598.     optnl();
  599. }
  600.  
  601. prtreg(rp)
  602. struct regs *rp;
  603. {
  604.     int i;
  605.  
  606.     i = strlen(rp->name);
  607.     prt(rp->name);
  608.     prtn(*(rp->value), 15-i);
  609.     prt("    ");
  610.     return;
  611. }
  612.  
  613. prtstbl(sp)
  614. struct symbol *sp;
  615. {
  616.     while (sp) {
  617.         prt(sp->name);
  618.         prt(": ");
  619.         prtn(sp->value, 0);
  620.         putchr('\n');
  621.         sp = sp->next;
  622.         if (chkbrk())
  623.             return;
  624.     }
  625.     return;
  626. }
  627.  
  628. cmdwrt(c, fmt, get)
  629. char c;
  630. char *fmt;
  631. long (*get)();
  632. {
  633.     long l;
  634.  
  635.     c = nb();
  636.     l = expr();
  637.     putn(l, DOT, c == 'w' ? 2 : 4, 1);
  638.     return;
  639. }
  640.  
  641. cmdprt(c, fmt, get)
  642. int c;
  643. char *fmt;
  644. long (*get)();
  645. {
  646.     register int c1;
  647.     long *ip;
  648.     struct symbol *sp;
  649.     long getdot();
  650.     int rep, incr, oldoff;
  651.  
  652.     incr = 0;
  653.     while (c = *fmt++) {
  654.         if (c >= '0' && c <= '9') {
  655.             rep = c - '0';
  656.             while ((c = *fmt++) >= '0' && c <= '9')
  657.                 rep = 10*rep + (c - '0');
  658.         } else
  659.             rep = 1;
  660.  
  661.         if (c == 't')
  662.             tab(rep);
  663.         else if (c == '^')
  664.             dotoff -= rep*incr;
  665.         else
  666.         while (rep--) {
  667.  
  668.         oldoff = dotoff;
  669.  
  670.         switch (c) {
  671.         case 'a':
  672.         case 'p':
  673.             prtad(DOT);
  674.             if (c == 'a')
  675.                 putchr(':');
  676.             tab(20);
  677.             break;
  678.         case 'i':
  679.             if (get == getdot)
  680.                 error(BADCMD);
  681.             puti();
  682.             putchr('\n');
  683.             break;
  684.         case 'o':
  685.             puto((*get)(DOT, 2) & 0xffff, 9);
  686.             break;
  687.         case 'O':
  688.             puto((*get)(DOT, 4), 19);
  689.             break;
  690.         case 'd':
  691.             putd((*get)(DOT, 2), 9);
  692.             break;
  693.         case 'D':
  694.             putd((*get)(DOT, 4), 19);
  695.             break;
  696.         case 'x':
  697.             putx((*get)(DOT, 2) & 0xffff, 9);
  698.             break;
  699.         case 'X':
  700.             putx((*get)(DOT, 4), 19);
  701.             break;
  702.         case 'b':
  703.             puto((*get)(DOT, 1) & 0xff, 4);
  704.             break;
  705.         case 'c':
  706.             putchr((char)(*get)(DOT, 1));
  707.             break;
  708.         case 'S':
  709.         case 's':
  710.             if (get == getdot)
  711.                 error(BADCMD);
  712.             while (c1 = (char)(*get)(DOT, 1)) {
  713.                 if ((c1 < ' ' || c1 > 127) && (c == 'S'))
  714.                     c1 = '.';
  715.                 putchr(c1);
  716.             }
  717.             break;
  718.         case '"':
  719.             while ((c = *fmt++) != '"' && c)
  720.                 putchr(c);
  721.             if (c != '"')
  722.                 fmt--;
  723.             break;
  724.         case 'r':
  725.             putchr(' ');
  726.             break;
  727.         case 'n':
  728.             putchr('\n');
  729.             break;
  730.         case '+':
  731.             dotoff++;
  732.             break;
  733.         case '-':
  734.             dotoff--;
  735.             break;
  736.         default:
  737.             putchr(c);
  738.             break;
  739.         }
  740.  
  741.         incr = dotoff - oldoff;
  742.  
  743.         }
  744.     }
  745.     optnl();
  746.     return;
  747. }
  748.  
  749. error(why)
  750. {
  751.  
  752.     while (getchr() != '\n')
  753.         ;
  754.     prt(errwhy[why]);
  755.     longjmp(jmpb, 1);
  756. }
  757.  
  758. prtad(where)
  759. long where;
  760. {
  761.     struct symbol *sp, *findsym();
  762.  
  763.     if ((sp = findsym(where, binary.symptr)))
  764.             prtsym(where, sp);
  765.         else
  766.             prtn(where, 0);
  767.     return;
  768. }
  769.  
  770. prt_sr()
  771. {
  772.     long sr;
  773.     int i;
  774.  
  775.     sr = *regs[SR].value;
  776.     prtf("sr %I -> ", sr);
  777.     if (sr & 0x2000)
  778.         prt("Supv");
  779.     else
  780.         prt("User");
  781.  
  782.     prtf(" pri%I ", (sr>>8) & 7);
  783.  
  784.     for (i=4; i>=0; i--)
  785.         if (sr & (1<<i))
  786.             putchr("CVZNX"[i]);
  787.     putchr('\n');
  788. }
  789.  
  790. struct regs *
  791. findreg(s)
  792. char *s;
  793. {
  794.     struct regs *rp;
  795.  
  796.     for (rp = regs; rp->value; rp++)
  797.         if (strcmp(s, rp->name) == 0)
  798.             return rp;
  799.     return 0;
  800. }
  801.