13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier *
33e12c5d1SDavid du Colombier * debugger
43e12c5d1SDavid du Colombier *
53e12c5d1SDavid du Colombier */
63e12c5d1SDavid du Colombier
73e12c5d1SDavid du Colombier #include "defs.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier char BADEQ[] = "unexpected `='";
113e12c5d1SDavid du Colombier
123e12c5d1SDavid du Colombier BOOL executing;
13061a3f44SDavid du Colombier extern Rune *lp;
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier char eqformat[ARB] = "z";
163e12c5d1SDavid du Colombier char stformat[ARB] = "zMi";
173e12c5d1SDavid du Colombier
183e12c5d1SDavid du Colombier ADDR ditto;
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier ADDR dot;
21*c93608ccSDavid du Colombier int dotinc;
223e12c5d1SDavid du Colombier WORD adrval, cntval, loopcnt;
233e12c5d1SDavid du Colombier int adrflg, cntflg;
243e12c5d1SDavid du Colombier
253e12c5d1SDavid du Colombier /* command decoding */
263e12c5d1SDavid du Colombier
command(char * buf,int defcom)273e12c5d1SDavid du Colombier command(char *buf, int defcom)
283e12c5d1SDavid du Colombier {
29219b2ee8SDavid du Colombier char *reg;
303e12c5d1SDavid du Colombier char savc;
31061a3f44SDavid du Colombier Rune *savlp=lp;
323e12c5d1SDavid du Colombier char savlc = lastc;
333e12c5d1SDavid du Colombier char savpc = peekc;
343e12c5d1SDavid du Colombier static char lastcom = '=', savecom = '=';
353e12c5d1SDavid du Colombier
363e12c5d1SDavid du Colombier if (defcom == 0)
373e12c5d1SDavid du Colombier defcom = lastcom;
383e12c5d1SDavid du Colombier if (buf) {
393e12c5d1SDavid du Colombier if (*buf==EOR)
403e12c5d1SDavid du Colombier return(FALSE);
413e12c5d1SDavid du Colombier clrinp();
42061a3f44SDavid du Colombier lp=(Rune*)buf;
433e12c5d1SDavid du Colombier }
443e12c5d1SDavid du Colombier do {
45219b2ee8SDavid du Colombier adrflg=expr(0); /* first address */
469a747e4fSDavid du Colombier if (adrflg){
479a747e4fSDavid du Colombier dot=expv;
489a747e4fSDavid du Colombier ditto=expv;
499a747e4fSDavid du Colombier }
503e12c5d1SDavid du Colombier adrval=dot;
51219b2ee8SDavid du Colombier
52219b2ee8SDavid du Colombier if (rdc()==',' && expr(0)) { /* count */
533e12c5d1SDavid du Colombier cntflg=TRUE;
543e12c5d1SDavid du Colombier cntval=expv;
553e12c5d1SDavid du Colombier } else {
563e12c5d1SDavid du Colombier cntflg=FALSE;
573e12c5d1SDavid du Colombier cntval=1;
583e12c5d1SDavid du Colombier reread();
593e12c5d1SDavid du Colombier }
60219b2ee8SDavid du Colombier
613e12c5d1SDavid du Colombier if (!eol(rdc()))
62219b2ee8SDavid du Colombier lastcom=lastc; /* command */
633e12c5d1SDavid du Colombier else {
643e12c5d1SDavid du Colombier if (adrflg==0)
653e12c5d1SDavid du Colombier dot=inkdot(dotinc);
663e12c5d1SDavid du Colombier reread();
673e12c5d1SDavid du Colombier lastcom=defcom;
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier switch(lastcom) {
703e12c5d1SDavid du Colombier case '/':
713e12c5d1SDavid du Colombier case '=':
723e12c5d1SDavid du Colombier case '?':
733e12c5d1SDavid du Colombier savecom = lastcom;
743e12c5d1SDavid du Colombier acommand(lastcom);
753e12c5d1SDavid du Colombier break;
763e12c5d1SDavid du Colombier
773e12c5d1SDavid du Colombier case '>':
783e12c5d1SDavid du Colombier lastcom = savecom;
793e12c5d1SDavid du Colombier savc=rdc();
80219b2ee8SDavid du Colombier if (reg=regname(savc))
81219b2ee8SDavid du Colombier rput(cormap, reg, dot);
823e12c5d1SDavid du Colombier else
833e12c5d1SDavid du Colombier error("bad variable");
843e12c5d1SDavid du Colombier break;
853e12c5d1SDavid du Colombier
863e12c5d1SDavid du Colombier case '!':
873e12c5d1SDavid du Colombier lastcom=savecom;
883e12c5d1SDavid du Colombier shell();
893e12c5d1SDavid du Colombier break;
903e12c5d1SDavid du Colombier
913e12c5d1SDavid du Colombier case '$':
923e12c5d1SDavid du Colombier lastcom=savecom;
933e12c5d1SDavid du Colombier printtrace(nextchar());
943e12c5d1SDavid du Colombier break;
953e12c5d1SDavid du Colombier
963e12c5d1SDavid du Colombier case ':':
973e12c5d1SDavid du Colombier if (!executing) {
983e12c5d1SDavid du Colombier executing=TRUE;
993e12c5d1SDavid du Colombier subpcs(nextchar());
1003e12c5d1SDavid du Colombier executing=FALSE;
1013e12c5d1SDavid du Colombier lastcom=savecom;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier break;
1043e12c5d1SDavid du Colombier
1053e12c5d1SDavid du Colombier case 0:
1063e12c5d1SDavid du Colombier prints(DBNAME);
1073e12c5d1SDavid du Colombier break;
1083e12c5d1SDavid du Colombier
1093e12c5d1SDavid du Colombier default:
1103e12c5d1SDavid du Colombier error("bad command");
1113e12c5d1SDavid du Colombier }
1123e12c5d1SDavid du Colombier flushbuf();
1133e12c5d1SDavid du Colombier } while (rdc()==';');
1143e12c5d1SDavid du Colombier if (buf == 0)
1153e12c5d1SDavid du Colombier reread();
1163e12c5d1SDavid du Colombier else {
1173e12c5d1SDavid du Colombier clrinp();
1183e12c5d1SDavid du Colombier lp=savlp;
1193e12c5d1SDavid du Colombier lastc = savlc;
1203e12c5d1SDavid du Colombier peekc = savpc;
1213e12c5d1SDavid du Colombier }
1223e12c5d1SDavid du Colombier
1233e12c5d1SDavid du Colombier if(adrflg)
1243e12c5d1SDavid du Colombier return dot;
1253e12c5d1SDavid du Colombier return 1;
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier /*
1293e12c5d1SDavid du Colombier * [/?][wml]
1303e12c5d1SDavid du Colombier */
1313e12c5d1SDavid du Colombier
1323e12c5d1SDavid du Colombier void
acommand(int pc)1333e12c5d1SDavid du Colombier acommand(int pc)
1343e12c5d1SDavid du Colombier {
1353e12c5d1SDavid du Colombier int eqcom;
136219b2ee8SDavid du Colombier Map *map;
1373e12c5d1SDavid du Colombier char *fmt;
138219b2ee8SDavid du Colombier char buf[512];
1393e12c5d1SDavid du Colombier
1403e12c5d1SDavid du Colombier if (pc == '=') {
141219b2ee8SDavid du Colombier eqcom = 1;
1423e12c5d1SDavid du Colombier fmt = eqformat;
143219b2ee8SDavid du Colombier map = dotmap;
1443e12c5d1SDavid du Colombier } else {
145219b2ee8SDavid du Colombier eqcom = 0;
1463e12c5d1SDavid du Colombier fmt = stformat;
147219b2ee8SDavid du Colombier if (pc == '/')
1483e12c5d1SDavid du Colombier map = cormap;
149219b2ee8SDavid du Colombier else
150219b2ee8SDavid du Colombier map = symmap;
1513e12c5d1SDavid du Colombier }
152219b2ee8SDavid du Colombier if (!map) {
1534de34a7eSDavid du Colombier snprint(buf, sizeof(buf), "no map for %c", pc);
154219b2ee8SDavid du Colombier error(buf);
1553e12c5d1SDavid du Colombier }
156219b2ee8SDavid du Colombier
157219b2ee8SDavid du Colombier switch (rdc())
158219b2ee8SDavid du Colombier {
1593e12c5d1SDavid du Colombier case 'm':
1603e12c5d1SDavid du Colombier if (eqcom)
1613e12c5d1SDavid du Colombier error(BADEQ);
1623e12c5d1SDavid du Colombier cmdmap(map);
1633e12c5d1SDavid du Colombier break;
1643e12c5d1SDavid du Colombier
1653e12c5d1SDavid du Colombier case 'L':
1663e12c5d1SDavid du Colombier case 'l':
1673e12c5d1SDavid du Colombier if (eqcom)
1683e12c5d1SDavid du Colombier error(BADEQ);
169219b2ee8SDavid du Colombier cmdsrc(lastc, map);
1703e12c5d1SDavid du Colombier break;
1713e12c5d1SDavid du Colombier
1723e12c5d1SDavid du Colombier case 'W':
1733e12c5d1SDavid du Colombier case 'w':
1743e12c5d1SDavid du Colombier if (eqcom)
1753e12c5d1SDavid du Colombier error(BADEQ);
176219b2ee8SDavid du Colombier cmdwrite(lastc, map);
1773e12c5d1SDavid du Colombier break;
1783e12c5d1SDavid du Colombier
1793e12c5d1SDavid du Colombier default:
1803e12c5d1SDavid du Colombier reread();
1813e12c5d1SDavid du Colombier getformat(fmt);
182219b2ee8SDavid du Colombier scanform(cntval, !eqcom, fmt, map, eqcom);
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier
1863e12c5d1SDavid du Colombier void
cmdsrc(int c,Map * map)187219b2ee8SDavid du Colombier cmdsrc(int c, Map *map)
1883e12c5d1SDavid du Colombier {
1894de34a7eSDavid du Colombier ulong w;
190219b2ee8SDavid du Colombier long locval, locmsk;
1913e12c5d1SDavid du Colombier ADDR savdot;
1923e12c5d1SDavid du Colombier ushort sh;
193219b2ee8SDavid du Colombier char buf[512];
194219b2ee8SDavid du Colombier int ret;
1953e12c5d1SDavid du Colombier
1963e12c5d1SDavid du Colombier if (c == 'L')
1973e12c5d1SDavid du Colombier dotinc = 4;
1983e12c5d1SDavid du Colombier else
1993e12c5d1SDavid du Colombier dotinc = 2;
2003e12c5d1SDavid du Colombier savdot=dot;
2013e12c5d1SDavid du Colombier expr(1);
2023e12c5d1SDavid du Colombier locval=expv;
2033e12c5d1SDavid du Colombier if (expr(0))
2043e12c5d1SDavid du Colombier locmsk=expv;
2053e12c5d1SDavid du Colombier else
2063e12c5d1SDavid du Colombier locmsk = ~0;
207219b2ee8SDavid du Colombier if (c == 'L')
208219b2ee8SDavid du Colombier while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval)
2093e12c5d1SDavid du Colombier dot = inkdot(dotinc);
210219b2ee8SDavid du Colombier else
211219b2ee8SDavid du Colombier while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
2123e12c5d1SDavid du Colombier dot = inkdot(dotinc);
213219b2ee8SDavid du Colombier if (ret < 0) {
2143e12c5d1SDavid du Colombier dot=savdot;
215219b2ee8SDavid du Colombier error("%r");
2163e12c5d1SDavid du Colombier }
217219b2ee8SDavid du Colombier symoff(buf, 512, dot, CANY);
218219b2ee8SDavid du Colombier dprint(buf);
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier
221219b2ee8SDavid du Colombier static char badwrite[] = "can't write process memory or text image";
222219b2ee8SDavid du Colombier
2233e12c5d1SDavid du Colombier void
cmdwrite(int wcom,Map * map)224219b2ee8SDavid du Colombier cmdwrite(int wcom, Map *map)
2253e12c5d1SDavid du Colombier {
2263e12c5d1SDavid du Colombier ADDR savdot;
227219b2ee8SDavid du Colombier char *format;
2283e12c5d1SDavid du Colombier int pass;
2293e12c5d1SDavid du Colombier
230219b2ee8SDavid du Colombier if (wcom == 'w')
231219b2ee8SDavid du Colombier format = "x";
232219b2ee8SDavid du Colombier else
233219b2ee8SDavid du Colombier format = "X";
2343e12c5d1SDavid du Colombier expr(1);
2353e12c5d1SDavid du Colombier pass = 0;
2363e12c5d1SDavid du Colombier do {
2373e12c5d1SDavid du Colombier pass++;
2383e12c5d1SDavid du Colombier savdot=dot;
239219b2ee8SDavid du Colombier exform(1, 1, format, map, 0, pass);
2403e12c5d1SDavid du Colombier dot=savdot;
241219b2ee8SDavid du Colombier if (wcom == 'W') {
242219b2ee8SDavid du Colombier if (put4(map, dot, expv) <= 0)
243219b2ee8SDavid du Colombier error(badwrite);
244219b2ee8SDavid du Colombier } else {
245219b2ee8SDavid du Colombier if (put2(map, dot, expv) <= 0)
246219b2ee8SDavid du Colombier error(badwrite);
247219b2ee8SDavid du Colombier }
2483e12c5d1SDavid du Colombier savdot=dot;
2493e12c5d1SDavid du Colombier dprint("=%8t");
250219b2ee8SDavid du Colombier exform(1, 0, format, map, 0, pass);
2513e12c5d1SDavid du Colombier newline();
252219b2ee8SDavid du Colombier } while (expr(0));
2533e12c5d1SDavid du Colombier dot=savdot;
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier
2563e12c5d1SDavid du Colombier /*
2573e12c5d1SDavid du Colombier * collect a register name; return register offset
2583e12c5d1SDavid du Colombier * this is not what i'd call a good division of labour
2593e12c5d1SDavid du Colombier */
2603e12c5d1SDavid du Colombier
261219b2ee8SDavid du Colombier char *
regname(int regnam)262219b2ee8SDavid du Colombier regname(int regnam)
2633e12c5d1SDavid du Colombier {
264219b2ee8SDavid du Colombier static char buf[64];
2653e12c5d1SDavid du Colombier char *p;
2663e12c5d1SDavid du Colombier int c;
2673e12c5d1SDavid du Colombier
2683e12c5d1SDavid du Colombier p = buf;
2693e12c5d1SDavid du Colombier *p++ = regnam;
270219b2ee8SDavid du Colombier while (isalnum(c = readchar())) {
271219b2ee8SDavid du Colombier if (p >= buf+sizeof(buf)-1)
272219b2ee8SDavid du Colombier error("register name too long");
2733e12c5d1SDavid du Colombier *p++ = c;
274219b2ee8SDavid du Colombier }
2753e12c5d1SDavid du Colombier *p = 0;
2763e12c5d1SDavid du Colombier reread();
277219b2ee8SDavid du Colombier return (buf);
2783e12c5d1SDavid du Colombier }
2793e12c5d1SDavid du Colombier
2803e12c5d1SDavid du Colombier /*
2813e12c5d1SDavid du Colombier * shell escape
2823e12c5d1SDavid du Colombier */
2833e12c5d1SDavid du Colombier
2843e12c5d1SDavid du Colombier void
shell(void)2853e12c5d1SDavid du Colombier shell(void)
2863e12c5d1SDavid du Colombier {
2873e12c5d1SDavid du Colombier int rc, unixpid;
288061a3f44SDavid du Colombier char *argp = (char*)lp;
2893e12c5d1SDavid du Colombier
2903e12c5d1SDavid du Colombier while (lastc!=EOR)
2913e12c5d1SDavid du Colombier rdc();
2923e12c5d1SDavid du Colombier if ((unixpid=fork())==0) {
2933e12c5d1SDavid du Colombier *lp=0;
294f19e7b74SDavid du Colombier execl("/bin/rc", "rc", "-c", argp, nil);
2953e12c5d1SDavid du Colombier exits("execl"); /* botch */
2963e12c5d1SDavid du Colombier } else if (unixpid == -1) {
2973e12c5d1SDavid du Colombier error("cannot fork");
2983e12c5d1SDavid du Colombier } else {
2993e12c5d1SDavid du Colombier mkfault = 0;
3009a747e4fSDavid du Colombier while ((rc = waitpid()) != unixpid){
3013e12c5d1SDavid du Colombier if(rc == -1 && mkfault){
3023e12c5d1SDavid du Colombier mkfault = 0;
3033e12c5d1SDavid du Colombier continue;
3043e12c5d1SDavid du Colombier }
3053e12c5d1SDavid du Colombier break;
3063e12c5d1SDavid du Colombier }
3073e12c5d1SDavid du Colombier prints("!");
3083e12c5d1SDavid du Colombier reread();
3093e12c5d1SDavid du Colombier }
3103e12c5d1SDavid du Colombier }
311