Commit | Line | Data |
---|---|---|
55b4dbd0 | 1 | /* |
0880b18e | 2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
55b4dbd0 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
a14fe297 | 6 | * @(#)prf.c 7.2 (Berkeley) %G% |
55b4dbd0 | 7 | */ |
4d05cd07 | 8 | |
99fe9747 | 9 | #include "../h/param.h" |
a031a31b SL |
10 | |
11 | #include "../vax/mtpr.h" | |
12 | #include "../vax/cons.h" | |
4d05cd07 BJ |
13 | |
14 | /* | |
15 | * Scaled down version of C Library printf. | |
99fe9747 BJ |
16 | * Used to print diagnostic information directly on console tty. |
17 | * Since it is not interrupt driven, all system activities are | |
18 | * suspended. Printf should not be used for chit-chat. | |
19 | * | |
20 | * One additional format: %b is supported to decode error registers. | |
21 | * Usage is: | |
22 | * printf("reg=%b\n", regval, "<base><arg>*"); | |
23 | * Where <base> is the output base expressed as a control character, | |
24 | * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of | |
25 | * characters, the first of which gives the bit number to be inspected | |
26 | * (origin 1), and the next characters (up to a control character, i.e. | |
27 | * a character <= 32), give the name of the register. Thus | |
28 | * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); | |
29 | * would produce output: | |
30 | * reg=2<BITTWO,BITONE> | |
4d05cd07 BJ |
31 | */ |
32 | /*VARARGS1*/ | |
33 | printf(fmt, x1) | |
99fe9747 BJ |
34 | char *fmt; |
35 | unsigned x1; | |
4d05cd07 | 36 | { |
99fe9747 BJ |
37 | |
38 | prf(fmt, &x1); | |
39 | } | |
40 | ||
41 | prf(fmt, adx) | |
42 | register char *fmt; | |
43 | register u_int *adx; | |
44 | { | |
45 | register int b, c, i; | |
4d05cd07 | 46 | char *s; |
99fe9747 | 47 | int any; |
4d05cd07 | 48 | |
4d05cd07 | 49 | loop: |
99fe9747 | 50 | while ((c = *fmt++) != '%') { |
4d05cd07 BJ |
51 | if(c == '\0') |
52 | return; | |
53 | putchar(c); | |
54 | } | |
99fe9747 | 55 | again: |
4d05cd07 | 56 | c = *fmt++; |
99fe9747 BJ |
57 | /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ |
58 | switch (c) { | |
59 | ||
60 | case 'l': | |
61 | goto again; | |
62 | case 'x': case 'X': | |
63 | b = 16; | |
64 | goto number; | |
65 | case 'd': case 'D': | |
66 | case 'u': /* what a joke */ | |
67 | b = 10; | |
68 | goto number; | |
69 | case 'o': case 'O': | |
70 | b = 8; | |
71 | number: | |
72 | printn((u_long)*adx, b); | |
73 | break; | |
74 | case 'c': | |
75 | b = *adx; | |
76 | for (i = 24; i >= 0; i -= 8) | |
77 | if (c = (b >> i) & 0x7f) | |
78 | putchar(c); | |
79 | break; | |
80 | case 'b': | |
81 | b = *adx++; | |
4d05cd07 | 82 | s = (char *)*adx; |
99fe9747 BJ |
83 | printn((u_long)b, *s++); |
84 | any = 0; | |
85 | if (b) { | |
99fe9747 BJ |
86 | while (i = *s++) { |
87 | if (b & (1 << (i-1))) { | |
d3553ea4 | 88 | putchar(any? ',' : '<'); |
99fe9747 BJ |
89 | any = 1; |
90 | for (; (c = *s) > 32; s++) | |
91 | putchar(c); | |
92 | } else | |
93 | for (; *s > 32; s++) | |
94 | ; | |
95 | } | |
d3553ea4 MK |
96 | if (any) |
97 | putchar('>'); | |
99fe9747 BJ |
98 | } |
99 | break; | |
100 | ||
101 | case 's': | |
102 | s = (char *)*adx; | |
103 | while (c = *s++) | |
4d05cd07 | 104 | putchar(c); |
99fe9747 | 105 | break; |
4d05cd07 BJ |
106 | } |
107 | adx++; | |
108 | goto loop; | |
109 | } | |
110 | ||
4d05cd07 | 111 | /* |
99fe9747 BJ |
112 | * Printn prints a number n in base b. |
113 | * We don't use recursion to avoid deep kernel stacks. | |
4d05cd07 BJ |
114 | */ |
115 | printn(n, b) | |
99fe9747 | 116 | u_long n; |
4d05cd07 | 117 | { |
99fe9747 BJ |
118 | char prbuf[11]; |
119 | register char *cp; | |
4d05cd07 | 120 | |
99fe9747 | 121 | if (b == 10 && (int)n < 0) { |
4d05cd07 | 122 | putchar('-'); |
99fe9747 | 123 | n = (unsigned)(-(int)n); |
4d05cd07 | 124 | } |
99fe9747 BJ |
125 | cp = prbuf; |
126 | do { | |
127 | *cp++ = "0123456789abcdef"[n%b]; | |
128 | n /= b; | |
129 | } while (n); | |
130 | do | |
131 | putchar(*--cp); | |
132 | while (cp > prbuf); | |
4d05cd07 BJ |
133 | } |
134 | ||
135 | /* | |
136 | * Print a character on console. | |
4d05cd07 BJ |
137 | */ |
138 | putchar(c) | |
99fe9747 | 139 | register c; |
4d05cd07 BJ |
140 | { |
141 | register s, timo; | |
142 | ||
143 | timo = 30000; | |
144 | /* | |
145 | * Try waiting for the console tty to come ready, | |
146 | * otherwise give up after a reasonable time. | |
147 | */ | |
148 | while((mfpr(TXCS)&TXCS_RDY) == 0) | |
149 | if(--timo == 0) | |
150 | break; | |
151 | if(c == 0) | |
152 | return; | |
153 | s = mfpr(TXCS); | |
154 | mtpr(TXCS,0); | |
155 | mtpr(TXDB, c&0xff); | |
156 | if(c == '\n') | |
157 | putchar('\r'); | |
158 | putchar(0); | |
159 | mtpr(TXCS, s); | |
160 | } | |
161 | ||
162 | getchar() | |
163 | { | |
164 | register c; | |
165 | ||
166 | while((mfpr(RXCS)&RXCS_DONE) == 0) | |
167 | ; | |
168 | c = mfpr(RXDB)&0177; | |
169 | if (c=='\r') | |
170 | c = '\n'; | |
a14fe297 MK |
171 | if (c != '\b' && c != '\177') |
172 | putchar(c); | |
4d05cd07 BJ |
173 | return(c); |
174 | } | |
175 | ||
176 | gets(buf) | |
99fe9747 | 177 | char *buf; |
4d05cd07 | 178 | { |
99fe9747 BJ |
179 | register char *lp; |
180 | register c; | |
4d05cd07 BJ |
181 | |
182 | lp = buf; | |
183 | for (;;) { | |
184 | c = getchar() & 0177; | |
4d05cd07 BJ |
185 | switch(c) { |
186 | case '\n': | |
187 | case '\r': | |
188 | c = '\n'; | |
189 | *lp++ = '\0'; | |
190 | return; | |
191 | case '\b': | |
d3553ea4 MK |
192 | if (lp > buf) { |
193 | lp--; | |
a14fe297 | 194 | putchar('\b'); |
d3553ea4 MK |
195 | putchar(' '); |
196 | putchar('\b'); | |
197 | } | |
198 | continue; | |
4d05cd07 | 199 | case '#': |
3c80ca93 | 200 | case '\177': |
4d05cd07 BJ |
201 | lp--; |
202 | if (lp < buf) | |
203 | lp = buf; | |
204 | continue; | |
205 | case '@': | |
66ad0583 | 206 | case 'u'&037: |
4d05cd07 BJ |
207 | lp = buf; |
208 | putchar('\n'); | |
209 | continue; | |
210 | default: | |
211 | *lp++ = c; | |
212 | } | |
213 | } | |
214 | } |