xref: /original-bsd/sys/tahoe/stand/prf.c (revision 6a6b77ee)
1 /*	prf.c	1.7	90/12/16	*/
2 /*	prf.c	4.3	81/05/05	*/
3 
4 #include "../include/mtpr.h"
5 
6 #include "sys/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  * Print a character on console.
108  */
109 struct	cpdcb_o cpout;
110 struct	cpdcb_i cpin;
111 
112 /* console requires even parity */
113 #define EVENP
114 
115 putchar(c)
116 	char c;
117 {
118 	int time;
119 #ifdef EVENP
120 	register mask, par;
121 
122 	for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1)
123 		par ^= c&mask;
124 	c |= par;
125 #endif EVENP
126 	cpout.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
127 	cpout.cp_hdr.cp_comm = CPWRITE;
128 	cpout.cp_hdr.cp_count = 1;
129 	cpout.cp_buf[0] = c;
130 	mtpr(CPMDCB, &cpout);
131 	time = 100000;				/* Delay loop */
132 	while (time--) {
133 		uncache(&cpout.cp_hdr.cp_unit);
134 		if (cpout.cp_hdr.cp_unit & CPDONE)
135 			break;
136 	}
137 	if (c == '\n')
138 		putchar ('\r');
139 }
140 
141 getchar()
142 {
143 	char c;
144 
145 	cpin.cp_hdr.cp_unit = CPCONS;	/* Resets done bit */
146 	cpin.cp_hdr.cp_comm = CPREAD;
147 	cpin.cp_hdr.cp_count = 1;
148 	mtpr(CPMDCB, &cpin);
149 	while ((cpin.cp_hdr.cp_unit & CPDONE) == 0)
150 		uncache(&cpin.cp_hdr.cp_unit);
151 	uncache(&cpin.cpi_buf[0]);
152 	c = cpin.cpi_buf[0] & 0x7f;
153 	if (c == '\r')
154 		c = '\n';
155 	if (c != '\b' && c != '\177')
156 		putchar(c);
157 	return (c);
158 }
159 
160 trap(ps)
161 	int ps;
162 {
163 	printf("Trap %o\n", ps);
164 	for (;;)
165 		;
166 }
167 
168 uncache (addr)
169 	char *addr;
170 {
171 	/* Return *(addr-0x4000); DIRTY assumes this address is valid */
172 	mtpr(PDCS, addr);
173 }
174