1*41488Smckusick /* 2*41488Smckusick * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 3*41488Smckusick * All rights reserved. 4*41488Smckusick * 5*41488Smckusick * %sccs.include.redist.c% 6*41488Smckusick * 7*41488Smckusick * @(#)prf.c 7.1 (Berkeley) 05/08/90 8*41488Smckusick */ 9*41488Smckusick 10*41488Smckusick #include "../h/param.h" 11*41488Smckusick 12*41488Smckusick /* 13*41488Smckusick * Scaled down version of C Library printf. 14*41488Smckusick * Used to print diagnostic information directly on console tty. 15*41488Smckusick * Since it is not interrupt driven, all system activities are 16*41488Smckusick * suspended. Printf should not be used for chit-chat. 17*41488Smckusick * 18*41488Smckusick * One additional format: %b is supported to decode error registers. 19*41488Smckusick * Usage is: 20*41488Smckusick * printf("reg=%b\n", regval, "<base><arg>*"); 21*41488Smckusick * Where <base> is the output base expressed as a control character, 22*41488Smckusick * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 23*41488Smckusick * characters, the first of which gives the bit number to be inspected 24*41488Smckusick * (origin 1), and the next characters (up to a control character, i.e. 25*41488Smckusick * a character <= 32), give the name of the register. Thus 26*41488Smckusick * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 27*41488Smckusick * would produce output: 28*41488Smckusick * reg=2<BITTWO,BITONE> 29*41488Smckusick */ 30*41488Smckusick /*VARARGS1*/ 31*41488Smckusick printf(fmt, x1) 32*41488Smckusick char *fmt; 33*41488Smckusick unsigned x1; 34*41488Smckusick { 35*41488Smckusick 36*41488Smckusick prf(0, fmt, &x1); 37*41488Smckusick } 38*41488Smckusick 39*41488Smckusick /*VARARGS1*/ 40*41488Smckusick romprintf(fmt, x1) 41*41488Smckusick char *fmt; 42*41488Smckusick unsigned x1; 43*41488Smckusick { 44*41488Smckusick 45*41488Smckusick prf(1, fmt, &x1); 46*41488Smckusick } 47*41488Smckusick 48*41488Smckusick prf(userom, fmt, adx) 49*41488Smckusick register char *fmt; 50*41488Smckusick register u_int *adx; 51*41488Smckusick { 52*41488Smckusick register int b, c, i; 53*41488Smckusick char *s; 54*41488Smckusick int any; 55*41488Smckusick 56*41488Smckusick loop: 57*41488Smckusick while ((c = *fmt++) != '%') { 58*41488Smckusick if(c == '\0') 59*41488Smckusick return; 60*41488Smckusick putchar(userom, c); 61*41488Smckusick } 62*41488Smckusick again: 63*41488Smckusick c = *fmt++; 64*41488Smckusick /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 65*41488Smckusick switch (c) { 66*41488Smckusick 67*41488Smckusick case 'l': 68*41488Smckusick goto again; 69*41488Smckusick case 'x': case 'X': 70*41488Smckusick b = 16; 71*41488Smckusick goto number; 72*41488Smckusick case 'd': case 'D': 73*41488Smckusick case 'u': /* what a joke */ 74*41488Smckusick b = 10; 75*41488Smckusick goto number; 76*41488Smckusick case 'o': case 'O': 77*41488Smckusick b = 8; 78*41488Smckusick number: 79*41488Smckusick printn(userom, (u_long)*adx, b); 80*41488Smckusick break; 81*41488Smckusick case 'c': 82*41488Smckusick b = *adx; 83*41488Smckusick for (i = 24; i >= 0; i -= 8) 84*41488Smckusick if (c = (b >> i) & 0x7f) 85*41488Smckusick putchar(userom, c); 86*41488Smckusick break; 87*41488Smckusick case 'b': 88*41488Smckusick b = *adx++; 89*41488Smckusick s = (char *)*adx; 90*41488Smckusick printn(userom, (u_long)b, *s++); 91*41488Smckusick any = 0; 92*41488Smckusick if (b) { 93*41488Smckusick while (i = *s++) { 94*41488Smckusick if (b & (1 << (i-1))) { 95*41488Smckusick putchar(userom, any? ',' : '<'); 96*41488Smckusick any = 1; 97*41488Smckusick for (; (c = *s) > 32; s++) 98*41488Smckusick putchar(userom, c); 99*41488Smckusick } else 100*41488Smckusick for (; *s > 32; s++) 101*41488Smckusick ; 102*41488Smckusick } 103*41488Smckusick if (any) 104*41488Smckusick putchar(userom, '>'); 105*41488Smckusick } 106*41488Smckusick break; 107*41488Smckusick 108*41488Smckusick case 's': 109*41488Smckusick s = (char *)*adx; 110*41488Smckusick while (c = *s++) 111*41488Smckusick putchar(userom, c); 112*41488Smckusick break; 113*41488Smckusick } 114*41488Smckusick adx++; 115*41488Smckusick goto loop; 116*41488Smckusick } 117*41488Smckusick 118*41488Smckusick /* 119*41488Smckusick * Printn prints a number n in base b. 120*41488Smckusick * We don't use recursion to avoid deep kernel stacks. 121*41488Smckusick */ 122*41488Smckusick printn(userom, n, b) 123*41488Smckusick u_long n; 124*41488Smckusick { 125*41488Smckusick char prbuf[11]; 126*41488Smckusick register char *cp; 127*41488Smckusick 128*41488Smckusick if (b == 10 && (int)n < 0) { 129*41488Smckusick putchar(userom, '-'); 130*41488Smckusick n = (unsigned)(-(int)n); 131*41488Smckusick } 132*41488Smckusick cp = prbuf; 133*41488Smckusick do { 134*41488Smckusick *cp++ = "0123456789abcdef"[n%b]; 135*41488Smckusick n /= b; 136*41488Smckusick } while (n); 137*41488Smckusick do 138*41488Smckusick putchar(userom, *--cp); 139*41488Smckusick while (cp > prbuf); 140*41488Smckusick } 141*41488Smckusick 142*41488Smckusick /* 143*41488Smckusick * Print a character on console. 144*41488Smckusick */ 145*41488Smckusick putchar(userom, c) 146*41488Smckusick register c; 147*41488Smckusick { 148*41488Smckusick #ifdef ROMPRF 149*41488Smckusick if (userom) { 150*41488Smckusick romputchar(c); 151*41488Smckusick return; 152*41488Smckusick } 153*41488Smckusick #endif 154*41488Smckusick cnputc(c); 155*41488Smckusick if(c == '\n') 156*41488Smckusick cnputc('\r'); 157*41488Smckusick } 158*41488Smckusick 159*41488Smckusick peekchar() 160*41488Smckusick { 161*41488Smckusick register c; 162*41488Smckusick 163*41488Smckusick c = cngetc(); 164*41488Smckusick if (c == ('c'&037)) { 165*41488Smckusick printf("^C"); 166*41488Smckusick _stop(""); 167*41488Smckusick /* NOTREACHED */ 168*41488Smckusick } 169*41488Smckusick return(c); 170*41488Smckusick } 171*41488Smckusick 172*41488Smckusick getchar() 173*41488Smckusick { 174*41488Smckusick register c; 175*41488Smckusick 176*41488Smckusick while((c = cngetc()) == 0) 177*41488Smckusick ; 178*41488Smckusick if (c == '\r') 179*41488Smckusick c = '\n'; 180*41488Smckusick else if (c == ('c'&037)) { 181*41488Smckusick printf("^C"); 182*41488Smckusick _stop(""); 183*41488Smckusick /* NOTREACHED */ 184*41488Smckusick } 185*41488Smckusick putchar(0, c); 186*41488Smckusick return(c); 187*41488Smckusick } 188*41488Smckusick 189*41488Smckusick gets(buf) 190*41488Smckusick char *buf; 191*41488Smckusick { 192*41488Smckusick register char *lp; 193*41488Smckusick register c; 194*41488Smckusick 195*41488Smckusick lp = buf; 196*41488Smckusick for (;;) { 197*41488Smckusick c = getchar() & 0177; 198*41488Smckusick switch(c) { 199*41488Smckusick case '\n': 200*41488Smckusick case '\r': 201*41488Smckusick c = '\n'; 202*41488Smckusick *lp++ = '\0'; 203*41488Smckusick return; 204*41488Smckusick case '\b': 205*41488Smckusick if (lp > buf) { 206*41488Smckusick lp--; 207*41488Smckusick putchar(0, ' '); 208*41488Smckusick putchar(0, '\b'); 209*41488Smckusick } 210*41488Smckusick continue; 211*41488Smckusick case '#': 212*41488Smckusick case '\177': 213*41488Smckusick lp--; 214*41488Smckusick if (lp < buf) 215*41488Smckusick lp = buf; 216*41488Smckusick continue; 217*41488Smckusick case '@': 218*41488Smckusick case 'u'&037: 219*41488Smckusick lp = buf; 220*41488Smckusick putchar(0, '\n'); 221*41488Smckusick continue; 222*41488Smckusick default: 223*41488Smckusick *lp++ = c; 224*41488Smckusick } 225*41488Smckusick } 226*41488Smckusick } 227*41488Smckusick 228