xref: /csrg-svn/sys/tahoe/stand/prf.c (revision 25870)
1*25870Ssam /*	prf.c	1.1	86/01/12	*/
2*25870Ssam /*	prf.c	4.3	81/05/05	*/
3*25870Ssam 
4*25870Ssam #include "../machine/mtpr.h"
5*25870Ssam 
6*25870Ssam #include "param.h"
7*25870Ssam #include "../tahoe/cp.h"
8*25870Ssam #ifdef NOIO
9*25870Ssam #define CINADR	0xf0000		/* Dummy keyboard (memory mapped) */
10*25870Ssam #define COUTADR	0xf1000		/* Dummy screen 	-,,-	  */
11*25870Ssam #endif
12*25870Ssam 
13*25870Ssam /*
14*25870Ssam  * Scaled down version of C Library printf.
15*25870Ssam  * Used to print diagnostic information directly on console tty.
16*25870Ssam  * Since it is not interrupt driven, all system activities are
17*25870Ssam  * suspended.  Printf should not be used for chit-chat.
18*25870Ssam  *
19*25870Ssam  * One additional format: %b is supported to decode error registers.
20*25870Ssam  * Usage is:
21*25870Ssam  *	printf("reg=%b\n", regval, "<base><arg>*");
22*25870Ssam  * Where <base> is the output base expressed as a control character,
23*25870Ssam  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
24*25870Ssam  * characters, the first of which gives the bit number to be inspected
25*25870Ssam  * (origin 1), and the next characters (up to a control character, i.e.
26*25870Ssam  * a character <= 32), give the name of the register.  Thus
27*25870Ssam  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
28*25870Ssam  * would produce output:
29*25870Ssam  *	reg=2<BITTWO,BITONE>
30*25870Ssam  */
31*25870Ssam /*VARARGS1*/
32*25870Ssam printf(fmt, x1)
33*25870Ssam 	char *fmt;
34*25870Ssam 	unsigned x1;
35*25870Ssam {
36*25870Ssam 
37*25870Ssam 	prf(fmt, &x1);
38*25870Ssam }
39*25870Ssam 
40*25870Ssam prf(fmt, adx)
41*25870Ssam 	register char *fmt;
42*25870Ssam 	register u_int *adx;
43*25870Ssam {
44*25870Ssam 	register int b, c, i;
45*25870Ssam 	char *s;
46*25870Ssam 	int any;
47*25870Ssam 
48*25870Ssam loop:
49*25870Ssam 	while ((c = *fmt++) != '%') {
50*25870Ssam 		if(c == '\0')
51*25870Ssam 			return;
52*25870Ssam 		putchar(c);
53*25870Ssam 	}
54*25870Ssam again:
55*25870Ssam 	c = *fmt++;
56*25870Ssam 	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
57*25870Ssam 	switch (c) {
58*25870Ssam 
59*25870Ssam 	case 'l':
60*25870Ssam 		goto again;
61*25870Ssam 	case 'x': case 'X':
62*25870Ssam 		b = 16;
63*25870Ssam 		goto number;
64*25870Ssam 	case 'd': case 'D':
65*25870Ssam 	case 'u':		/* what a joke */
66*25870Ssam 		b = 10;
67*25870Ssam 		goto number;
68*25870Ssam 	case 'o': case 'O':
69*25870Ssam 		b = 8;
70*25870Ssam number:
71*25870Ssam 		printn((u_long)*adx, b);
72*25870Ssam 		break;
73*25870Ssam 	case 'c':
74*25870Ssam 		b = *adx;
75*25870Ssam 		for (i = 24; i >= 0; i -= 8)
76*25870Ssam 			if (c = (b >> i) & 0x7f)
77*25870Ssam 				putchar(c);
78*25870Ssam 		break;
79*25870Ssam 	case 'b':
80*25870Ssam 		b = *adx++;
81*25870Ssam 		s = (char *)*adx;
82*25870Ssam 		printn((u_long)b, *s++);
83*25870Ssam 		any = 0;
84*25870Ssam 		if (b) {
85*25870Ssam 			putchar('<');
86*25870Ssam 			while (i = *s++) {
87*25870Ssam 				if (b & (1 << (i-1))) {
88*25870Ssam 					if (any)
89*25870Ssam 						putchar(',');
90*25870Ssam 					any = 1;
91*25870Ssam 					for (; (c = *s) > 32; s++)
92*25870Ssam 						putchar(c);
93*25870Ssam 				} else
94*25870Ssam 					for (; *s > 32; s++)
95*25870Ssam 						;
96*25870Ssam 			}
97*25870Ssam 			putchar('>');
98*25870Ssam 		}
99*25870Ssam 		break;
100*25870Ssam 
101*25870Ssam 	case 's':
102*25870Ssam 		s = (char *)*adx;
103*25870Ssam 		while (c = *s++)
104*25870Ssam 			putchar(c);
105*25870Ssam 		break;
106*25870Ssam 	}
107*25870Ssam 	adx++;
108*25870Ssam 	goto loop;
109*25870Ssam }
110*25870Ssam 
111*25870Ssam /*
112*25870Ssam  * Printn prints a number n in base b.
113*25870Ssam  * We don't use recursion to avoid deep kernel stacks.
114*25870Ssam  */
115*25870Ssam printn(n, b)
116*25870Ssam 	u_long n;
117*25870Ssam {
118*25870Ssam 	char prbuf[11];
119*25870Ssam 	register char *cp;
120*25870Ssam 
121*25870Ssam 	if (b == 10 && (int)n < 0) {
122*25870Ssam 		putchar('-');
123*25870Ssam 		n = (unsigned)(-(int)n);
124*25870Ssam 	}
125*25870Ssam 	cp = prbuf;
126*25870Ssam 	do {
127*25870Ssam 		*cp++ = "0123456789abcdef"[n%b];
128*25870Ssam 		n /= b;
129*25870Ssam 	} while (n);
130*25870Ssam 	do
131*25870Ssam 		putchar(*--cp);
132*25870Ssam 	while (cp > prbuf);
133*25870Ssam }
134*25870Ssam 
135*25870Ssam /*
136*25870Ssam  * Print a character on console.
137*25870Ssam  * Attempts to save and restore device
138*25870Ssam  * status.
139*25870Ssam  *
140*25870Ssam  * Whether or not printing is inhibited,
141*25870Ssam  * the last MSGBUFS characters
142*25870Ssam  * are saved in msgbuf for inspection later.
143*25870Ssam  */
144*25870Ssam #ifdef NOIO
145*25870Ssam char	*coutadr=(char *)COUTADR;
146*25870Ssam putchar(c)
147*25870Ssam 	register c;
148*25870Ssam {
149*25870Ssam 	*coutadr++ = c;
150*25870Ssam }
151*25870Ssam 
152*25870Ssam char	*cinadr=(char *)CINADR;
153*25870Ssam getchar()
154*25870Ssam {
155*25870Ssam 	return( *cinadr++ );
156*25870Ssam }
157*25870Ssam 
158*25870Ssam #else
159*25870Ssam struct	cpdcb_o cpout;
160*25870Ssam struct	cpdcb_i cpin;
161*25870Ssam 
162*25870Ssam /* console requires even parity */
163*25870Ssam #define EVENP
164*25870Ssam putchar(c)
165*25870Ssam char c;
166*25870Ssam {
167*25870Ssam 	int time;
168*25870Ssam #ifdef EVENP
169*25870Ssam 	register mask, par;
170*25870Ssam 
171*25870Ssam 	for(par=0, mask=1; mask!=0200; mask<<=1, par<<=1)
172*25870Ssam 		par ^= c&mask;
173*25870Ssam 	c |= par;
174*25870Ssam #endif EVENP
175*25870Ssam 	cpout.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
176*25870Ssam 	cpout.cp_hdr.cp_comm = CPWRITE;
177*25870Ssam 	cpout.cp_hdr.cp_count = 1;
178*25870Ssam 	cpout.cp_buf[0] = c;
179*25870Ssam 	mtpr(CPMDCB, &cpout);
180*25870Ssam #ifdef SIMIO
181*25870Ssam 	simout(&cpout);
182*25870Ssam #endif
183*25870Ssam 	time = 100000;				/* Delay loop */
184*25870Ssam 	while (time--) {
185*25870Ssam 		uncache (&cpout.cp_hdr.cp_unit) ;
186*25870Ssam 		if (cpout.cp_hdr.cp_unit & CPDONE) break;
187*25870Ssam 	}
188*25870Ssam 	if (c == '\n') putchar ('\r');
189*25870Ssam }
190*25870Ssam 
191*25870Ssam #ifdef SIMIO
192*25870Ssam simout(addr)
193*25870Ssam {
194*25870Ssam 	asm(".byte 0x4");
195*25870Ssam }
196*25870Ssam simin(addr)
197*25870Ssam {
198*25870Ssam 	asm(".byte 0x3");
199*25870Ssam }
200*25870Ssam #endif
201*25870Ssam 
202*25870Ssam getchar()
203*25870Ssam {
204*25870Ssam 	char	c;
205*25870Ssam 
206*25870Ssam 	cpin.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
207*25870Ssam 	cpin.cp_hdr.cp_comm = CPREAD;
208*25870Ssam 	cpin.cp_hdr.cp_count = 1;
209*25870Ssam 	mtpr(CPMDCB, &cpin);
210*25870Ssam #ifdef SIMIO
211*25870Ssam 	simin(&cpin);
212*25870Ssam #endif
213*25870Ssam 	while ((cpin.cp_hdr.cp_unit & CPDONE) == 0)
214*25870Ssam 		uncache (&cpin.cp_hdr.cp_unit);
215*25870Ssam 	uncache (&cpin.cpi_buf[0]);
216*25870Ssam 	c = cpin.cpi_buf[0] & 0x7f;
217*25870Ssam 	if (c == '\r')  c = '\n';
218*25870Ssam 	putchar(c);
219*25870Ssam 	return(c);
220*25870Ssam }
221*25870Ssam #endif
222*25870Ssam 
223*25870Ssam 
224*25870Ssam gets(buf)
225*25870Ssam 	char *buf;
226*25870Ssam {
227*25870Ssam 	register char *lp;
228*25870Ssam 	register c;
229*25870Ssam 
230*25870Ssam 	lp = buf;
231*25870Ssam 	for (;;) {
232*25870Ssam 		c = getchar() & 0177;
233*25870Ssam 	store:
234*25870Ssam 		switch(c) {
235*25870Ssam 		case '\n':
236*25870Ssam 		case '\r':
237*25870Ssam 			c = '\n';
238*25870Ssam 			*lp++ = '\0';
239*25870Ssam 			return;
240*25870Ssam 		case '\b':
241*25870Ssam 		case '#':
242*25870Ssam 			lp--;
243*25870Ssam 			if (lp < buf)
244*25870Ssam 				lp = buf;
245*25870Ssam 			continue;
246*25870Ssam 		case '@':
247*25870Ssam 		case 'u'&037:
248*25870Ssam 			lp = buf;
249*25870Ssam 			putchar('\n');
250*25870Ssam 			continue;
251*25870Ssam 		default:
252*25870Ssam 			*lp++ = c;
253*25870Ssam 		}
254*25870Ssam 	}
255*25870Ssam }
256