123236Smckusick /* 2*29305Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323236Smckusick * All rights reserved. The Berkeley software License Agreement 423236Smckusick * specifies the terms and conditions for redistribution. 523236Smckusick * 6*29305Smckusick * @(#)prf.c 7.1 (Berkeley) 06/05/86 723236Smckusick */ 8324Sbill 93262Swnj #include "../h/param.h" 10324Sbill 119186Ssam #include "../vax/mtpr.h" 129186Ssam #include "../vax/cons.h" 139186Ssam 14324Sbill /* 15324Sbill * Scaled down version of C Library printf. 163262Swnj * Used to print diagnostic information directly on console tty. 173262Swnj * Since it is not interrupt driven, all system activities are 183262Swnj * suspended. Printf should not be used for chit-chat. 193262Swnj * 203262Swnj * One additional format: %b is supported to decode error registers. 213262Swnj * Usage is: 223262Swnj * printf("reg=%b\n", regval, "<base><arg>*"); 233262Swnj * Where <base> is the output base expressed as a control character, 243262Swnj * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 253262Swnj * characters, the first of which gives the bit number to be inspected 263262Swnj * (origin 1), and the next characters (up to a control character, i.e. 273262Swnj * a character <= 32), give the name of the register. Thus 283262Swnj * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 293262Swnj * would produce output: 303262Swnj * reg=2<BITTWO,BITONE> 31324Sbill */ 32324Sbill /*VARARGS1*/ 33324Sbill printf(fmt, x1) 343262Swnj char *fmt; 353262Swnj unsigned x1; 36324Sbill { 373262Swnj 383262Swnj prf(fmt, &x1); 393262Swnj } 403262Swnj 413262Swnj prf(fmt, adx) 423262Swnj register char *fmt; 433262Swnj register u_int *adx; 443262Swnj { 453262Swnj register int b, c, i; 46324Sbill char *s; 473262Swnj int any; 48324Sbill 49324Sbill loop: 503262Swnj while ((c = *fmt++) != '%') { 51324Sbill if(c == '\0') 52324Sbill return; 53324Sbill putchar(c); 54324Sbill } 553262Swnj again: 56324Sbill c = *fmt++; 573262Swnj /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 583262Swnj switch (c) { 593262Swnj 603262Swnj case 'l': 613262Swnj goto again; 623262Swnj case 'x': case 'X': 633262Swnj b = 16; 643262Swnj goto number; 653262Swnj case 'd': case 'D': 663262Swnj case 'u': /* what a joke */ 673262Swnj b = 10; 683262Swnj goto number; 693262Swnj case 'o': case 'O': 703262Swnj b = 8; 713262Swnj number: 723262Swnj printn((u_long)*adx, b); 733262Swnj break; 743262Swnj case 'c': 753262Swnj b = *adx; 763262Swnj for (i = 24; i >= 0; i -= 8) 773262Swnj if (c = (b >> i) & 0x7f) 783262Swnj putchar(c); 793262Swnj break; 803262Swnj case 'b': 813262Swnj b = *adx++; 82324Sbill s = (char *)*adx; 833262Swnj printn((u_long)b, *s++); 843262Swnj any = 0; 853262Swnj if (b) { 863262Swnj while (i = *s++) { 873262Swnj if (b & (1 << (i-1))) { 8826507Skarels putchar(any? ',' : '<'); 893262Swnj any = 1; 903262Swnj for (; (c = *s) > 32; s++) 913262Swnj putchar(c); 923262Swnj } else 933262Swnj for (; *s > 32; s++) 943262Swnj ; 953262Swnj } 9626507Skarels if (any) 9726507Skarels putchar('>'); 983262Swnj } 993262Swnj break; 1003262Swnj 1013262Swnj case 's': 1023262Swnj s = (char *)*adx; 1033262Swnj while (c = *s++) 104324Sbill putchar(c); 1053262Swnj break; 106324Sbill } 107324Sbill adx++; 108324Sbill goto loop; 109324Sbill } 110324Sbill 111324Sbill /* 1123262Swnj * Printn prints a number n in base b. 1133262Swnj * We don't use recursion to avoid deep kernel stacks. 114324Sbill */ 115324Sbill printn(n, b) 1163262Swnj u_long n; 117324Sbill { 1183262Swnj char prbuf[11]; 1193262Swnj register char *cp; 120324Sbill 1213262Swnj if (b == 10 && (int)n < 0) { 122324Sbill putchar('-'); 1233262Swnj n = (unsigned)(-(int)n); 124324Sbill } 1253262Swnj cp = prbuf; 1263262Swnj do { 1273262Swnj *cp++ = "0123456789abcdef"[n%b]; 1283262Swnj n /= b; 1293262Swnj } while (n); 1303262Swnj do 1313262Swnj putchar(*--cp); 1323262Swnj while (cp > prbuf); 133324Sbill } 134324Sbill 135324Sbill /* 136324Sbill * Print a character on console. 137324Sbill */ 138324Sbill putchar(c) 1393262Swnj 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) 1763262Swnj char *buf; 177324Sbill { 1783262Swnj register char *lp; 1793262Swnj register c; 180324Sbill 181324Sbill lp = buf; 182324Sbill for (;;) { 183324Sbill c = getchar() & 0177; 184324Sbill switch(c) { 185324Sbill case '\n': 186324Sbill case '\r': 187324Sbill c = '\n'; 188324Sbill *lp++ = '\0'; 189324Sbill return; 190324Sbill case '\b': 19126507Skarels if (lp > buf) { 19226507Skarels lp--; 19326507Skarels putchar(' '); 19426507Skarels putchar('\b'); 19526507Skarels } 19626507Skarels continue; 197324Sbill case '#': 19823875Smckusick case '\177': 199324Sbill lp--; 200324Sbill if (lp < buf) 201324Sbill lp = buf; 202324Sbill continue; 203324Sbill case '@': 2041530Sbill case 'u'&037: 205324Sbill lp = buf; 206324Sbill putchar('\n'); 207324Sbill continue; 208324Sbill default: 209324Sbill *lp++ = c; 210324Sbill } 211324Sbill } 212324Sbill } 213