xref: /plan9/sys/src/cmd/ki/cmd.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <ctype.h>
43e12c5d1SDavid du Colombier #include <bio.h>
5bd389b36SDavid du Colombier #include <mach.h>
63e12c5d1SDavid du Colombier #define Extern extern
73e12c5d1SDavid du Colombier #include "sparc.h"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier char	buf[128], lastcmd[128];
103e12c5d1SDavid du Colombier char	fmt = 'X';
113e12c5d1SDavid du Colombier int	width = 60;
123e12c5d1SDavid du Colombier int	inc;
133e12c5d1SDavid du Colombier 
143e12c5d1SDavid du Colombier ulong	expr(char*);
153e12c5d1SDavid du Colombier ulong	expr1(char*);
163e12c5d1SDavid du Colombier char*	term(char*, ulong*);
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier char *
193e12c5d1SDavid du Colombier nextc(char *p)
203e12c5d1SDavid du Colombier {
213e12c5d1SDavid du Colombier 	while(*p && (*p == ' ' || *p == '\t') && *p != '\n')
223e12c5d1SDavid du Colombier 		p++;
233e12c5d1SDavid du Colombier 
243e12c5d1SDavid du Colombier 	if(*p == '\n')
253e12c5d1SDavid du Colombier 		*p = '\0';
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	return p;
283e12c5d1SDavid du Colombier }
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier char *
313e12c5d1SDavid du Colombier numsym(char *addr, ulong *val)
323e12c5d1SDavid du Colombier {
333e12c5d1SDavid du Colombier 	char tsym[128], *t;
343e12c5d1SDavid du Colombier 	static char *delim = "`'<>/\\@*|-~+-/=?\n";
353e12c5d1SDavid du Colombier 	Symbol s;
363e12c5d1SDavid du Colombier 	char c;
373e12c5d1SDavid du Colombier 
383e12c5d1SDavid du Colombier 	t = tsym;
393e12c5d1SDavid du Colombier 	while(c = *addr) {
403e12c5d1SDavid du Colombier 		if(strchr(delim, c))
413e12c5d1SDavid du Colombier 			break;
423e12c5d1SDavid du Colombier 		*t++ = c;
433e12c5d1SDavid du Colombier 		addr++;
443e12c5d1SDavid du Colombier 	}
453e12c5d1SDavid du Colombier 	t[0] = '\0';
463e12c5d1SDavid du Colombier 
473e12c5d1SDavid du Colombier 	if(strcmp(tsym, ".") == 0) {
483e12c5d1SDavid du Colombier 		*val = dot;
493e12c5d1SDavid du Colombier 		return addr;
503e12c5d1SDavid du Colombier 	}
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier 	if(lookup(0, tsym, &s))
533e12c5d1SDavid du Colombier 		*val = s.value;
543e12c5d1SDavid du Colombier 	else {
553e12c5d1SDavid du Colombier 		if(tsym[0] == '#')
563e12c5d1SDavid du Colombier 			*val = strtoul(tsym+1, 0, 16);
573e12c5d1SDavid du Colombier 		else
583e12c5d1SDavid du Colombier 			*val = strtoul(tsym, 0, 0);
593e12c5d1SDavid du Colombier 	}
603e12c5d1SDavid du Colombier 	return addr;
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier 
633e12c5d1SDavid du Colombier ulong
643e12c5d1SDavid du Colombier expr(char *addr)
653e12c5d1SDavid du Colombier {
663e12c5d1SDavid du Colombier 	ulong t, t2;
673e12c5d1SDavid du Colombier 	char op;
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier 	if(*addr == '\0')
703e12c5d1SDavid du Colombier 		return dot;
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier 	addr = numsym(addr, &t);
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier 	if(*addr == '\0')
753e12c5d1SDavid du Colombier 		return t;
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 	addr = nextc(addr);
783e12c5d1SDavid du Colombier 	op = *addr++;
793e12c5d1SDavid du Colombier 	numsym(addr, &t2);
803e12c5d1SDavid du Colombier 	switch(op) {
813e12c5d1SDavid du Colombier 	default:
823e12c5d1SDavid du Colombier 		Bprint(bioout, "expr syntax\n");
833e12c5d1SDavid du Colombier 		return 0;
843e12c5d1SDavid du Colombier 	case '+':
853e12c5d1SDavid du Colombier 		t += t2;
863e12c5d1SDavid du Colombier 		break;
873e12c5d1SDavid du Colombier 	case '-':
883e12c5d1SDavid du Colombier 		t -= t2;
893e12c5d1SDavid du Colombier 		break;
903e12c5d1SDavid du Colombier 	case '%':
913e12c5d1SDavid du Colombier 		t /= t2;
923e12c5d1SDavid du Colombier 		break;
933e12c5d1SDavid du Colombier 	case '&':
943e12c5d1SDavid du Colombier 		t &= t2;
953e12c5d1SDavid du Colombier 		break;
963e12c5d1SDavid du Colombier 	case '|':
973e12c5d1SDavid du Colombier 		t |= t2;
983e12c5d1SDavid du Colombier 		break;
993e12c5d1SDavid du Colombier 	}
1003e12c5d1SDavid du Colombier 
1013e12c5d1SDavid du Colombier 	return t;
1023e12c5d1SDavid du Colombier }
1033e12c5d1SDavid du Colombier 
1043e12c5d1SDavid du Colombier int
1053e12c5d1SDavid du Colombier buildargv(char *str, char **args, int max)
1063e12c5d1SDavid du Colombier {
1073e12c5d1SDavid du Colombier 	int na = 0;
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier 	while (na < max) {
1103e12c5d1SDavid du Colombier 		while((*str == ' ' || *str == '\t' || *str == '\n') && *str != '\0')
1113e12c5d1SDavid du Colombier 			str++;
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier 		if(*str == '\0')
1143e12c5d1SDavid du Colombier 			return na;
1153e12c5d1SDavid du Colombier 
1163e12c5d1SDavid du Colombier 		args[na++] = str;
1173e12c5d1SDavid du Colombier 		while(!(*str == ' ' || *str == '\t'|| *str == '\n') && *str != '\0')
1183e12c5d1SDavid du Colombier 			str++;
1193e12c5d1SDavid du Colombier 
1203e12c5d1SDavid du Colombier 		if(*str == '\n')
1213e12c5d1SDavid du Colombier 			*str = '\0';
1223e12c5d1SDavid du Colombier 
1233e12c5d1SDavid du Colombier 		if(*str == '\0')
1243e12c5d1SDavid du Colombier 			break;
1253e12c5d1SDavid du Colombier 
1263e12c5d1SDavid du Colombier 		*str++ = '\0';
1273e12c5d1SDavid du Colombier 	}
1283e12c5d1SDavid du Colombier 	return na;
1293e12c5d1SDavid du Colombier }
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier void
1323e12c5d1SDavid du Colombier colon(char *addr, char *cp)
1333e12c5d1SDavid du Colombier {
1343e12c5d1SDavid du Colombier 	int argc;
1353e12c5d1SDavid du Colombier 	char *argv[100];
136219b2ee8SDavid du Colombier 	char tbuf[512];
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier 	cp = nextc(cp);
1393e12c5d1SDavid du Colombier 	switch(*cp) {
1403e12c5d1SDavid du Colombier 	default:
1413e12c5d1SDavid du Colombier 		Bprint(bioout, "?\n");
1423e12c5d1SDavid du Colombier 		return;
1433e12c5d1SDavid du Colombier 	case 'b':
1443e12c5d1SDavid du Colombier 		breakpoint(addr, cp+1);
1453e12c5d1SDavid du Colombier 		return;
1463e12c5d1SDavid du Colombier 
1473e12c5d1SDavid du Colombier 	case 'd':
1483e12c5d1SDavid du Colombier 		delbpt(addr);
1493e12c5d1SDavid du Colombier 		return;
1503e12c5d1SDavid du Colombier 
1513e12c5d1SDavid du Colombier 	/* These fall through to print the stopped address */
1523e12c5d1SDavid du Colombier 	case 'r':
1533e12c5d1SDavid du Colombier 		reset();
1543e12c5d1SDavid du Colombier 		argc = buildargv(cp+1, argv, 100);
155219b2ee8SDavid du Colombier 		initstk(argc, argv);
1563e12c5d1SDavid du Colombier 		count = 0;
1573e12c5d1SDavid du Colombier 		atbpt = 0;
1583e12c5d1SDavid du Colombier 		run();
1593e12c5d1SDavid du Colombier 		break;
1603e12c5d1SDavid du Colombier 	case 'c':
1613e12c5d1SDavid du Colombier 		count = 0;
1623e12c5d1SDavid du Colombier 		atbpt = 0;
1633e12c5d1SDavid du Colombier 		run();
1643e12c5d1SDavid du Colombier 		break;
1653e12c5d1SDavid du Colombier 	case 's':
1663e12c5d1SDavid du Colombier 		cp = nextc(cp+1);
1673e12c5d1SDavid du Colombier 		count = 0;
1683e12c5d1SDavid du Colombier 		if(*cp)
1693e12c5d1SDavid du Colombier 			count = strtoul(cp, 0, 0);
1703e12c5d1SDavid du Colombier 		if(count == 0)
1713e12c5d1SDavid du Colombier 			count = 1;
1723e12c5d1SDavid du Colombier 		atbpt = 0;
1733e12c5d1SDavid du Colombier 		run();
1743e12c5d1SDavid du Colombier 		break;
1753e12c5d1SDavid du Colombier 	}
1763e12c5d1SDavid du Colombier 
1773e12c5d1SDavid du Colombier 	dot = reg.pc;
1783e12c5d1SDavid du Colombier 	Bprint(bioout, "%s at #%lux ", atbpt ? "breakpoint" : "stopped", dot);
179219b2ee8SDavid du Colombier 	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
180219b2ee8SDavid du Colombier 	Bprint(bioout, tbuf);
1813e12c5d1SDavid du Colombier 	if(fmt == 'z')
1823e12c5d1SDavid du Colombier 		printsource(dot);
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier 	Bprint(bioout, "\n");
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 
1883e12c5d1SDavid du Colombier void
1893e12c5d1SDavid du Colombier dollar(char *cp)
1903e12c5d1SDavid du Colombier {
1913e12c5d1SDavid du Colombier 	cp = nextc(cp);
1923e12c5d1SDavid du Colombier 	switch(*cp) {
1933e12c5d1SDavid du Colombier 	default:
1943e12c5d1SDavid du Colombier 		Bprint(bioout, "?\n");
1953e12c5d1SDavid du Colombier 		break;
1963e12c5d1SDavid du Colombier 
1973e12c5d1SDavid du Colombier 	case 'c':
1983e12c5d1SDavid du Colombier 	case 'C':
1993e12c5d1SDavid du Colombier 		stktrace(*cp);
2003e12c5d1SDavid du Colombier 		break;
2013e12c5d1SDavid du Colombier 
2023e12c5d1SDavid du Colombier 	case 'b':
2033e12c5d1SDavid du Colombier 		dobplist();
2043e12c5d1SDavid du Colombier 		break;
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier 	case 'r':
2073e12c5d1SDavid du Colombier 		dumpreg();
2083e12c5d1SDavid du Colombier 		break;
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 	case 'R':
2113e12c5d1SDavid du Colombier 		dumpreg();
212219b2ee8SDavid du Colombier 		/* fall through */
2133e12c5d1SDavid du Colombier 
2143e12c5d1SDavid du Colombier 	case 'f':
2153e12c5d1SDavid du Colombier 		dumpfreg();
2163e12c5d1SDavid du Colombier 		break;
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier 	case 'F':
2193e12c5d1SDavid du Colombier 		dumpdreg();
2203e12c5d1SDavid du Colombier 		break;
2213e12c5d1SDavid du Colombier 
2223e12c5d1SDavid du Colombier 	case 'q':
2233e12c5d1SDavid du Colombier 		exits(0);
2243e12c5d1SDavid du Colombier 		break;
2253e12c5d1SDavid du Colombier 
2263e12c5d1SDavid du Colombier 	case 'Q':
2273e12c5d1SDavid du Colombier 		isum();
2283e12c5d1SDavid du Colombier 		segsum();
2293e12c5d1SDavid du Colombier 		break;
2303e12c5d1SDavid du Colombier 
2313e12c5d1SDavid du Colombier 	case 't':
2323e12c5d1SDavid du Colombier 		cp++;
2333e12c5d1SDavid du Colombier 		switch(*cp) {
2343e12c5d1SDavid du Colombier 		default:
2353e12c5d1SDavid du Colombier 			Bprint(bioout, ":t[0sic]\n");
2363e12c5d1SDavid du Colombier 			break;
2373e12c5d1SDavid du Colombier 		case '\0':
2383e12c5d1SDavid du Colombier 			trace = 1;
2393e12c5d1SDavid du Colombier 			break;
2403e12c5d1SDavid du Colombier 		case '0':
2413e12c5d1SDavid du Colombier 			trace = 0;
2423e12c5d1SDavid du Colombier 			sysdbg = 0;
2433e12c5d1SDavid du Colombier 			calltree = 0;
2443e12c5d1SDavid du Colombier 			break;
2453e12c5d1SDavid du Colombier 		case 's':
2463e12c5d1SDavid du Colombier 			sysdbg = 1;
2473e12c5d1SDavid du Colombier 			break;
2483e12c5d1SDavid du Colombier 		case 'i':
2493e12c5d1SDavid du Colombier 			trace = 1;
2503e12c5d1SDavid du Colombier 			break;
2513e12c5d1SDavid du Colombier 		case 'c':
2523e12c5d1SDavid du Colombier 			calltree = 1;
2533e12c5d1SDavid du Colombier 			break;
2543e12c5d1SDavid du Colombier 		}
2553e12c5d1SDavid du Colombier 		break;
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier 	case 'i':
2583e12c5d1SDavid du Colombier 		cp++;
2593e12c5d1SDavid du Colombier 		switch(*cp) {
2603e12c5d1SDavid du Colombier 		default:
261219b2ee8SDavid du Colombier 			Bprint(bioout, "$i[isa]\n");
2623e12c5d1SDavid du Colombier 			break;
2633e12c5d1SDavid du Colombier 		case 'i':
2643e12c5d1SDavid du Colombier 			isum();
2653e12c5d1SDavid du Colombier 			break;
2663e12c5d1SDavid du Colombier 		case 's':
2673e12c5d1SDavid du Colombier 			segsum();
2683e12c5d1SDavid du Colombier 			break;
2693e12c5d1SDavid du Colombier 		case 'a':
2703e12c5d1SDavid du Colombier 			isum();
2713e12c5d1SDavid du Colombier 			segsum();
2723e12c5d1SDavid du Colombier 			iprofile();
2733e12c5d1SDavid du Colombier 			break;
2743e12c5d1SDavid du Colombier 		case 'p':
2753e12c5d1SDavid du Colombier 			iprofile();
2763e12c5d1SDavid du Colombier 			break;
2773e12c5d1SDavid du Colombier 		}
2783e12c5d1SDavid du Colombier 	}
2793e12c5d1SDavid du Colombier }
2803e12c5d1SDavid du Colombier 
2813e12c5d1SDavid du Colombier int
2823e12c5d1SDavid du Colombier pfmt(char fmt, int mem, ulong val)
2833e12c5d1SDavid du Colombier {
2843e12c5d1SDavid du Colombier 	int c, i;
2853e12c5d1SDavid du Colombier 	Symbol s;
2863e12c5d1SDavid du Colombier 	char *p, ch, str[1024];
2873e12c5d1SDavid du Colombier 
2883e12c5d1SDavid du Colombier 	c = 0;
2893e12c5d1SDavid du Colombier 	switch(fmt) {
2903e12c5d1SDavid du Colombier 	default:
2913e12c5d1SDavid du Colombier 		Bprint(bioout, "bad modifier\n");
2923e12c5d1SDavid du Colombier 		return 0;
2933e12c5d1SDavid du Colombier 	case 'o':
294*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%-4lo ", mem ? (ushort)getmem_2(dot) : val);
2953e12c5d1SDavid du Colombier 		inc = 2;
2963e12c5d1SDavid du Colombier 		break;
2973e12c5d1SDavid du Colombier 
2983e12c5d1SDavid du Colombier 	case 'O':
299*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%-8lo ", mem ? getmem_4(dot) : val);
3003e12c5d1SDavid du Colombier 		inc = 4;
3013e12c5d1SDavid du Colombier 		break;
3023e12c5d1SDavid du Colombier 
3033e12c5d1SDavid du Colombier 	case 'q':
304*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%-4lo ", mem ? (short)getmem_2(dot) : val);
3053e12c5d1SDavid du Colombier 		inc = 2;
3063e12c5d1SDavid du Colombier 		break;
3073e12c5d1SDavid du Colombier 
3083e12c5d1SDavid du Colombier 	case 'Q':
309*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%-8lo ", mem ? (long)getmem_4(dot) : val);
3103e12c5d1SDavid du Colombier 		inc = 4;
3113e12c5d1SDavid du Colombier 		break;
3123e12c5d1SDavid du Colombier 
3133e12c5d1SDavid du Colombier 	case 'd':
3143e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%-5ld ", mem ? (short)getmem_2(dot) : val);
3153e12c5d1SDavid du Colombier 		inc = 2;
3163e12c5d1SDavid du Colombier 		break;
3173e12c5d1SDavid du Colombier 
3183e12c5d1SDavid du Colombier 
3193e12c5d1SDavid du Colombier 	case 'D':
3203e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%-8ld ", mem ? (long)getmem_4(dot) : val);
3213e12c5d1SDavid du Colombier 		inc = 4;
3223e12c5d1SDavid du Colombier 		break;
3233e12c5d1SDavid du Colombier 
3243e12c5d1SDavid du Colombier 	case 'x':
3253e12c5d1SDavid du Colombier 		c = Bprint(bioout, "#%-4lux ", mem ? (long)getmem_2(dot) : val);
3263e12c5d1SDavid du Colombier 		inc = 2;
3273e12c5d1SDavid du Colombier 		break;
3283e12c5d1SDavid du Colombier 
3293e12c5d1SDavid du Colombier 	case 'X':
3303e12c5d1SDavid du Colombier 		c = Bprint(bioout, "#%-8lux ", mem ? (long)getmem_4(dot) : val);
3313e12c5d1SDavid du Colombier 		inc = 4;
3323e12c5d1SDavid du Colombier 		break;
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier 	case 'u':
3353e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%-5ld ", mem ? (ushort)getmem_2(dot) : val);
3363e12c5d1SDavid du Colombier 		inc = 2;
3373e12c5d1SDavid du Colombier 		break;
3383e12c5d1SDavid du Colombier 
3393e12c5d1SDavid du Colombier 	case 'U':
3403e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%-8ld ", mem ? (ulong)getmem_4(dot) : val);
3413e12c5d1SDavid du Colombier 		inc = 4;
3423e12c5d1SDavid du Colombier 		break;
3433e12c5d1SDavid du Colombier 
3443e12c5d1SDavid du Colombier 	case 'b':
345*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%-3d ", (int)(mem ? getmem_b(dot) : val));
3463e12c5d1SDavid du Colombier 		inc = 1;
3473e12c5d1SDavid du Colombier 		break;
3483e12c5d1SDavid du Colombier 
3493e12c5d1SDavid du Colombier 	case 'c':
350*7dd7cddfSDavid du Colombier 		c = Bprint(bioout, "%c ", (int)(mem ? getmem_b(dot) : val));
3513e12c5d1SDavid du Colombier 		inc = 1;
3523e12c5d1SDavid du Colombier 		break;
3533e12c5d1SDavid du Colombier 
3543e12c5d1SDavid du Colombier 	case 'C':
3553e12c5d1SDavid du Colombier 		ch = mem ? getmem_b(dot) : val;
3563e12c5d1SDavid du Colombier 		if(isprint(ch))
3573e12c5d1SDavid du Colombier 			c = Bprint(bioout, "%c ", ch);
3583e12c5d1SDavid du Colombier 		else
3593e12c5d1SDavid du Colombier 			c = Bprint(bioout, "\\x%.2x ", ch);
3603e12c5d1SDavid du Colombier 		inc = 1;
3613e12c5d1SDavid du Colombier 		break;
3623e12c5d1SDavid du Colombier 
3633e12c5d1SDavid du Colombier 	case 's':
3643e12c5d1SDavid du Colombier 		i = 0;
3653e12c5d1SDavid du Colombier 		while(ch = getmem_b(dot+i))
3663e12c5d1SDavid du Colombier 			str[i++] = ch;
3673e12c5d1SDavid du Colombier 		str[i] = '\0';
3683e12c5d1SDavid du Colombier 		dot += i;
3693e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%s", str);
3703e12c5d1SDavid du Colombier 		inc = 0;
3713e12c5d1SDavid du Colombier 		break;
3723e12c5d1SDavid du Colombier 
3733e12c5d1SDavid du Colombier 	case 'S':
3743e12c5d1SDavid du Colombier 		i = 0;
3753e12c5d1SDavid du Colombier 		while(ch = getmem_b(dot+i))
3763e12c5d1SDavid du Colombier 			str[i++] = ch;
3773e12c5d1SDavid du Colombier 		str[i] = '\0';
3783e12c5d1SDavid du Colombier 		dot += i;
3793e12c5d1SDavid du Colombier 		for(p = str; *p; p++)
3803e12c5d1SDavid du Colombier 			if(isprint(*p))
3813e12c5d1SDavid du Colombier 				c += Bprint(bioout, "%c", *p);
3823e12c5d1SDavid du Colombier 			else
383*7dd7cddfSDavid du Colombier 				c += Bprint(bioout, "\\x%.2ux", *p);
3843e12c5d1SDavid du Colombier 		inc = 0;
3853e12c5d1SDavid du Colombier 		break;
3863e12c5d1SDavid du Colombier 
3873e12c5d1SDavid du Colombier 	case 'Y':
3883e12c5d1SDavid du Colombier 		p = ctime(mem ? getmem_b(dot) : val);
3893e12c5d1SDavid du Colombier 		p[30] = '\0';
3903e12c5d1SDavid du Colombier 		c = Bprint(bioout, "%s", p);
3913e12c5d1SDavid du Colombier 		inc = 4;
3923e12c5d1SDavid du Colombier 		break;
3933e12c5d1SDavid du Colombier 
3943e12c5d1SDavid du Colombier 	case 'a':
395219b2ee8SDavid du Colombier 		symoff(str, sizeof(str), dot, CTEXT);
396219b2ee8SDavid du Colombier 		Bprint(bioout, "%s", str);
3973e12c5d1SDavid du Colombier 		inc = 0;
3983e12c5d1SDavid du Colombier 		break;
3993e12c5d1SDavid du Colombier 
4003e12c5d1SDavid du Colombier 	case 'e':
4013e12c5d1SDavid du Colombier 		for (i = 0; globalsym(&s, i); i++)
4023e12c5d1SDavid du Colombier 			Bprint(bioout, "%-15s #%lux\n", s.name,	getmem_4(s.value));
4033e12c5d1SDavid du Colombier 		inc = 0;
4043e12c5d1SDavid du Colombier 		break;
4053e12c5d1SDavid du Colombier 
4063e12c5d1SDavid du Colombier 	case 'I':
407219b2ee8SDavid du Colombier 	case 'i':
408219b2ee8SDavid du Colombier 		inc = machdata->das(symmap, dot, fmt, str, sizeof(str));
409219b2ee8SDavid du Colombier 		if (inc < 0) {
410219b2ee8SDavid du Colombier 			Bprint(bioout, "ki: %r\n");
411219b2ee8SDavid du Colombier 			return 0;
412219b2ee8SDavid du Colombier 		}
413219b2ee8SDavid du Colombier 		c = Bprint(bioout, "\t%s", str);
4143e12c5d1SDavid du Colombier 		break;
4153e12c5d1SDavid du Colombier 
4163e12c5d1SDavid du Colombier 	case 'n':
4173e12c5d1SDavid du Colombier 		c = width+1;
4183e12c5d1SDavid du Colombier 		inc = 0;
4193e12c5d1SDavid du Colombier 		break;
4203e12c5d1SDavid du Colombier 
4213e12c5d1SDavid du Colombier 	case '-':
4223e12c5d1SDavid du Colombier 		c = 0;
4233e12c5d1SDavid du Colombier 		inc = -1;
4243e12c5d1SDavid du Colombier 		break;
4253e12c5d1SDavid du Colombier 
4263e12c5d1SDavid du Colombier 	case '+':
4273e12c5d1SDavid du Colombier 		c = 0;
4283e12c5d1SDavid du Colombier 		inc = 1;
4293e12c5d1SDavid du Colombier 		break;
4303e12c5d1SDavid du Colombier 
4313e12c5d1SDavid du Colombier 	case '^':
4323e12c5d1SDavid du Colombier 		c = 0;
4333e12c5d1SDavid du Colombier 		if(inc > 0)
4343e12c5d1SDavid du Colombier 			inc = -inc;
4353e12c5d1SDavid du Colombier 		break;
4363e12c5d1SDavid du Colombier 
4373e12c5d1SDavid du Colombier 	case 'z':
4383e12c5d1SDavid du Colombier 		if (findsym(dot, CTEXT, &s))
4393e12c5d1SDavid du Colombier 			Bprint(bioout, "  %s() ", s.name);
4403e12c5d1SDavid du Colombier 		printsource(dot);
4413e12c5d1SDavid du Colombier 		inc = 0;
4423e12c5d1SDavid du Colombier 		break;
4433e12c5d1SDavid du Colombier 	}
4443e12c5d1SDavid du Colombier 	return c;
4453e12c5d1SDavid du Colombier }
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier void
4483e12c5d1SDavid du Colombier eval(char *addr, char *p)
4493e12c5d1SDavid du Colombier {
4503e12c5d1SDavid du Colombier 	ulong val;
4513e12c5d1SDavid du Colombier 
4523e12c5d1SDavid du Colombier 	val = expr(addr);
4533e12c5d1SDavid du Colombier 	p = nextc(p);
4543e12c5d1SDavid du Colombier 	if(*p == '\0') {
4553e12c5d1SDavid du Colombier 		p[0] = fmt;
4563e12c5d1SDavid du Colombier 		p[1] = '\0';
4573e12c5d1SDavid du Colombier 	}
4583e12c5d1SDavid du Colombier 	pfmt(*p, 0, val);
4593e12c5d1SDavid du Colombier 	Bprint(bioout, "\n");
4603e12c5d1SDavid du Colombier }
4613e12c5d1SDavid du Colombier 
4623e12c5d1SDavid du Colombier void
4633e12c5d1SDavid du Colombier quesie(char *p)
4643e12c5d1SDavid du Colombier {
4653e12c5d1SDavid du Colombier 	int c, count, i;
466219b2ee8SDavid du Colombier 	char tbuf[512];
4673e12c5d1SDavid du Colombier 
4683e12c5d1SDavid du Colombier 	c = 0;
469219b2ee8SDavid du Colombier 	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
470219b2ee8SDavid du Colombier 	Bprint(bioout, "%s?\t", tbuf);
4713e12c5d1SDavid du Colombier 
4723e12c5d1SDavid du Colombier 	while(*p) {
4733e12c5d1SDavid du Colombier 		p = nextc(p);
4743e12c5d1SDavid du Colombier 		if(*p == '"') {
4753e12c5d1SDavid du Colombier 			for(p++; *p && *p != '"'; p++) {
4763e12c5d1SDavid du Colombier 				Bputc(bioout, *p);
4773e12c5d1SDavid du Colombier 				c++;
4783e12c5d1SDavid du Colombier 			}
4793e12c5d1SDavid du Colombier 			if(*p)
4803e12c5d1SDavid du Colombier 				p++;
4813e12c5d1SDavid du Colombier 			continue;
4823e12c5d1SDavid du Colombier 		}
4833e12c5d1SDavid du Colombier 		count = 0;
4843e12c5d1SDavid du Colombier 		while(*p >= '0' && *p <= '9')
4853e12c5d1SDavid du Colombier 			count = count*10 + (*p++ - '0');
4863e12c5d1SDavid du Colombier 		if(count == 0)
4873e12c5d1SDavid du Colombier 			count = 1;
4883e12c5d1SDavid du Colombier 		p = nextc(p);
4893e12c5d1SDavid du Colombier 		if(*p == '\0') {
4903e12c5d1SDavid du Colombier 			p[0] = fmt;
4913e12c5d1SDavid du Colombier 			p[1] = '\0';
4923e12c5d1SDavid du Colombier 		}
4933e12c5d1SDavid du Colombier 		for(i = 0; i < count; i++) {
4943e12c5d1SDavid du Colombier 			c += pfmt(*p, 1, 0);
4953e12c5d1SDavid du Colombier 			dot += inc;
4963e12c5d1SDavid du Colombier 			if(c > width) {
4973e12c5d1SDavid du Colombier 				Bprint(bioout, "\n");
498219b2ee8SDavid du Colombier 				symoff(tbuf, sizeof(tbuf), dot, CTEXT);
499219b2ee8SDavid du Colombier 				Bprint(bioout, "%s?\t", tbuf);
5003e12c5d1SDavid du Colombier 				c = 0;
5013e12c5d1SDavid du Colombier 			}
5023e12c5d1SDavid du Colombier 		}
5033e12c5d1SDavid du Colombier 		fmt = *p++;
5043e12c5d1SDavid du Colombier 		p = nextc(p);
5053e12c5d1SDavid du Colombier 	}
5063e12c5d1SDavid du Colombier 	Bprint(bioout, "\n");
5073e12c5d1SDavid du Colombier }
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier void
5103e12c5d1SDavid du Colombier catcher(void *a, char *msg)
5113e12c5d1SDavid du Colombier {
5123e12c5d1SDavid du Colombier 	USED(a);
5133e12c5d1SDavid du Colombier 	if(strcmp(msg, "interrupt") != 0)
5143e12c5d1SDavid du Colombier 		noted(NDFLT);
5153e12c5d1SDavid du Colombier 
5163e12c5d1SDavid du Colombier 	count = 1;
5173e12c5d1SDavid du Colombier 	print("ki\n");
5183e12c5d1SDavid du Colombier 	noted(NCONT);
5193e12c5d1SDavid du Colombier }
5203e12c5d1SDavid du Colombier 
5213e12c5d1SDavid du Colombier void
5223e12c5d1SDavid du Colombier setreg(char *addr, char *cp)
5233e12c5d1SDavid du Colombier {
5243e12c5d1SDavid du Colombier 	int rn;
5253e12c5d1SDavid du Colombier 
5263e12c5d1SDavid du Colombier 	dot = expr(addr);
5273e12c5d1SDavid du Colombier 	cp = nextc(cp);
5283e12c5d1SDavid du Colombier 	if(strcmp(cp, "pc") == 0) {
5293e12c5d1SDavid du Colombier 		reg.pc = dot;
5303e12c5d1SDavid du Colombier 		return;
5313e12c5d1SDavid du Colombier 	}
5323e12c5d1SDavid du Colombier 	if(strcmp(cp, "sp") == 0) {
5333e12c5d1SDavid du Colombier 		reg.r[1] = dot;
5343e12c5d1SDavid du Colombier 		return;
5353e12c5d1SDavid du Colombier 	}
5363e12c5d1SDavid du Colombier 	if(strcmp(cp, "y") == 0) {
5373e12c5d1SDavid du Colombier 		reg.Y = dot;
5383e12c5d1SDavid du Colombier 		return;
5393e12c5d1SDavid du Colombier 	}
5403e12c5d1SDavid du Colombier 	if(strcmp(cp, "psr") == 0) {
5413e12c5d1SDavid du Colombier 		reg.psr = dot;
5423e12c5d1SDavid du Colombier 		return;
5433e12c5d1SDavid du Colombier 	}
5443e12c5d1SDavid du Colombier 	if(*cp++ == 'r') {
5453e12c5d1SDavid du Colombier 		rn = strtoul(cp, 0, 10);
5463e12c5d1SDavid du Colombier 		if(rn > 0 && rn < 32) {
5473e12c5d1SDavid du Colombier 			reg.r[rn] = dot;
5483e12c5d1SDavid du Colombier 			return;
5493e12c5d1SDavid du Colombier 		}
5503e12c5d1SDavid du Colombier 	}
5513e12c5d1SDavid du Colombier 	Bprint(bioout, "bad register\n");
5523e12c5d1SDavid du Colombier }
5533e12c5d1SDavid du Colombier 
5543e12c5d1SDavid du Colombier void
5553e12c5d1SDavid du Colombier cmd(void)
5563e12c5d1SDavid du Colombier {
5573e12c5d1SDavid du Colombier 	char *p, *a, *cp, *gotint;
5583e12c5d1SDavid du Colombier 	char addr[128];
5593e12c5d1SDavid du Colombier 	static char *cmdlet = ":$?/=>";
5603e12c5d1SDavid du Colombier 	int n, i;
5613e12c5d1SDavid du Colombier 
5623e12c5d1SDavid du Colombier 	notify(catcher);
5633e12c5d1SDavid du Colombier 
5643e12c5d1SDavid du Colombier 	dot = reg.pc;
5653e12c5d1SDavid du Colombier 	setjmp(errjmp);
5663e12c5d1SDavid du Colombier 
5673e12c5d1SDavid du Colombier 	for(;;) {
5683e12c5d1SDavid du Colombier 		Bflush(bioout);
5693e12c5d1SDavid du Colombier 		p = buf;
5703e12c5d1SDavid du Colombier 		n = 0;
5713e12c5d1SDavid du Colombier 		for(;;) {
5723e12c5d1SDavid du Colombier 			i = Bgetc(bin);
5733e12c5d1SDavid du Colombier 			if(i < 0)
5743e12c5d1SDavid du Colombier 				exits(0);
5753e12c5d1SDavid du Colombier 			*p++ = i;
5763e12c5d1SDavid du Colombier 			n++;
5773e12c5d1SDavid du Colombier 			if(i == '\n')
5783e12c5d1SDavid du Colombier 				break;
5793e12c5d1SDavid du Colombier 		}
5803e12c5d1SDavid du Colombier 
5813e12c5d1SDavid du Colombier 		if(buf[0] == '\n')
5823e12c5d1SDavid du Colombier 			strcpy(buf, lastcmd);
5833e12c5d1SDavid du Colombier 		else {
5843e12c5d1SDavid du Colombier 			buf[n-1] = '\0';
5853e12c5d1SDavid du Colombier 			strcpy(lastcmd, buf);
5863e12c5d1SDavid du Colombier 		}
5873e12c5d1SDavid du Colombier 		p = buf;
5883e12c5d1SDavid du Colombier 		a = addr;
5893e12c5d1SDavid du Colombier 
5903e12c5d1SDavid du Colombier 		for(;;) {
5913e12c5d1SDavid du Colombier 			p = nextc(p);
5923e12c5d1SDavid du Colombier 			if(*p == 0 || strchr(cmdlet, *p))
5933e12c5d1SDavid du Colombier 				break;
5943e12c5d1SDavid du Colombier 			*a++ = *p++;
5953e12c5d1SDavid du Colombier 		}
5963e12c5d1SDavid du Colombier 
5973e12c5d1SDavid du Colombier 		*a = '\0';
5983e12c5d1SDavid du Colombier 		cmdcount = 1;
5993e12c5d1SDavid du Colombier 		cp = strchr(addr, ',');
6003e12c5d1SDavid du Colombier 		if(cp != 0) {
6013e12c5d1SDavid du Colombier 			if(cp[1] == '#')
6023e12c5d1SDavid du Colombier 				cmdcount = strtoul(cp+2, &gotint, 16);
6033e12c5d1SDavid du Colombier 			else
6043e12c5d1SDavid du Colombier 				cmdcount = strtoul(cp+1, &gotint, 0);
6053e12c5d1SDavid du Colombier 			*cp = '\0';
6063e12c5d1SDavid du Colombier 		}
6073e12c5d1SDavid du Colombier 
6083e12c5d1SDavid du Colombier 		switch(*p) {
6093e12c5d1SDavid du Colombier 		case '$':
6103e12c5d1SDavid du Colombier 			dollar(p+1);
6113e12c5d1SDavid du Colombier 			break;
6123e12c5d1SDavid du Colombier 		case ':':
6133e12c5d1SDavid du Colombier 			colon(addr, p+1);
6143e12c5d1SDavid du Colombier 			break;
6153e12c5d1SDavid du Colombier 		case '/':
6163e12c5d1SDavid du Colombier 		case '?':
6173e12c5d1SDavid du Colombier 			dot = expr(addr);
6183e12c5d1SDavid du Colombier 			for(i = 0; i < cmdcount; i++)
6193e12c5d1SDavid du Colombier 				quesie(p+1);
6203e12c5d1SDavid du Colombier 			break;
6213e12c5d1SDavid du Colombier 		case '=':
6223e12c5d1SDavid du Colombier 			eval(addr, p+1);
6233e12c5d1SDavid du Colombier 			break;
6243e12c5d1SDavid du Colombier 		case '>':
6253e12c5d1SDavid du Colombier 			setreg(addr, p+1);
6263e12c5d1SDavid du Colombier 			break;
6273e12c5d1SDavid du Colombier 		default:
6283e12c5d1SDavid du Colombier 			Bprint(bioout, "?\n");
6293e12c5d1SDavid du Colombier 			break;
6303e12c5d1SDavid du Colombier 		}
6313e12c5d1SDavid du Colombier 	}
6323e12c5d1SDavid du Colombier }
633