xref: /csrg-svn/sys/tahoe/stand/prf.c (revision 29979)
1*29979Skarels /*	prf.c	1.2	86/11/04	*/
225870Ssam /*	prf.c	4.3	81/05/05	*/
325870Ssam 
425870Ssam #include "../machine/mtpr.h"
525870Ssam 
625870Ssam #include "param.h"
725870Ssam #include "../tahoe/cp.h"
825870Ssam 
925870Ssam /*
1025870Ssam  * Scaled down version of C Library printf.
1125870Ssam  * Used to print diagnostic information directly on console tty.
1225870Ssam  * Since it is not interrupt driven, all system activities are
1325870Ssam  * suspended.  Printf should not be used for chit-chat.
1425870Ssam  *
1525870Ssam  * One additional format: %b is supported to decode error registers.
1625870Ssam  * Usage is:
1725870Ssam  *	printf("reg=%b\n", regval, "<base><arg>*");
1825870Ssam  * Where <base> is the output base expressed as a control character,
1925870Ssam  * e.g. \10 gives octal; \20 gives hex.  Each arg is a sequence of
2025870Ssam  * characters, the first of which gives the bit number to be inspected
2125870Ssam  * (origin 1), and the next characters (up to a control character, i.e.
2225870Ssam  * a character <= 32), give the name of the register.  Thus
2325870Ssam  *	printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
2425870Ssam  * would produce output:
2525870Ssam  *	reg=2<BITTWO,BITONE>
2625870Ssam  */
2725870Ssam /*VARARGS1*/
2825870Ssam printf(fmt, x1)
2925870Ssam 	char *fmt;
3025870Ssam 	unsigned x1;
3125870Ssam {
3225870Ssam 
3325870Ssam 	prf(fmt, &x1);
3425870Ssam }
3525870Ssam 
3625870Ssam prf(fmt, adx)
3725870Ssam 	register char *fmt;
3825870Ssam 	register u_int *adx;
3925870Ssam {
4025870Ssam 	register int b, c, i;
4125870Ssam 	char *s;
4225870Ssam 	int any;
4325870Ssam 
4425870Ssam loop:
4525870Ssam 	while ((c = *fmt++) != '%') {
46*29979Skarels 		if (c == '\0')
4725870Ssam 			return;
4825870Ssam 		putchar(c);
4925870Ssam 	}
5025870Ssam again:
5125870Ssam 	c = *fmt++;
5225870Ssam 	/* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
5325870Ssam 	switch (c) {
5425870Ssam 
5525870Ssam 	case 'l':
5625870Ssam 		goto again;
5725870Ssam 	case 'x': case 'X':
5825870Ssam 		b = 16;
5925870Ssam 		goto number;
6025870Ssam 	case 'd': case 'D':
6125870Ssam 	case 'u':		/* what a joke */
6225870Ssam 		b = 10;
6325870Ssam 		goto number;
6425870Ssam 	case 'o': case 'O':
6525870Ssam 		b = 8;
6625870Ssam number:
6725870Ssam 		printn((u_long)*adx, b);
6825870Ssam 		break;
6925870Ssam 	case 'c':
7025870Ssam 		b = *adx;
7125870Ssam 		for (i = 24; i >= 0; i -= 8)
7225870Ssam 			if (c = (b >> i) & 0x7f)
7325870Ssam 				putchar(c);
7425870Ssam 		break;
7525870Ssam 	case 'b':
7625870Ssam 		b = *adx++;
7725870Ssam 		s = (char *)*adx;
7825870Ssam 		printn((u_long)b, *s++);
7925870Ssam 		any = 0;
8025870Ssam 		if (b) {
8125870Ssam 			while (i = *s++) {
8225870Ssam 				if (b & (1 << (i-1))) {
83*29979Skarels 					putchar(any? ',' : '<');
8425870Ssam 					any = 1;
8525870Ssam 					for (; (c = *s) > 32; s++)
8625870Ssam 						putchar(c);
8725870Ssam 				} else
8825870Ssam 					for (; *s > 32; s++)
8925870Ssam 						;
9025870Ssam 			}
91*29979Skarels 			if (any)
92*29979Skarels 				putchar('>');
9325870Ssam 		}
9425870Ssam 		break;
9525870Ssam 
9625870Ssam 	case 's':
9725870Ssam 		s = (char *)*adx;
9825870Ssam 		while (c = *s++)
9925870Ssam 			putchar(c);
10025870Ssam 		break;
10125870Ssam 	}
10225870Ssam 	adx++;
10325870Ssam 	goto loop;
10425870Ssam }
10525870Ssam 
10625870Ssam /*
10725870Ssam  * Printn prints a number n in base b.
10825870Ssam  * We don't use recursion to avoid deep kernel stacks.
10925870Ssam  */
11025870Ssam printn(n, b)
11125870Ssam 	u_long n;
11225870Ssam {
11325870Ssam 	char prbuf[11];
11425870Ssam 	register char *cp;
11525870Ssam 
11625870Ssam 	if (b == 10 && (int)n < 0) {
11725870Ssam 		putchar('-');
11825870Ssam 		n = (unsigned)(-(int)n);
11925870Ssam 	}
12025870Ssam 	cp = prbuf;
12125870Ssam 	do {
12225870Ssam 		*cp++ = "0123456789abcdef"[n%b];
12325870Ssam 		n /= b;
12425870Ssam 	} while (n);
12525870Ssam 	do
12625870Ssam 		putchar(*--cp);
12725870Ssam 	while (cp > prbuf);
12825870Ssam }
12925870Ssam 
13025870Ssam /*
13125870Ssam  * Print a character on console.
13225870Ssam  */
13325870Ssam struct	cpdcb_o cpout;
13425870Ssam struct	cpdcb_i cpin;
13525870Ssam 
13625870Ssam /* console requires even parity */
13725870Ssam #define EVENP
138*29979Skarels 
13925870Ssam putchar(c)
140*29979Skarels 	char c;
14125870Ssam {
14225870Ssam 	int time;
14325870Ssam #ifdef EVENP
14425870Ssam 	register mask, par;
14525870Ssam 
146*29979Skarels 	for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1)
14725870Ssam 		par ^= c&mask;
14825870Ssam 	c |= par;
14925870Ssam #endif EVENP
15025870Ssam 	cpout.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
15125870Ssam 	cpout.cp_hdr.cp_comm = CPWRITE;
15225870Ssam 	cpout.cp_hdr.cp_count = 1;
15325870Ssam 	cpout.cp_buf[0] = c;
15425870Ssam 	mtpr(CPMDCB, &cpout);
15525870Ssam 	time = 100000;				/* Delay loop */
15625870Ssam 	while (time--) {
157*29979Skarels 		uncache(&cpout.cp_hdr.cp_unit);
158*29979Skarels 		if (cpout.cp_hdr.cp_unit & CPDONE)
159*29979Skarels 			break;
16025870Ssam 	}
161*29979Skarels 	if (c == '\n')
162*29979Skarels 		putchar ('\r');
16325870Ssam }
16425870Ssam 
16525870Ssam getchar()
16625870Ssam {
167*29979Skarels 	char c;
16825870Ssam 
16925870Ssam 	cpin.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
17025870Ssam 	cpin.cp_hdr.cp_comm = CPREAD;
17125870Ssam 	cpin.cp_hdr.cp_count = 1;
17225870Ssam 	mtpr(CPMDCB, &cpin);
17325870Ssam 	while ((cpin.cp_hdr.cp_unit & CPDONE) == 0)
174*29979Skarels 		uncache(&cpin.cp_hdr.cp_unit);
175*29979Skarels 	uncache(&cpin.cpi_buf[0]);
17625870Ssam 	c = cpin.cpi_buf[0] & 0x7f;
177*29979Skarels 	if (c == '\r')
178*29979Skarels 		c = '\n';
179*29979Skarels 	if (c != '\b' && c != '\177')
180*29979Skarels 		putchar(c);
181*29979Skarels 	return (c);
18225870Ssam }
18325870Ssam 
18425870Ssam gets(buf)
18525870Ssam 	char *buf;
18625870Ssam {
18725870Ssam 	register char *lp;
18825870Ssam 	register c;
18925870Ssam 
19025870Ssam 	lp = buf;
19125870Ssam 	for (;;) {
19225870Ssam 		c = getchar() & 0177;
19325870Ssam 		switch(c) {
19425870Ssam 		case '\n':
19525870Ssam 		case '\r':
19625870Ssam 			c = '\n';
19725870Ssam 			*lp++ = '\0';
19825870Ssam 			return;
19925870Ssam 		case '\b':
200*29979Skarels 		case '\177':
201*29979Skarels 			if (lp > buf) {
202*29979Skarels 				lp--;
203*29979Skarels 				putchar('\b');
204*29979Skarels 				putchar(' ');
205*29979Skarels 				putchar('\b');
206*29979Skarels 			}
207*29979Skarels 			continue;
20825870Ssam 		case '#':
209*29979Skarels 			if (--lp < buf)
21025870Ssam 				lp = buf;
21125870Ssam 			continue;
21225870Ssam 		case '@':
21325870Ssam 		case 'u'&037:
21425870Ssam 			lp = buf;
21525870Ssam 			putchar('\n');
21625870Ssam 			continue;
21725870Ssam 		default:
21825870Ssam 			*lp++ = c;
21925870Ssam 		}
22025870Ssam 	}
22125870Ssam }
222