|
|
1.1 root 1: /* prf.c 1.4 88/03/03 */
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: * 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.