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