xref: /plan9/sys/src/cmd/qi/cmd.c (revision 7d9195a7bc3493d7fc3e1166ef25bf446be66b1a)
1*7d9195a7SDavid du Colombier #include <u.h>
2*7d9195a7SDavid du Colombier #include <libc.h>
3*7d9195a7SDavid du Colombier #include <ctype.h>
4*7d9195a7SDavid du Colombier #include <bio.h>
5*7d9195a7SDavid du Colombier #include <mach.h>
6*7d9195a7SDavid du Colombier #define Extern extern
7*7d9195a7SDavid du Colombier #include "power.h"
8*7d9195a7SDavid du Colombier 
9*7d9195a7SDavid du Colombier char	buf[128], lastcmd[128];
10*7d9195a7SDavid du Colombier char	fmt = 'X';
11*7d9195a7SDavid du Colombier int	width = 60;
12*7d9195a7SDavid du Colombier int	inc;
13*7d9195a7SDavid du Colombier 
14*7d9195a7SDavid du Colombier ulong	expr(char*);
15*7d9195a7SDavid du Colombier ulong	expr1(char*);
16*7d9195a7SDavid du Colombier char*	term(char*, ulong*);
17*7d9195a7SDavid du Colombier 
18*7d9195a7SDavid du Colombier char *
19*7d9195a7SDavid du Colombier nextc(char *p)
20*7d9195a7SDavid du Colombier {
21*7d9195a7SDavid du Colombier 	while(*p && (*p == ' ' || *p == '\t') && *p != '\n')
22*7d9195a7SDavid du Colombier 		p++;
23*7d9195a7SDavid du Colombier 
24*7d9195a7SDavid du Colombier 	if(*p == '\n')
25*7d9195a7SDavid du Colombier 		*p = '\0';
26*7d9195a7SDavid du Colombier 
27*7d9195a7SDavid du Colombier 	return p;
28*7d9195a7SDavid du Colombier }
29*7d9195a7SDavid du Colombier 
30*7d9195a7SDavid du Colombier char *
31*7d9195a7SDavid du Colombier numsym(char *addr, ulong *val)
32*7d9195a7SDavid du Colombier {
33*7d9195a7SDavid du Colombier 	char tsym[128], *t;
34*7d9195a7SDavid du Colombier 	static char *delim = "`'<>/\\@*|-~+-/=?\n";
35*7d9195a7SDavid du Colombier 	Symbol s;
36*7d9195a7SDavid du Colombier 	char c;
37*7d9195a7SDavid du Colombier 
38*7d9195a7SDavid du Colombier 	t = tsym;
39*7d9195a7SDavid du Colombier 	while(c = *addr) {
40*7d9195a7SDavid du Colombier 		if(strchr(delim, c))
41*7d9195a7SDavid du Colombier 			break;
42*7d9195a7SDavid du Colombier 		*t++ = c;
43*7d9195a7SDavid du Colombier 		addr++;
44*7d9195a7SDavid du Colombier 	}
45*7d9195a7SDavid du Colombier 	t[0] = '\0';
46*7d9195a7SDavid du Colombier 
47*7d9195a7SDavid du Colombier 	if(strcmp(tsym, ".") == 0) {
48*7d9195a7SDavid du Colombier 		*val = dot;
49*7d9195a7SDavid du Colombier 		return addr;
50*7d9195a7SDavid du Colombier 	}
51*7d9195a7SDavid du Colombier 
52*7d9195a7SDavid du Colombier 	if(lookup(0, tsym, &s))
53*7d9195a7SDavid du Colombier 		*val = s.value;
54*7d9195a7SDavid du Colombier 	else {
55*7d9195a7SDavid du Colombier 		if(tsym[0] == '#')
56*7d9195a7SDavid du Colombier 			*val = strtoul(tsym+1, 0, 16);
57*7d9195a7SDavid du Colombier 		else
58*7d9195a7SDavid du Colombier 			*val = strtoul(tsym, 0, 0);
59*7d9195a7SDavid du Colombier 	}
60*7d9195a7SDavid du Colombier 	return addr;
61*7d9195a7SDavid du Colombier }
62*7d9195a7SDavid du Colombier 
63*7d9195a7SDavid du Colombier ulong
64*7d9195a7SDavid du Colombier expr(char *addr)
65*7d9195a7SDavid du Colombier {
66*7d9195a7SDavid du Colombier 	ulong t, t2;
67*7d9195a7SDavid du Colombier 	char op;
68*7d9195a7SDavid du Colombier 
69*7d9195a7SDavid du Colombier 	if(*addr == '\0')
70*7d9195a7SDavid du Colombier 		return dot;
71*7d9195a7SDavid du Colombier 
72*7d9195a7SDavid du Colombier 	addr = numsym(addr, &t);
73*7d9195a7SDavid du Colombier 
74*7d9195a7SDavid du Colombier 	if(*addr == '\0')
75*7d9195a7SDavid du Colombier 		return t;
76*7d9195a7SDavid du Colombier 
77*7d9195a7SDavid du Colombier 	addr = nextc(addr);
78*7d9195a7SDavid du Colombier 	op = *addr++;
79*7d9195a7SDavid du Colombier 	numsym(addr, &t2);
80*7d9195a7SDavid du Colombier 	switch(op) {
81*7d9195a7SDavid du Colombier 	default:
82*7d9195a7SDavid du Colombier 		Bprint(bioout, "expr syntax\n");
83*7d9195a7SDavid du Colombier 		return 0;
84*7d9195a7SDavid du Colombier 	case '+':
85*7d9195a7SDavid du Colombier 		t += t2;
86*7d9195a7SDavid du Colombier 		break;
87*7d9195a7SDavid du Colombier 	case '-':
88*7d9195a7SDavid du Colombier 		t -= t2;
89*7d9195a7SDavid du Colombier 		break;
90*7d9195a7SDavid du Colombier 	case '%':
91*7d9195a7SDavid du Colombier 		t /= t2;
92*7d9195a7SDavid du Colombier 		break;
93*7d9195a7SDavid du Colombier 	case '&':
94*7d9195a7SDavid du Colombier 		t &= t2;
95*7d9195a7SDavid du Colombier 		break;
96*7d9195a7SDavid du Colombier 	case '|':
97*7d9195a7SDavid du Colombier 		t |= t2;
98*7d9195a7SDavid du Colombier 		break;
99*7d9195a7SDavid du Colombier 	}
100*7d9195a7SDavid du Colombier 
101*7d9195a7SDavid du Colombier 	return t;
102*7d9195a7SDavid du Colombier }
103*7d9195a7SDavid du Colombier 
104*7d9195a7SDavid du Colombier int
105*7d9195a7SDavid du Colombier buildargv(char *str, char **args, int max)
106*7d9195a7SDavid du Colombier {
107*7d9195a7SDavid du Colombier 	int na = 0;
108*7d9195a7SDavid du Colombier 
109*7d9195a7SDavid du Colombier 	while (na < max) {
110*7d9195a7SDavid du Colombier 		while((*str == ' ' || *str == '\t' || *str == '\n') && *str != '\0')
111*7d9195a7SDavid du Colombier 			str++;
112*7d9195a7SDavid du Colombier 
113*7d9195a7SDavid du Colombier 		if(*str == '\0')
114*7d9195a7SDavid du Colombier 			return na;
115*7d9195a7SDavid du Colombier 
116*7d9195a7SDavid du Colombier 		args[na++] = str;
117*7d9195a7SDavid du Colombier 		while(!(*str == ' ' || *str == '\t'|| *str == '\n') && *str != '\0')
118*7d9195a7SDavid du Colombier 			str++;
119*7d9195a7SDavid du Colombier 
120*7d9195a7SDavid du Colombier 		if(*str == '\n')
121*7d9195a7SDavid du Colombier 			*str = '\0';
122*7d9195a7SDavid du Colombier 
123*7d9195a7SDavid du Colombier 		if(*str == '\0')
124*7d9195a7SDavid du Colombier 			break;
125*7d9195a7SDavid du Colombier 
126*7d9195a7SDavid du Colombier 		*str++ = '\0';
127*7d9195a7SDavid du Colombier 	}
128*7d9195a7SDavid du Colombier 	return na;
129*7d9195a7SDavid du Colombier }
130*7d9195a7SDavid du Colombier 
131*7d9195a7SDavid du Colombier void
132*7d9195a7SDavid du Colombier colon(char *addr, char *cp)
133*7d9195a7SDavid du Colombier {
134*7d9195a7SDavid du Colombier 	int argc;
135*7d9195a7SDavid du Colombier 	char *argv[100];
136*7d9195a7SDavid du Colombier 	char tbuf[512];
137*7d9195a7SDavid du Colombier 
138*7d9195a7SDavid du Colombier 	cp = nextc(cp);
139*7d9195a7SDavid du Colombier 	switch(*cp) {
140*7d9195a7SDavid du Colombier 	default:
141*7d9195a7SDavid du Colombier 		Bprint(bioout, "?\n");
142*7d9195a7SDavid du Colombier 		return;
143*7d9195a7SDavid du Colombier 	case 'b':
144*7d9195a7SDavid du Colombier 		breakpoint(addr, cp+1);
145*7d9195a7SDavid du Colombier 		return;
146*7d9195a7SDavid du Colombier 
147*7d9195a7SDavid du Colombier 	case 'd':
148*7d9195a7SDavid du Colombier 		delbpt(addr);
149*7d9195a7SDavid du Colombier 		return;
150*7d9195a7SDavid du Colombier 
151*7d9195a7SDavid du Colombier 	/* These fall through to print the stopped address */
152*7d9195a7SDavid du Colombier 	case 'r':
153*7d9195a7SDavid du Colombier 		reset();
154*7d9195a7SDavid du Colombier 		argc = buildargv(cp+1, argv, 100);
155*7d9195a7SDavid du Colombier 		initstk(argc, argv);
156*7d9195a7SDavid du Colombier 		count = 0;
157*7d9195a7SDavid du Colombier 		atbpt = 0;
158*7d9195a7SDavid du Colombier 		run();
159*7d9195a7SDavid du Colombier 		break;
160*7d9195a7SDavid du Colombier 	case 'c':
161*7d9195a7SDavid du Colombier 		count = 0;
162*7d9195a7SDavid du Colombier 		atbpt = 0;
163*7d9195a7SDavid du Colombier 		run();
164*7d9195a7SDavid du Colombier 		break;
165*7d9195a7SDavid du Colombier 	case 's':
166*7d9195a7SDavid du Colombier 		cp = nextc(cp+1);
167*7d9195a7SDavid du Colombier 		count = 0;
168*7d9195a7SDavid du Colombier 		if(*cp)
169*7d9195a7SDavid du Colombier 			count = strtoul(cp, 0, 0);
170*7d9195a7SDavid du Colombier 		if(count == 0)
171*7d9195a7SDavid du Colombier 			count = 1;
172*7d9195a7SDavid du Colombier 		atbpt = 0;
173*7d9195a7SDavid du Colombier 		run();
174*7d9195a7SDavid du Colombier 		break;
175*7d9195a7SDavid du Colombier 	}
176*7d9195a7SDavid du Colombier 
177*7d9195a7SDavid du Colombier 	dot = reg.pc;
178*7d9195a7SDavid du Colombier 	Bprint(bioout, "%s at #%lux ", atbpt ? "breakpoint" : "stopped", dot);
179*7d9195a7SDavid du Colombier 	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
180*7d9195a7SDavid du Colombier 	Bprint(bioout, tbuf);
181*7d9195a7SDavid du Colombier 	if(fmt == 'z')
182*7d9195a7SDavid du Colombier 		printsource(dot);
183*7d9195a7SDavid du Colombier 
184*7d9195a7SDavid du Colombier 	Bprint(bioout, "\n");
185*7d9195a7SDavid du Colombier }
186*7d9195a7SDavid du Colombier 
187*7d9195a7SDavid du Colombier 
188*7d9195a7SDavid du Colombier void
189*7d9195a7SDavid du Colombier dollar(char *cp)
190*7d9195a7SDavid du Colombier {
191*7d9195a7SDavid du Colombier 	cp = nextc(cp);
192*7d9195a7SDavid du Colombier 	switch(*cp) {
193*7d9195a7SDavid du Colombier 	default:
194*7d9195a7SDavid du Colombier 		Bprint(bioout, "?\n");
195*7d9195a7SDavid du Colombier 		break;
196*7d9195a7SDavid du Colombier 
197*7d9195a7SDavid du Colombier 	case 'c':
198*7d9195a7SDavid du Colombier 	case 'C':
199*7d9195a7SDavid du Colombier 		stktrace(*cp);
200*7d9195a7SDavid du Colombier 		break;
201*7d9195a7SDavid du Colombier 
202*7d9195a7SDavid du Colombier 	case 'b':
203*7d9195a7SDavid du Colombier 		dobplist();
204*7d9195a7SDavid du Colombier 		break;
205*7d9195a7SDavid du Colombier 
206*7d9195a7SDavid du Colombier 	case 'r':
207*7d9195a7SDavid du Colombier 		dumpreg();
208*7d9195a7SDavid du Colombier 		break;
209*7d9195a7SDavid du Colombier 
210*7d9195a7SDavid du Colombier 	case 'R':
211*7d9195a7SDavid du Colombier 		dumpreg();
212*7d9195a7SDavid du Colombier 		/* fall through */
213*7d9195a7SDavid du Colombier 
214*7d9195a7SDavid du Colombier 	case 'f':
215*7d9195a7SDavid du Colombier 		dumpfreg();
216*7d9195a7SDavid du Colombier 		break;
217*7d9195a7SDavid du Colombier 
218*7d9195a7SDavid du Colombier 	case 'F':
219*7d9195a7SDavid du Colombier 		dumpdreg();
220*7d9195a7SDavid du Colombier 		break;
221*7d9195a7SDavid du Colombier 
222*7d9195a7SDavid du Colombier 	case 'q':
223*7d9195a7SDavid du Colombier 		exits(0);
224*7d9195a7SDavid du Colombier 		break;
225*7d9195a7SDavid du Colombier 
226*7d9195a7SDavid du Colombier 	case 'Q':
227*7d9195a7SDavid du Colombier 		isum();
228*7d9195a7SDavid du Colombier 		segsum();
229*7d9195a7SDavid du Colombier 		break;
230*7d9195a7SDavid du Colombier 
231*7d9195a7SDavid du Colombier 	case 't':
232*7d9195a7SDavid du Colombier 		cp++;
233*7d9195a7SDavid du Colombier 		switch(*cp) {
234*7d9195a7SDavid du Colombier 		default:
235*7d9195a7SDavid du Colombier 			Bprint(bioout, ":t[0sic]\n");
236*7d9195a7SDavid du Colombier 			break;
237*7d9195a7SDavid du Colombier 		case '\0':
238*7d9195a7SDavid du Colombier 			trace = 1;
239*7d9195a7SDavid du Colombier 			break;
240*7d9195a7SDavid du Colombier 		case '0':
241*7d9195a7SDavid du Colombier 			trace = 0;
242*7d9195a7SDavid du Colombier 			sysdbg = 0;
243*7d9195a7SDavid du Colombier 			calltree = 0;
244*7d9195a7SDavid du Colombier 			break;
245*7d9195a7SDavid du Colombier 		case 's':
246*7d9195a7SDavid du Colombier 			sysdbg = 1;
247*7d9195a7SDavid du Colombier 			break;
248*7d9195a7SDavid du Colombier 		case 'i':
249*7d9195a7SDavid du Colombier 			trace = 1;
250*7d9195a7SDavid du Colombier 			break;
251*7d9195a7SDavid du Colombier 		case 'c':
252*7d9195a7SDavid du Colombier 			calltree = 1;
253*7d9195a7SDavid du Colombier 			break;
254*7d9195a7SDavid du Colombier 		}
255*7d9195a7SDavid du Colombier 		break;
256*7d9195a7SDavid du Colombier 
257*7d9195a7SDavid du Colombier 	case 'i':
258*7d9195a7SDavid du Colombier 		cp++;
259*7d9195a7SDavid du Colombier 		switch(*cp) {
260*7d9195a7SDavid du Colombier 		default:
261*7d9195a7SDavid du Colombier 			Bprint(bioout, "$i[isa]\n");
262*7d9195a7SDavid du Colombier 			break;
263*7d9195a7SDavid du Colombier 		case 'i':
264*7d9195a7SDavid du Colombier 			isum();
265*7d9195a7SDavid du Colombier 			break;
266*7d9195a7SDavid du Colombier 		case 's':
267*7d9195a7SDavid du Colombier 			segsum();
268*7d9195a7SDavid du Colombier 			break;
269*7d9195a7SDavid du Colombier 		case 'a':
270*7d9195a7SDavid du Colombier 			isum();
271*7d9195a7SDavid du Colombier 			segsum();
272*7d9195a7SDavid du Colombier 			iprofile();
273*7d9195a7SDavid du Colombier 			break;
274*7d9195a7SDavid du Colombier 		case 'p':
275*7d9195a7SDavid du Colombier 			iprofile();
276*7d9195a7SDavid du Colombier 			break;
277*7d9195a7SDavid du Colombier 		}
278*7d9195a7SDavid du Colombier 	}
279*7d9195a7SDavid du Colombier }
280*7d9195a7SDavid du Colombier 
281*7d9195a7SDavid du Colombier int
282*7d9195a7SDavid du Colombier pfmt(char fmt, int mem, ulong val)
283*7d9195a7SDavid du Colombier {
284*7d9195a7SDavid du Colombier 	int c, i;
285*7d9195a7SDavid du Colombier 	Symbol s;
286*7d9195a7SDavid du Colombier 	char *p, ch, str[1024];
287*7d9195a7SDavid du Colombier 
288*7d9195a7SDavid du Colombier 	c = 0;
289*7d9195a7SDavid du Colombier 	switch(fmt) {
290*7d9195a7SDavid du Colombier 	default:
291*7d9195a7SDavid du Colombier 		Bprint(bioout, "bad modifier\n");
292*7d9195a7SDavid du Colombier 		return 0;
293*7d9195a7SDavid du Colombier 	case 'o':
294*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-4lo ", mem ? (ushort)getmem_2(dot) : val);
295*7d9195a7SDavid du Colombier 		inc = 2;
296*7d9195a7SDavid du Colombier 		break;
297*7d9195a7SDavid du Colombier 
298*7d9195a7SDavid du Colombier 	case 'O':
299*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-8lo ", mem ? getmem_4(dot) : val);
300*7d9195a7SDavid du Colombier 		inc = 4;
301*7d9195a7SDavid du Colombier 		break;
302*7d9195a7SDavid du Colombier 
303*7d9195a7SDavid du Colombier 	case 'q':
304*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-4lo ", mem ? (short)getmem_2(dot) : val);
305*7d9195a7SDavid du Colombier 		inc = 2;
306*7d9195a7SDavid du Colombier 		break;
307*7d9195a7SDavid du Colombier 
308*7d9195a7SDavid du Colombier 	case 'Q':
309*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-8lo ", mem ? (long)getmem_4(dot) : val);
310*7d9195a7SDavid du Colombier 		inc = 4;
311*7d9195a7SDavid du Colombier 		break;
312*7d9195a7SDavid du Colombier 
313*7d9195a7SDavid du Colombier 	case 'd':
314*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-5ld ", mem ? (short)getmem_2(dot) : val);
315*7d9195a7SDavid du Colombier 		inc = 2;
316*7d9195a7SDavid du Colombier 		break;
317*7d9195a7SDavid du Colombier 
318*7d9195a7SDavid du Colombier 
319*7d9195a7SDavid du Colombier 	case 'D':
320*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-8ld ", mem ? (long)getmem_4(dot) : val);
321*7d9195a7SDavid du Colombier 		inc = 4;
322*7d9195a7SDavid du Colombier 		break;
323*7d9195a7SDavid du Colombier 
324*7d9195a7SDavid du Colombier 	case 'x':
325*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "#%-4lux ", mem ? (long)getmem_2(dot) : val);
326*7d9195a7SDavid du Colombier 		inc = 2;
327*7d9195a7SDavid du Colombier 		break;
328*7d9195a7SDavid du Colombier 
329*7d9195a7SDavid du Colombier 	case 'X':
330*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "#%-8lux ", mem ? (long)getmem_4(dot) : val);
331*7d9195a7SDavid du Colombier 		inc = 4;
332*7d9195a7SDavid du Colombier 		break;
333*7d9195a7SDavid du Colombier 
334*7d9195a7SDavid du Colombier 	case 'u':
335*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-5ld ", mem ? (ushort)getmem_2(dot) : val);
336*7d9195a7SDavid du Colombier 		inc = 2;
337*7d9195a7SDavid du Colombier 		break;
338*7d9195a7SDavid du Colombier 
339*7d9195a7SDavid du Colombier 	case 'U':
340*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-8ld ", mem ? (ulong)getmem_4(dot) : val);
341*7d9195a7SDavid du Colombier 		inc = 4;
342*7d9195a7SDavid du Colombier 		break;
343*7d9195a7SDavid du Colombier 
344*7d9195a7SDavid du Colombier 	case 'b':
345*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%-3ld ", mem ? getmem_b(dot) : val);
346*7d9195a7SDavid du Colombier 		inc = 1;
347*7d9195a7SDavid du Colombier 		break;
348*7d9195a7SDavid du Colombier 
349*7d9195a7SDavid du Colombier 	case 'c':
350*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%c ", (int)(mem ? getmem_b(dot) : val));
351*7d9195a7SDavid du Colombier 		inc = 1;
352*7d9195a7SDavid du Colombier 		break;
353*7d9195a7SDavid du Colombier 
354*7d9195a7SDavid du Colombier 	case 'C':
355*7d9195a7SDavid du Colombier 		ch = mem ? getmem_b(dot) : val;
356*7d9195a7SDavid du Colombier 		if(isprint(ch))
357*7d9195a7SDavid du Colombier 			c = Bprint(bioout, "%c ", ch);
358*7d9195a7SDavid du Colombier 		else
359*7d9195a7SDavid du Colombier 			c = Bprint(bioout, "\\x%.2x ", ch);
360*7d9195a7SDavid du Colombier 		inc = 1;
361*7d9195a7SDavid du Colombier 		break;
362*7d9195a7SDavid du Colombier 
363*7d9195a7SDavid du Colombier 	case 's':
364*7d9195a7SDavid du Colombier 		i = 0;
365*7d9195a7SDavid du Colombier 		while(ch = getmem_b(dot+i))
366*7d9195a7SDavid du Colombier 			str[i++] = ch;
367*7d9195a7SDavid du Colombier 		str[i] = '\0';
368*7d9195a7SDavid du Colombier 		dot += i;
369*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%s", str);
370*7d9195a7SDavid du Colombier 		inc = 0;
371*7d9195a7SDavid du Colombier 		break;
372*7d9195a7SDavid du Colombier 
373*7d9195a7SDavid du Colombier 	case 'S':
374*7d9195a7SDavid du Colombier 		i = 0;
375*7d9195a7SDavid du Colombier 		while(ch = getmem_b(dot+i))
376*7d9195a7SDavid du Colombier 			str[i++] = ch;
377*7d9195a7SDavid du Colombier 		str[i] = '\0';
378*7d9195a7SDavid du Colombier 		dot += i;
379*7d9195a7SDavid du Colombier 		for(p = str; *p; p++)
380*7d9195a7SDavid du Colombier 			if(isprint(*p))
381*7d9195a7SDavid du Colombier 				c += Bprint(bioout, "%c", *p);
382*7d9195a7SDavid du Colombier 			else
383*7d9195a7SDavid du Colombier 				c += Bprint(bioout, "\\x%.2ux", *p);
384*7d9195a7SDavid du Colombier 		inc = 0;
385*7d9195a7SDavid du Colombier 		break;
386*7d9195a7SDavid du Colombier 
387*7d9195a7SDavid du Colombier 	case 'Y':
388*7d9195a7SDavid du Colombier 		p = ctime(mem ? getmem_b(dot) : val);
389*7d9195a7SDavid du Colombier 		p[30] = '\0';
390*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "%s", p);
391*7d9195a7SDavid du Colombier 		inc = 4;
392*7d9195a7SDavid du Colombier 		break;
393*7d9195a7SDavid du Colombier 
394*7d9195a7SDavid du Colombier 	case 'a':
395*7d9195a7SDavid du Colombier 		symoff(str, sizeof(str), dot, CTEXT);
396*7d9195a7SDavid du Colombier 		Bprint(bioout, "%s", str);
397*7d9195a7SDavid du Colombier 		inc = 0;
398*7d9195a7SDavid du Colombier 		break;
399*7d9195a7SDavid du Colombier 
400*7d9195a7SDavid du Colombier 	case 'e':
401*7d9195a7SDavid du Colombier 		for (i = 0; globalsym(&s, i); i++)
402*7d9195a7SDavid du Colombier 			Bprint(bioout, "%-15s #%lux\n", s.name,	getmem_4(s.value));
403*7d9195a7SDavid du Colombier 		inc = 0;
404*7d9195a7SDavid du Colombier 		break;
405*7d9195a7SDavid du Colombier 
406*7d9195a7SDavid du Colombier 	case 'I':
407*7d9195a7SDavid du Colombier 	case 'i':
408*7d9195a7SDavid du Colombier 		inc = machdata->das(symmap, dot, fmt, str, sizeof(str));
409*7d9195a7SDavid du Colombier 		if (inc < 0) {
410*7d9195a7SDavid du Colombier 			Bprint(bioout, "qi: %r\n");
411*7d9195a7SDavid du Colombier 			return 0;
412*7d9195a7SDavid du Colombier 		}
413*7d9195a7SDavid du Colombier 		c = Bprint(bioout, "\t%s", str);
414*7d9195a7SDavid du Colombier 		break;
415*7d9195a7SDavid du Colombier 
416*7d9195a7SDavid du Colombier 	case 'n':
417*7d9195a7SDavid du Colombier 		c = width+1;
418*7d9195a7SDavid du Colombier 		inc = 0;
419*7d9195a7SDavid du Colombier 		break;
420*7d9195a7SDavid du Colombier 
421*7d9195a7SDavid du Colombier 	case '-':
422*7d9195a7SDavid du Colombier 		c = 0;
423*7d9195a7SDavid du Colombier 		inc = -1;
424*7d9195a7SDavid du Colombier 		break;
425*7d9195a7SDavid du Colombier 
426*7d9195a7SDavid du Colombier 	case '+':
427*7d9195a7SDavid du Colombier 		c = 0;
428*7d9195a7SDavid du Colombier 		inc = 1;
429*7d9195a7SDavid du Colombier 		break;
430*7d9195a7SDavid du Colombier 
431*7d9195a7SDavid du Colombier 	case '^':
432*7d9195a7SDavid du Colombier 		c = 0;
433*7d9195a7SDavid du Colombier 		if(inc > 0)
434*7d9195a7SDavid du Colombier 			inc = -inc;
435*7d9195a7SDavid du Colombier 		break;
436*7d9195a7SDavid du Colombier 
437*7d9195a7SDavid du Colombier 	case 'z':
438*7d9195a7SDavid du Colombier 		if (findsym(dot, CTEXT, &s))
439*7d9195a7SDavid du Colombier 			Bprint(bioout, "  %s() ", s.name);
440*7d9195a7SDavid du Colombier 		printsource(dot);
441*7d9195a7SDavid du Colombier 		inc = 0;
442*7d9195a7SDavid du Colombier 		break;
443*7d9195a7SDavid du Colombier 	}
444*7d9195a7SDavid du Colombier 	return c;
445*7d9195a7SDavid du Colombier }
446*7d9195a7SDavid du Colombier 
447*7d9195a7SDavid du Colombier void
448*7d9195a7SDavid du Colombier eval(char *addr, char *p)
449*7d9195a7SDavid du Colombier {
450*7d9195a7SDavid du Colombier 	ulong val;
451*7d9195a7SDavid du Colombier 
452*7d9195a7SDavid du Colombier 	val = expr(addr);
453*7d9195a7SDavid du Colombier 	p = nextc(p);
454*7d9195a7SDavid du Colombier 	if(*p == '\0') {
455*7d9195a7SDavid du Colombier 		p[0] = fmt;
456*7d9195a7SDavid du Colombier 		p[1] = '\0';
457*7d9195a7SDavid du Colombier 	}
458*7d9195a7SDavid du Colombier 	pfmt(*p, 0, val);
459*7d9195a7SDavid du Colombier 	Bprint(bioout, "\n");
460*7d9195a7SDavid du Colombier }
461*7d9195a7SDavid du Colombier 
462*7d9195a7SDavid du Colombier void
463*7d9195a7SDavid du Colombier quesie(char *p)
464*7d9195a7SDavid du Colombier {
465*7d9195a7SDavid du Colombier 	int c, count, i;
466*7d9195a7SDavid du Colombier 	char tbuf[512];
467*7d9195a7SDavid du Colombier 
468*7d9195a7SDavid du Colombier 	c = 0;
469*7d9195a7SDavid du Colombier 	symoff(tbuf, sizeof(tbuf), dot, CTEXT);
470*7d9195a7SDavid du Colombier 	Bprint(bioout, "%s?\t", tbuf);
471*7d9195a7SDavid du Colombier 
472*7d9195a7SDavid du Colombier 	while(*p) {
473*7d9195a7SDavid du Colombier 		p = nextc(p);
474*7d9195a7SDavid du Colombier 		if(*p == '"') {
475*7d9195a7SDavid du Colombier 			for(p++; *p && *p != '"'; p++) {
476*7d9195a7SDavid du Colombier 				Bputc(bioout, *p);
477*7d9195a7SDavid du Colombier 				c++;
478*7d9195a7SDavid du Colombier 			}
479*7d9195a7SDavid du Colombier 			if(*p)
480*7d9195a7SDavid du Colombier 				p++;
481*7d9195a7SDavid du Colombier 			continue;
482*7d9195a7SDavid du Colombier 		}
483*7d9195a7SDavid du Colombier 		count = 0;
484*7d9195a7SDavid du Colombier 		while(*p >= '0' && *p <= '9')
485*7d9195a7SDavid du Colombier 			count = count*10 + (*p++ - '0');
486*7d9195a7SDavid du Colombier 		if(count == 0)
487*7d9195a7SDavid du Colombier 			count = 1;
488*7d9195a7SDavid du Colombier 		p = nextc(p);
489*7d9195a7SDavid du Colombier 		if(*p == '\0') {
490*7d9195a7SDavid du Colombier 			p[0] = fmt;
491*7d9195a7SDavid du Colombier 			p[1] = '\0';
492*7d9195a7SDavid du Colombier 		}
493*7d9195a7SDavid du Colombier 		for(i = 0; i < count; i++) {
494*7d9195a7SDavid du Colombier 			c += pfmt(*p, 1, 0);
495*7d9195a7SDavid du Colombier 			dot += inc;
496*7d9195a7SDavid du Colombier 			if(c > width) {
497*7d9195a7SDavid du Colombier 				Bprint(bioout, "\n");
498*7d9195a7SDavid du Colombier 				symoff(tbuf, sizeof(tbuf), dot, CTEXT);
499*7d9195a7SDavid du Colombier 				Bprint(bioout, "%s?\t", tbuf);
500*7d9195a7SDavid du Colombier 				c = 0;
501*7d9195a7SDavid du Colombier 			}
502*7d9195a7SDavid du Colombier 		}
503*7d9195a7SDavid du Colombier 		fmt = *p++;
504*7d9195a7SDavid du Colombier 		p = nextc(p);
505*7d9195a7SDavid du Colombier 	}
506*7d9195a7SDavid du Colombier 	Bprint(bioout, "\n");
507*7d9195a7SDavid du Colombier }
508*7d9195a7SDavid du Colombier 
509*7d9195a7SDavid du Colombier void
510*7d9195a7SDavid du Colombier catcher(void *a, char *msg)
511*7d9195a7SDavid du Colombier {
512*7d9195a7SDavid du Colombier 	USED(a);
513*7d9195a7SDavid du Colombier 	if(strcmp(msg, "interrupt") != 0)
514*7d9195a7SDavid du Colombier 		noted(NDFLT);
515*7d9195a7SDavid du Colombier 
516*7d9195a7SDavid du Colombier 	count = 1;
517*7d9195a7SDavid du Colombier 	print("qi\n");
518*7d9195a7SDavid du Colombier 	noted(NCONT);
519*7d9195a7SDavid du Colombier }
520*7d9195a7SDavid du Colombier 
521*7d9195a7SDavid du Colombier void
522*7d9195a7SDavid du Colombier setreg(char *addr, char *cp)
523*7d9195a7SDavid du Colombier {
524*7d9195a7SDavid du Colombier 	int rn;
525*7d9195a7SDavid du Colombier 
526*7d9195a7SDavid du Colombier 	dot = expr(addr);
527*7d9195a7SDavid du Colombier 	cp = nextc(cp);
528*7d9195a7SDavid du Colombier 	if(strcmp(cp, "pc") == 0) {
529*7d9195a7SDavid du Colombier 		reg.pc = dot;
530*7d9195a7SDavid du Colombier 		return;
531*7d9195a7SDavid du Colombier 	}
532*7d9195a7SDavid du Colombier 	if(strcmp(cp, "sp") == 0) {
533*7d9195a7SDavid du Colombier 		reg.r[1] = dot;
534*7d9195a7SDavid du Colombier 		return;
535*7d9195a7SDavid du Colombier 	}
536*7d9195a7SDavid du Colombier 	if(strcmp(cp, "lr") == 0) {
537*7d9195a7SDavid du Colombier 		reg.lr = dot;
538*7d9195a7SDavid du Colombier 		return;
539*7d9195a7SDavid du Colombier 	}
540*7d9195a7SDavid du Colombier 	if(strcmp(cp, "ctr") == 0) {
541*7d9195a7SDavid du Colombier 		reg.ctr = dot;
542*7d9195a7SDavid du Colombier 		return;
543*7d9195a7SDavid du Colombier 	}
544*7d9195a7SDavid du Colombier 	if(strcmp(cp, "fpscr") == 0) {
545*7d9195a7SDavid du Colombier 		reg.fpscr = dot;
546*7d9195a7SDavid du Colombier 		return;
547*7d9195a7SDavid du Colombier 	}
548*7d9195a7SDavid du Colombier 	if(strcmp(cp, "xer") == 0) {
549*7d9195a7SDavid du Colombier 		reg.xer = dot;
550*7d9195a7SDavid du Colombier 		return;
551*7d9195a7SDavid du Colombier 	}
552*7d9195a7SDavid du Colombier 	if(strcmp(cp, "cr") == 0) {
553*7d9195a7SDavid du Colombier 		reg.cr = dot;
554*7d9195a7SDavid du Colombier 		return;
555*7d9195a7SDavid du Colombier 	}
556*7d9195a7SDavid du Colombier 	if(*cp++ == 'r') {
557*7d9195a7SDavid du Colombier 		rn = strtoul(cp, 0, 10);
558*7d9195a7SDavid du Colombier 		if(rn > 0 && rn < 32) {
559*7d9195a7SDavid du Colombier 			reg.r[rn] = dot;
560*7d9195a7SDavid du Colombier 			return;
561*7d9195a7SDavid du Colombier 		}
562*7d9195a7SDavid du Colombier 	}
563*7d9195a7SDavid du Colombier 	Bprint(bioout, "bad register\n");
564*7d9195a7SDavid du Colombier }
565*7d9195a7SDavid du Colombier 
566*7d9195a7SDavid du Colombier void
567*7d9195a7SDavid du Colombier cmd(void)
568*7d9195a7SDavid du Colombier {
569*7d9195a7SDavid du Colombier 	char *p, *a, *cp, *gotint;
570*7d9195a7SDavid du Colombier 	char addr[128];
571*7d9195a7SDavid du Colombier 	static char *cmdlet = ":$?/=>";
572*7d9195a7SDavid du Colombier 	int n, i;
573*7d9195a7SDavid du Colombier 
574*7d9195a7SDavid du Colombier 	notify(catcher);
575*7d9195a7SDavid du Colombier 
576*7d9195a7SDavid du Colombier 	dot = reg.pc;
577*7d9195a7SDavid du Colombier 	setjmp(errjmp);
578*7d9195a7SDavid du Colombier 
579*7d9195a7SDavid du Colombier 	for(;;) {
580*7d9195a7SDavid du Colombier 		Bflush(bioout);
581*7d9195a7SDavid du Colombier 		p = buf;
582*7d9195a7SDavid du Colombier 		n = 0;
583*7d9195a7SDavid du Colombier 		for(;;) {
584*7d9195a7SDavid du Colombier 			i = Bgetc(bin);
585*7d9195a7SDavid du Colombier 			if(i < 0)
586*7d9195a7SDavid du Colombier 				exits(0);
587*7d9195a7SDavid du Colombier 			*p++ = i;
588*7d9195a7SDavid du Colombier 			n++;
589*7d9195a7SDavid du Colombier 			if(i == '\n')
590*7d9195a7SDavid du Colombier 				break;
591*7d9195a7SDavid du Colombier 		}
592*7d9195a7SDavid du Colombier 
593*7d9195a7SDavid du Colombier 		if(buf[0] == '\n')
594*7d9195a7SDavid du Colombier 			strcpy(buf, lastcmd);
595*7d9195a7SDavid du Colombier 		else {
596*7d9195a7SDavid du Colombier 			buf[n-1] = '\0';
597*7d9195a7SDavid du Colombier 			strcpy(lastcmd, buf);
598*7d9195a7SDavid du Colombier 		}
599*7d9195a7SDavid du Colombier 		p = buf;
600*7d9195a7SDavid du Colombier 		a = addr;
601*7d9195a7SDavid du Colombier 
602*7d9195a7SDavid du Colombier 		for(;;) {
603*7d9195a7SDavid du Colombier 			p = nextc(p);
604*7d9195a7SDavid du Colombier 			if(*p == 0 || strchr(cmdlet, *p))
605*7d9195a7SDavid du Colombier 				break;
606*7d9195a7SDavid du Colombier 			*a++ = *p++;
607*7d9195a7SDavid du Colombier 		}
608*7d9195a7SDavid du Colombier 
609*7d9195a7SDavid du Colombier 		*a = '\0';
610*7d9195a7SDavid du Colombier 		cmdcount = 1;
611*7d9195a7SDavid du Colombier 		cp = strchr(addr, ',');
612*7d9195a7SDavid du Colombier 		if(cp != 0) {
613*7d9195a7SDavid du Colombier 			if(cp[1] == '#')
614*7d9195a7SDavid du Colombier 				cmdcount = strtoul(cp+2, &gotint, 16);
615*7d9195a7SDavid du Colombier 			else
616*7d9195a7SDavid du Colombier 				cmdcount = strtoul(cp+1, &gotint, 0);
617*7d9195a7SDavid du Colombier 			*cp = '\0';
618*7d9195a7SDavid du Colombier 		}
619*7d9195a7SDavid du Colombier 
620*7d9195a7SDavid du Colombier 		switch(*p) {
621*7d9195a7SDavid du Colombier 		case '$':
622*7d9195a7SDavid du Colombier 			dollar(p+1);
623*7d9195a7SDavid du Colombier 			break;
624*7d9195a7SDavid du Colombier 		case ':':
625*7d9195a7SDavid du Colombier 			colon(addr, p+1);
626*7d9195a7SDavid du Colombier 			break;
627*7d9195a7SDavid du Colombier 		case '/':
628*7d9195a7SDavid du Colombier 		case '?':
629*7d9195a7SDavid du Colombier 			dot = expr(addr);
630*7d9195a7SDavid du Colombier 			for(i = 0; i < cmdcount; i++)
631*7d9195a7SDavid du Colombier 				quesie(p+1);
632*7d9195a7SDavid du Colombier 			break;
633*7d9195a7SDavid du Colombier 		case '=':
634*7d9195a7SDavid du Colombier 			eval(addr, p+1);
635*7d9195a7SDavid du Colombier 			break;
636*7d9195a7SDavid du Colombier 		case '>':
637*7d9195a7SDavid du Colombier 			setreg(addr, p+1);
638*7d9195a7SDavid du Colombier 			break;
639*7d9195a7SDavid du Colombier 		default:
640*7d9195a7SDavid du Colombier 			Bprint(bioout, "?\n");
641*7d9195a7SDavid du Colombier 			break;
642*7d9195a7SDavid du Colombier 		}
643*7d9195a7SDavid du Colombier 	}
644*7d9195a7SDavid du Colombier }
645