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