1*3262Swnj /* prf.c 4.2 81/03/15 */ 2324Sbill 3*3262Swnj #include "../h/param.h" 4324Sbill #include "../h/cons.h" 5324Sbill #include "../h/mtpr.h" 6324Sbill 7324Sbill /* 8324Sbill * Scaled down version of C Library printf. 9*3262Swnj * Used to print diagnostic information directly on console tty. 10*3262Swnj * Since it is not interrupt driven, all system activities are 11*3262Swnj * suspended. Printf should not be used for chit-chat. 12*3262Swnj * 13*3262Swnj * One additional format: %b is supported to decode error registers. 14*3262Swnj * Usage is: 15*3262Swnj * printf("reg=%b\n", regval, "<base><arg>*"); 16*3262Swnj * Where <base> is the output base expressed as a control character, 17*3262Swnj * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 18*3262Swnj * characters, the first of which gives the bit number to be inspected 19*3262Swnj * (origin 1), and the next characters (up to a control character, i.e. 20*3262Swnj * a character <= 32), give the name of the register. Thus 21*3262Swnj * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 22*3262Swnj * would produce output: 23*3262Swnj * reg=2<BITTWO,BITONE> 24324Sbill */ 25324Sbill /*VARARGS1*/ 26324Sbill printf(fmt, x1) 27*3262Swnj char *fmt; 28*3262Swnj unsigned x1; 29324Sbill { 30*3262Swnj 31*3262Swnj prf(fmt, &x1); 32*3262Swnj } 33*3262Swnj 34*3262Swnj prf(fmt, adx) 35*3262Swnj register char *fmt; 36*3262Swnj register u_int *adx; 37*3262Swnj { 38*3262Swnj register int b, c, i; 39324Sbill char *s; 40*3262Swnj int any; 41324Sbill 42324Sbill loop: 43*3262Swnj while ((c = *fmt++) != '%') { 44324Sbill if(c == '\0') 45324Sbill return; 46324Sbill putchar(c); 47324Sbill } 48*3262Swnj again: 49324Sbill c = *fmt++; 50*3262Swnj /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 51*3262Swnj switch (c) { 52*3262Swnj 53*3262Swnj case 'l': 54*3262Swnj goto again; 55*3262Swnj case 'x': case 'X': 56*3262Swnj b = 16; 57*3262Swnj goto number; 58*3262Swnj case 'd': case 'D': 59*3262Swnj case 'u': /* what a joke */ 60*3262Swnj b = 10; 61*3262Swnj goto number; 62*3262Swnj case 'o': case 'O': 63*3262Swnj b = 8; 64*3262Swnj number: 65*3262Swnj printn((u_long)*adx, b); 66*3262Swnj break; 67*3262Swnj case 'c': 68*3262Swnj b = *adx; 69*3262Swnj for (i = 24; i >= 0; i -= 8) 70*3262Swnj if (c = (b >> i) & 0x7f) 71*3262Swnj putchar(c); 72*3262Swnj break; 73*3262Swnj case 'b': 74*3262Swnj b = *adx++; 75324Sbill s = (char *)*adx; 76*3262Swnj printn((u_long)b, *s++); 77*3262Swnj any = 0; 78*3262Swnj if (b) { 79*3262Swnj putchar('<'); 80*3262Swnj while (i = *s++) { 81*3262Swnj if (b & (1 << (i-1))) { 82*3262Swnj if (any) 83*3262Swnj putchar(','); 84*3262Swnj any = 1; 85*3262Swnj for (; (c = *s) > 32; s++) 86*3262Swnj putchar(c); 87*3262Swnj } else 88*3262Swnj for (; *s > 32; s++) 89*3262Swnj ; 90*3262Swnj } 91*3262Swnj putchar('>'); 92*3262Swnj } 93*3262Swnj break; 94*3262Swnj 95*3262Swnj case 's': 96*3262Swnj s = (char *)*adx; 97*3262Swnj while (c = *s++) 98324Sbill putchar(c); 99*3262Swnj break; 100324Sbill } 101324Sbill adx++; 102324Sbill goto loop; 103324Sbill } 104324Sbill 105324Sbill /* 106*3262Swnj * Printn prints a number n in base b. 107*3262Swnj * We don't use recursion to avoid deep kernel stacks. 108324Sbill */ 109324Sbill printn(n, b) 110*3262Swnj u_long n; 111324Sbill { 112*3262Swnj char prbuf[11]; 113*3262Swnj register char *cp; 114324Sbill 115*3262Swnj if (b == 10 && (int)n < 0) { 116324Sbill putchar('-'); 117*3262Swnj n = (unsigned)(-(int)n); 118324Sbill } 119*3262Swnj cp = prbuf; 120*3262Swnj do { 121*3262Swnj *cp++ = "0123456789abcdef"[n%b]; 122*3262Swnj n /= b; 123*3262Swnj } while (n); 124*3262Swnj do 125*3262Swnj putchar(*--cp); 126*3262Swnj while (cp > prbuf); 127324Sbill } 128324Sbill 129324Sbill /* 130324Sbill * Print a character on console. 131324Sbill * Attempts to save and restore device 132324Sbill * status. 133324Sbill * 134324Sbill * Whether or not printing is inhibited, 135324Sbill * the last MSGBUFS characters 136324Sbill * are saved in msgbuf for inspection later. 137324Sbill */ 138324Sbill putchar(c) 139*3262Swnj register c; 140324Sbill { 141324Sbill register s, timo; 142324Sbill 143324Sbill timo = 30000; 144324Sbill /* 145324Sbill * Try waiting for the console tty to come ready, 146324Sbill * otherwise give up after a reasonable time. 147324Sbill */ 148324Sbill while((mfpr(TXCS)&TXCS_RDY) == 0) 149324Sbill if(--timo == 0) 150324Sbill break; 151324Sbill if(c == 0) 152324Sbill return; 153324Sbill s = mfpr(TXCS); 154324Sbill mtpr(TXCS,0); 155324Sbill mtpr(TXDB, c&0xff); 156324Sbill if(c == '\n') 157324Sbill putchar('\r'); 158324Sbill putchar(0); 159324Sbill mtpr(TXCS, s); 160324Sbill } 161324Sbill 162324Sbill getchar() 163324Sbill { 164324Sbill register c; 165324Sbill 166324Sbill while((mfpr(RXCS)&RXCS_DONE) == 0) 167324Sbill ; 168324Sbill c = mfpr(RXDB)&0177; 169324Sbill if (c=='\r') 170324Sbill c = '\n'; 171324Sbill putchar(c); 172324Sbill return(c); 173324Sbill } 174324Sbill 175324Sbill gets(buf) 176*3262Swnj char *buf; 177324Sbill { 178*3262Swnj register char *lp; 179*3262Swnj register c; 180324Sbill 181324Sbill lp = buf; 182324Sbill for (;;) { 183324Sbill c = getchar() & 0177; 184324Sbill if (c>='A' && c<='Z') 185324Sbill c -= 'A' - 'a'; 186324Sbill if (lp != buf && *(lp-1) == '\\') { 187324Sbill lp--; 188324Sbill if (c>='a' && c<='z') { 189324Sbill c += 'A' - 'a'; 190324Sbill goto store; 191324Sbill } 192324Sbill switch ( c) { 193324Sbill case '(': 194324Sbill c = '{'; 195324Sbill break; 196324Sbill case ')': 197324Sbill c = '}'; 198324Sbill break; 199324Sbill case '!': 200324Sbill c = '|'; 201324Sbill break; 202324Sbill case '^': 203324Sbill c = '~'; 204324Sbill break; 205324Sbill case '\'': 206324Sbill c = '`'; 207324Sbill break; 208324Sbill } 209324Sbill } 210324Sbill store: 211324Sbill switch(c) { 212324Sbill case '\n': 213324Sbill case '\r': 214324Sbill c = '\n'; 215324Sbill *lp++ = '\0'; 216324Sbill return; 217324Sbill case '\b': 218324Sbill case '#': 219324Sbill lp--; 220324Sbill if (lp < buf) 221324Sbill lp = buf; 222324Sbill continue; 223324Sbill case '@': 2241530Sbill case 'u'&037: 225324Sbill lp = buf; 226324Sbill putchar('\n'); 227324Sbill continue; 228324Sbill default: 229324Sbill *lp++ = c; 230324Sbill } 231324Sbill } 232324Sbill } 233