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