put boot in /, not /stand
[unix-history] / usr / src / sys / tahoe / stand / prf.c
CommitLineData
ec3296ac 1/* prf.c 1.6 90/06/22 */
1e1f58c3
SL
2/* prf.c 4.3 81/05/05 */
3
c18e27ed 4#include "machine/mtpr.h"
1e1f58c3 5
ec3296ac
BJ
6#include "sys/param.h"
7#include "tahoe/cp.h"
1e1f58c3
SL
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*/
28printf(fmt, x1)
29 char *fmt;
30 unsigned x1;
31{
32
33 prf(fmt, &x1);
34}
35
36prf(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
44loop:
45 while ((c = *fmt++) != '%') {
54e5fb0b 46 if (c == '\0')
1e1f58c3
SL
47 return;
48 putchar(c);
49 }
50again:
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;
66number:
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) {
1e1f58c3
SL
81 while (i = *s++) {
82 if (b & (1 << (i-1))) {
54e5fb0b 83 putchar(any? ',' : '<');
1e1f58c3
SL
84 any = 1;
85 for (; (c = *s) > 32; s++)
86 putchar(c);
87 } else
88 for (; *s > 32; s++)
89 ;
90 }
54e5fb0b
MK
91 if (any)
92 putchar('>');
1e1f58c3
SL
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
1e1f58c3
SL
106/*
107 * Print a character on console.
1e1f58c3 108 */
1e1f58c3
SL
109struct cpdcb_o cpout;
110struct cpdcb_i cpin;
111
112/* console requires even parity */
113#define EVENP
54e5fb0b 114
1e1f58c3 115putchar(c)
54e5fb0b 116 char c;
1e1f58c3
SL
117{
118 int time;
119#ifdef EVENP
120 register mask, par;
121
54e5fb0b 122 for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1)
1e1f58c3
SL
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);
1e1f58c3
SL
131 time = 100000; /* Delay loop */
132 while (time--) {
54e5fb0b
MK
133 uncache(&cpout.cp_hdr.cp_unit);
134 if (cpout.cp_hdr.cp_unit & CPDONE)
135 break;
1e1f58c3 136 }
54e5fb0b
MK
137 if (c == '\n')
138 putchar ('\r');
1e1f58c3 139}
1e1f58c3
SL
140
141getchar()
142{
54e5fb0b 143 char c;
1e1f58c3
SL
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);
1e1f58c3 149 while ((cpin.cp_hdr.cp_unit & CPDONE) == 0)
54e5fb0b
MK
150 uncache(&cpin.cp_hdr.cp_unit);
151 uncache(&cpin.cpi_buf[0]);
1e1f58c3 152 c = cpin.cpi_buf[0] & 0x7f;
54e5fb0b
MK
153 if (c == '\r')
154 c = '\n';
155 if (c != '\b' && c != '\177')
156 putchar(c);
157 return (c);
1e1f58c3 158}
0aa02f62
KB
159
160trap(ps)
161 int ps;
162{
163 printf("Trap %o\n", ps);
164 for (;;)
165 ;
166}
167
168uncache (addr)
169 char *addr;
170{
171 /* Return *(addr-0x4000); DIRTY assumes this address is valid */
172 mtpr(PDCS, addr);
173}