1*29979Skarels /* prf.c 1.2 86/11/04 */ 225870Ssam /* prf.c 4.3 81/05/05 */ 325870Ssam 425870Ssam #include "../machine/mtpr.h" 525870Ssam 625870Ssam #include "param.h" 725870Ssam #include "../tahoe/cp.h" 825870Ssam 925870Ssam /* 1025870Ssam * Scaled down version of C Library printf. 1125870Ssam * Used to print diagnostic information directly on console tty. 1225870Ssam * Since it is not interrupt driven, all system activities are 1325870Ssam * suspended. Printf should not be used for chit-chat. 1425870Ssam * 1525870Ssam * One additional format: %b is supported to decode error registers. 1625870Ssam * Usage is: 1725870Ssam * printf("reg=%b\n", regval, "<base><arg>*"); 1825870Ssam * Where <base> is the output base expressed as a control character, 1925870Ssam * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 2025870Ssam * characters, the first of which gives the bit number to be inspected 2125870Ssam * (origin 1), and the next characters (up to a control character, i.e. 2225870Ssam * a character <= 32), give the name of the register. Thus 2325870Ssam * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 2425870Ssam * would produce output: 2525870Ssam * reg=2<BITTWO,BITONE> 2625870Ssam */ 2725870Ssam /*VARARGS1*/ 2825870Ssam printf(fmt, x1) 2925870Ssam char *fmt; 3025870Ssam unsigned x1; 3125870Ssam { 3225870Ssam 3325870Ssam prf(fmt, &x1); 3425870Ssam } 3525870Ssam 3625870Ssam prf(fmt, adx) 3725870Ssam register char *fmt; 3825870Ssam register u_int *adx; 3925870Ssam { 4025870Ssam register int b, c, i; 4125870Ssam char *s; 4225870Ssam int any; 4325870Ssam 4425870Ssam loop: 4525870Ssam while ((c = *fmt++) != '%') { 46*29979Skarels if (c == '\0') 4725870Ssam return; 4825870Ssam putchar(c); 4925870Ssam } 5025870Ssam again: 5125870Ssam c = *fmt++; 5225870Ssam /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 5325870Ssam switch (c) { 5425870Ssam 5525870Ssam case 'l': 5625870Ssam goto again; 5725870Ssam case 'x': case 'X': 5825870Ssam b = 16; 5925870Ssam goto number; 6025870Ssam case 'd': case 'D': 6125870Ssam case 'u': /* what a joke */ 6225870Ssam b = 10; 6325870Ssam goto number; 6425870Ssam case 'o': case 'O': 6525870Ssam b = 8; 6625870Ssam number: 6725870Ssam printn((u_long)*adx, b); 6825870Ssam break; 6925870Ssam case 'c': 7025870Ssam b = *adx; 7125870Ssam for (i = 24; i >= 0; i -= 8) 7225870Ssam if (c = (b >> i) & 0x7f) 7325870Ssam putchar(c); 7425870Ssam break; 7525870Ssam case 'b': 7625870Ssam b = *adx++; 7725870Ssam s = (char *)*adx; 7825870Ssam printn((u_long)b, *s++); 7925870Ssam any = 0; 8025870Ssam if (b) { 8125870Ssam while (i = *s++) { 8225870Ssam if (b & (1 << (i-1))) { 83*29979Skarels putchar(any? ',' : '<'); 8425870Ssam any = 1; 8525870Ssam for (; (c = *s) > 32; s++) 8625870Ssam putchar(c); 8725870Ssam } else 8825870Ssam for (; *s > 32; s++) 8925870Ssam ; 9025870Ssam } 91*29979Skarels if (any) 92*29979Skarels putchar('>'); 9325870Ssam } 9425870Ssam break; 9525870Ssam 9625870Ssam case 's': 9725870Ssam s = (char *)*adx; 9825870Ssam while (c = *s++) 9925870Ssam putchar(c); 10025870Ssam break; 10125870Ssam } 10225870Ssam adx++; 10325870Ssam goto loop; 10425870Ssam } 10525870Ssam 10625870Ssam /* 10725870Ssam * Printn prints a number n in base b. 10825870Ssam * We don't use recursion to avoid deep kernel stacks. 10925870Ssam */ 11025870Ssam printn(n, b) 11125870Ssam u_long n; 11225870Ssam { 11325870Ssam char prbuf[11]; 11425870Ssam register char *cp; 11525870Ssam 11625870Ssam if (b == 10 && (int)n < 0) { 11725870Ssam putchar('-'); 11825870Ssam n = (unsigned)(-(int)n); 11925870Ssam } 12025870Ssam cp = prbuf; 12125870Ssam do { 12225870Ssam *cp++ = "0123456789abcdef"[n%b]; 12325870Ssam n /= b; 12425870Ssam } while (n); 12525870Ssam do 12625870Ssam putchar(*--cp); 12725870Ssam while (cp > prbuf); 12825870Ssam } 12925870Ssam 13025870Ssam /* 13125870Ssam * Print a character on console. 13225870Ssam */ 13325870Ssam struct cpdcb_o cpout; 13425870Ssam struct cpdcb_i cpin; 13525870Ssam 13625870Ssam /* console requires even parity */ 13725870Ssam #define EVENP 138*29979Skarels 13925870Ssam putchar(c) 140*29979Skarels char c; 14125870Ssam { 14225870Ssam int time; 14325870Ssam #ifdef EVENP 14425870Ssam register mask, par; 14525870Ssam 146*29979Skarels for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1) 14725870Ssam par ^= c&mask; 14825870Ssam c |= par; 14925870Ssam #endif EVENP 15025870Ssam cpout.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 15125870Ssam cpout.cp_hdr.cp_comm = CPWRITE; 15225870Ssam cpout.cp_hdr.cp_count = 1; 15325870Ssam cpout.cp_buf[0] = c; 15425870Ssam mtpr(CPMDCB, &cpout); 15525870Ssam time = 100000; /* Delay loop */ 15625870Ssam while (time--) { 157*29979Skarels uncache(&cpout.cp_hdr.cp_unit); 158*29979Skarels if (cpout.cp_hdr.cp_unit & CPDONE) 159*29979Skarels break; 16025870Ssam } 161*29979Skarels if (c == '\n') 162*29979Skarels putchar ('\r'); 16325870Ssam } 16425870Ssam 16525870Ssam getchar() 16625870Ssam { 167*29979Skarels char c; 16825870Ssam 16925870Ssam cpin.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 17025870Ssam cpin.cp_hdr.cp_comm = CPREAD; 17125870Ssam cpin.cp_hdr.cp_count = 1; 17225870Ssam mtpr(CPMDCB, &cpin); 17325870Ssam while ((cpin.cp_hdr.cp_unit & CPDONE) == 0) 174*29979Skarels uncache(&cpin.cp_hdr.cp_unit); 175*29979Skarels uncache(&cpin.cpi_buf[0]); 17625870Ssam c = cpin.cpi_buf[0] & 0x7f; 177*29979Skarels if (c == '\r') 178*29979Skarels c = '\n'; 179*29979Skarels if (c != '\b' && c != '\177') 180*29979Skarels putchar(c); 181*29979Skarels return (c); 18225870Ssam } 18325870Ssam 18425870Ssam gets(buf) 18525870Ssam char *buf; 18625870Ssam { 18725870Ssam register char *lp; 18825870Ssam register c; 18925870Ssam 19025870Ssam lp = buf; 19125870Ssam for (;;) { 19225870Ssam c = getchar() & 0177; 19325870Ssam switch(c) { 19425870Ssam case '\n': 19525870Ssam case '\r': 19625870Ssam c = '\n'; 19725870Ssam *lp++ = '\0'; 19825870Ssam return; 19925870Ssam case '\b': 200*29979Skarels case '\177': 201*29979Skarels if (lp > buf) { 202*29979Skarels lp--; 203*29979Skarels putchar('\b'); 204*29979Skarels putchar(' '); 205*29979Skarels putchar('\b'); 206*29979Skarels } 207*29979Skarels continue; 20825870Ssam case '#': 209*29979Skarels if (--lp < buf) 21025870Ssam lp = buf; 21125870Ssam continue; 21225870Ssam case '@': 21325870Ssam case 'u'&037: 21425870Ssam lp = buf; 21525870Ssam putchar('\n'); 21625870Ssam continue; 21725870Ssam default: 21825870Ssam *lp++ = c; 21925870Ssam } 22025870Ssam } 22125870Ssam } 222