Commit | Line | Data |
---|---|---|
55b4dbd0 KM |
1 | /* |
2 | * Copyright (c) 1982 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
9ccc8700 | 6 | * @(#)prf.c 6.4 (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) { | |
86 | putchar('<'); | |
87 | while (i = *s++) { | |
88 | if (b & (1 << (i-1))) { | |
89 | if (any) | |
90 | putchar(','); | |
91 | any = 1; | |
92 | for (; (c = *s) > 32; s++) | |
93 | putchar(c); | |
94 | } else | |
95 | for (; *s > 32; s++) | |
96 | ; | |
97 | } | |
98 | putchar('>'); | |
99 | } | |
100 | break; | |
101 | ||
102 | case 's': | |
103 | s = (char *)*adx; | |
104 | while (c = *s++) | |
4d05cd07 | 105 | putchar(c); |
99fe9747 | 106 | break; |
4d05cd07 BJ |
107 | } |
108 | adx++; | |
109 | goto loop; | |
110 | } | |
111 | ||
4d05cd07 | 112 | /* |
99fe9747 BJ |
113 | * Printn prints a number n in base b. |
114 | * We don't use recursion to avoid deep kernel stacks. | |
4d05cd07 BJ |
115 | */ |
116 | printn(n, b) | |
99fe9747 | 117 | u_long n; |
4d05cd07 | 118 | { |
99fe9747 BJ |
119 | char prbuf[11]; |
120 | register char *cp; | |
4d05cd07 | 121 | |
99fe9747 | 122 | if (b == 10 && (int)n < 0) { |
4d05cd07 | 123 | putchar('-'); |
99fe9747 | 124 | n = (unsigned)(-(int)n); |
4d05cd07 | 125 | } |
99fe9747 BJ |
126 | cp = prbuf; |
127 | do { | |
128 | *cp++ = "0123456789abcdef"[n%b]; | |
129 | n /= b; | |
130 | } while (n); | |
131 | do | |
132 | putchar(*--cp); | |
133 | while (cp > prbuf); | |
4d05cd07 BJ |
134 | } |
135 | ||
136 | /* | |
137 | * Print a character on console. | |
138 | * Attempts to save and restore device | |
139 | * status. | |
4d05cd07 BJ |
140 | * |
141 | * Whether or not printing is inhibited, | |
142 | * the last MSGBUFS characters | |
143 | * are saved in msgbuf for inspection later. | |
144 | */ | |
145 | putchar(c) | |
99fe9747 | 146 | register c; |
4d05cd07 BJ |
147 | { |
148 | register s, timo; | |
149 | ||
150 | timo = 30000; | |
151 | /* | |
152 | * Try waiting for the console tty to come ready, | |
153 | * otherwise give up after a reasonable time. | |
154 | */ | |
155 | while((mfpr(TXCS)&TXCS_RDY) == 0) | |
156 | if(--timo == 0) | |
157 | break; | |
158 | if(c == 0) | |
159 | return; | |
160 | s = mfpr(TXCS); | |
161 | mtpr(TXCS,0); | |
162 | mtpr(TXDB, c&0xff); | |
163 | if(c == '\n') | |
164 | putchar('\r'); | |
165 | putchar(0); | |
166 | mtpr(TXCS, s); | |
167 | } | |
168 | ||
169 | getchar() | |
170 | { | |
171 | register c; | |
172 | ||
173 | while((mfpr(RXCS)&RXCS_DONE) == 0) | |
174 | ; | |
175 | c = mfpr(RXDB)&0177; | |
176 | if (c=='\r') | |
177 | c = '\n'; | |
178 | putchar(c); | |
179 | return(c); | |
180 | } | |
181 | ||
182 | gets(buf) | |
99fe9747 | 183 | char *buf; |
4d05cd07 | 184 | { |
99fe9747 BJ |
185 | register char *lp; |
186 | register c; | |
4d05cd07 BJ |
187 | |
188 | lp = buf; | |
189 | for (;;) { | |
190 | c = getchar() & 0177; | |
4d05cd07 BJ |
191 | store: |
192 | switch(c) { | |
193 | case '\n': | |
194 | case '\r': | |
195 | c = '\n'; | |
196 | *lp++ = '\0'; | |
197 | return; | |
198 | case '\b': | |
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 | } |