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