1 /* prf.c 4.4 82/11/13 */ 2 3 #include "../h/param.h" 4 5 #include "../vax/mtpr.h" 6 #include "../vax/cons.h" 7 8 /* 9 * Scaled down version of C Library printf. 10 * Used to print diagnostic information directly on console tty. 11 * Since it is not interrupt driven, all system activities are 12 * suspended. Printf should not be used for chit-chat. 13 * 14 * One additional format: %b is supported to decode error registers. 15 * Usage is: 16 * printf("reg=%b\n", regval, "<base><arg>*"); 17 * Where <base> is the output base expressed as a control character, 18 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 19 * characters, the first of which gives the bit number to be inspected 20 * (origin 1), and the next characters (up to a control character, i.e. 21 * a character <= 32), give the name of the register. Thus 22 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 23 * would produce output: 24 * reg=2<BITTWO,BITONE> 25 */ 26 /*VARARGS1*/ 27 printf(fmt, x1) 28 char *fmt; 29 unsigned x1; 30 { 31 32 prf(fmt, &x1); 33 } 34 35 prf(fmt, adx) 36 register char *fmt; 37 register u_int *adx; 38 { 39 register int b, c, i; 40 char *s; 41 int any; 42 43 loop: 44 while ((c = *fmt++) != '%') { 45 if(c == '\0') 46 return; 47 putchar(c); 48 } 49 again: 50 c = *fmt++; 51 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 52 switch (c) { 53 54 case 'l': 55 goto again; 56 case 'x': case 'X': 57 b = 16; 58 goto number; 59 case 'd': case 'D': 60 case 'u': /* what a joke */ 61 b = 10; 62 goto number; 63 case 'o': case 'O': 64 b = 8; 65 number: 66 printn((u_long)*adx, b); 67 break; 68 case 'c': 69 b = *adx; 70 for (i = 24; i >= 0; i -= 8) 71 if (c = (b >> i) & 0x7f) 72 putchar(c); 73 break; 74 case 'b': 75 b = *adx++; 76 s = (char *)*adx; 77 printn((u_long)b, *s++); 78 any = 0; 79 if (b) { 80 putchar('<'); 81 while (i = *s++) { 82 if (b & (1 << (i-1))) { 83 if (any) 84 putchar(','); 85 any = 1; 86 for (; (c = *s) > 32; s++) 87 putchar(c); 88 } else 89 for (; *s > 32; s++) 90 ; 91 } 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 * Attempts to save and restore device 133 * status. 134 * 135 * Whether or not printing is inhibited, 136 * the last MSGBUFS characters 137 * are saved in msgbuf for inspection later. 138 */ 139 putchar(c) 140 register c; 141 { 142 register s, timo; 143 144 timo = 30000; 145 /* 146 * Try waiting for the console tty to come ready, 147 * otherwise give up after a reasonable time. 148 */ 149 while((mfpr(TXCS)&TXCS_RDY) == 0) 150 if(--timo == 0) 151 break; 152 if(c == 0) 153 return; 154 s = mfpr(TXCS); 155 mtpr(TXCS,0); 156 mtpr(TXDB, c&0xff); 157 if(c == '\n') 158 putchar('\r'); 159 putchar(0); 160 mtpr(TXCS, s); 161 } 162 163 getchar() 164 { 165 register c; 166 167 while((mfpr(RXCS)&RXCS_DONE) == 0) 168 ; 169 c = mfpr(RXDB)&0177; 170 if (c=='\r') 171 c = '\n'; 172 putchar(c); 173 return(c); 174 } 175 176 gets(buf) 177 char *buf; 178 { 179 register char *lp; 180 register c; 181 182 lp = buf; 183 for (;;) { 184 c = getchar() & 0177; 185 store: 186 switch(c) { 187 case '\n': 188 case '\r': 189 c = '\n'; 190 *lp++ = '\0'; 191 return; 192 case '\b': 193 case '#': 194 lp--; 195 if (lp < buf) 196 lp = buf; 197 continue; 198 case '@': 199 case 'u'&037: 200 lp = buf; 201 putchar('\n'); 202 continue; 203 default: 204 *lp++ = c; 205 } 206 } 207 } 208