1 /* prf.c 1.2 86/11/04 */ 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 * Printn prints a number n in base b. 108 * We don't use recursion to avoid deep kernel stacks. 109 */ 110 printn(n, b) 111 u_long n; 112 { 113 char prbuf[11]; 114 register char *cp; 115 116 if (b == 10 && (int)n < 0) { 117 putchar('-'); 118 n = (unsigned)(-(int)n); 119 } 120 cp = prbuf; 121 do { 122 *cp++ = "0123456789abcdef"[n%b]; 123 n /= b; 124 } while (n); 125 do 126 putchar(*--cp); 127 while (cp > prbuf); 128 } 129 130 /* 131 * Print a character on console. 132 */ 133 struct cpdcb_o cpout; 134 struct cpdcb_i cpin; 135 136 /* console requires even parity */ 137 #define EVENP 138 139 putchar(c) 140 char c; 141 { 142 int time; 143 #ifdef EVENP 144 register mask, par; 145 146 for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1) 147 par ^= c&mask; 148 c |= par; 149 #endif EVENP 150 cpout.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 151 cpout.cp_hdr.cp_comm = CPWRITE; 152 cpout.cp_hdr.cp_count = 1; 153 cpout.cp_buf[0] = c; 154 mtpr(CPMDCB, &cpout); 155 time = 100000; /* Delay loop */ 156 while (time--) { 157 uncache(&cpout.cp_hdr.cp_unit); 158 if (cpout.cp_hdr.cp_unit & CPDONE) 159 break; 160 } 161 if (c == '\n') 162 putchar ('\r'); 163 } 164 165 getchar() 166 { 167 char c; 168 169 cpin.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 170 cpin.cp_hdr.cp_comm = CPREAD; 171 cpin.cp_hdr.cp_count = 1; 172 mtpr(CPMDCB, &cpin); 173 while ((cpin.cp_hdr.cp_unit & CPDONE) == 0) 174 uncache(&cpin.cp_hdr.cp_unit); 175 uncache(&cpin.cpi_buf[0]); 176 c = cpin.cpi_buf[0] & 0x7f; 177 if (c == '\r') 178 c = '\n'; 179 if (c != '\b' && c != '\177') 180 putchar(c); 181 return (c); 182 } 183 184 gets(buf) 185 char *buf; 186 { 187 register char *lp; 188 register c; 189 190 lp = buf; 191 for (;;) { 192 c = getchar() & 0177; 193 switch(c) { 194 case '\n': 195 case '\r': 196 c = '\n'; 197 *lp++ = '\0'; 198 return; 199 case '\b': 200 case '\177': 201 if (lp > buf) { 202 lp--; 203 putchar('\b'); 204 putchar(' '); 205 putchar('\b'); 206 } 207 continue; 208 case '#': 209 if (--lp < buf) 210 lp = buf; 211 continue; 212 case '@': 213 case 'u'&037: 214 lp = buf; 215 putchar('\n'); 216 continue; 217 default: 218 *lp++ = c; 219 } 220 } 221 } 222