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; 13*061a3f44SDavid 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; 213e12c5d1SDavid du Colombier WORD 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 273e12c5d1SDavid du Colombier command(char *buf, int defcom) 283e12c5d1SDavid du Colombier { 29219b2ee8SDavid du Colombier char *reg; 303e12c5d1SDavid du Colombier char savc; 31*061a3f44SDavid 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(); 42*061a3f44SDavid 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 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) { 153219b2ee8SDavid du Colombier sprint(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 187219b2ee8SDavid du Colombier cmdsrc(int c, Map *map) 1883e12c5d1SDavid du Colombier { 189219b2ee8SDavid du Colombier long 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 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 * 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 2853e12c5d1SDavid du Colombier shell(void) 2863e12c5d1SDavid du Colombier { 2873e12c5d1SDavid du Colombier int rc, unixpid; 288*061a3f44SDavid 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; 2943e12c5d1SDavid du Colombier execl("/bin/rc", "rc", "-c", argp, 0); 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