1*23236Smckusick /* 2*23236Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23236Smckusick * All rights reserved. The Berkeley software License Agreement 4*23236Smckusick * specifies the terms and conditions for redistribution. 5*23236Smckusick * 6*23236Smckusick * @(#)prf.c 6.2 (Berkeley) 06/08/85 7*23236Smckusick */ 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 putchar('<'); 873262Swnj while (i = *s++) { 883262Swnj if (b & (1 << (i-1))) { 893262Swnj if (any) 903262Swnj putchar(','); 913262Swnj any = 1; 923262Swnj for (; (c = *s) > 32; s++) 933262Swnj putchar(c); 943262Swnj } else 953262Swnj for (; *s > 32; s++) 963262Swnj ; 973262Swnj } 983262Swnj putchar('>'); 993262Swnj } 1003262Swnj break; 1013262Swnj 1023262Swnj case 's': 1033262Swnj s = (char *)*adx; 1043262Swnj while (c = *s++) 105324Sbill putchar(c); 1063262Swnj break; 107324Sbill } 108324Sbill adx++; 109324Sbill goto loop; 110324Sbill } 111324Sbill 112324Sbill /* 1133262Swnj * Printn prints a number n in base b. 1143262Swnj * We don't use recursion to avoid deep kernel stacks. 115324Sbill */ 116324Sbill printn(n, b) 1173262Swnj u_long n; 118324Sbill { 1193262Swnj char prbuf[11]; 1203262Swnj register char *cp; 121324Sbill 1223262Swnj if (b == 10 && (int)n < 0) { 123324Sbill putchar('-'); 1243262Swnj n = (unsigned)(-(int)n); 125324Sbill } 1263262Swnj cp = prbuf; 1273262Swnj do { 1283262Swnj *cp++ = "0123456789abcdef"[n%b]; 1293262Swnj n /= b; 1303262Swnj } while (n); 1313262Swnj do 1323262Swnj putchar(*--cp); 1333262Swnj while (cp > prbuf); 134324Sbill } 135324Sbill 136324Sbill /* 137324Sbill * Print a character on console. 138324Sbill * Attempts to save and restore device 139324Sbill * status. 140324Sbill * 141324Sbill * Whether or not printing is inhibited, 142324Sbill * the last MSGBUFS characters 143324Sbill * are saved in msgbuf for inspection later. 144324Sbill */ 145324Sbill putchar(c) 1463262Swnj register c; 147324Sbill { 148324Sbill register s, timo; 149324Sbill 150324Sbill timo = 30000; 151324Sbill /* 152324Sbill * Try waiting for the console tty to come ready, 153324Sbill * otherwise give up after a reasonable time. 154324Sbill */ 155324Sbill while((mfpr(TXCS)&TXCS_RDY) == 0) 156324Sbill if(--timo == 0) 157324Sbill break; 158324Sbill if(c == 0) 159324Sbill return; 160324Sbill s = mfpr(TXCS); 161324Sbill mtpr(TXCS,0); 162324Sbill mtpr(TXDB, c&0xff); 163324Sbill if(c == '\n') 164324Sbill putchar('\r'); 165324Sbill putchar(0); 166324Sbill mtpr(TXCS, s); 167324Sbill } 168324Sbill 169324Sbill getchar() 170324Sbill { 171324Sbill register c; 172324Sbill 173324Sbill while((mfpr(RXCS)&RXCS_DONE) == 0) 174324Sbill ; 175324Sbill c = mfpr(RXDB)&0177; 176324Sbill if (c=='\r') 177324Sbill c = '\n'; 178324Sbill putchar(c); 179324Sbill return(c); 180324Sbill } 181324Sbill 182324Sbill gets(buf) 1833262Swnj char *buf; 184324Sbill { 1853262Swnj register char *lp; 1863262Swnj register c; 187324Sbill 188324Sbill lp = buf; 189324Sbill for (;;) { 190324Sbill c = getchar() & 0177; 191324Sbill store: 192324Sbill switch(c) { 193324Sbill case '\n': 194324Sbill case '\r': 195324Sbill c = '\n'; 196324Sbill *lp++ = '\0'; 197324Sbill return; 198324Sbill case '\b': 199324Sbill case '#': 200324Sbill lp--; 201324Sbill if (lp < buf) 202324Sbill lp = buf; 203324Sbill continue; 204324Sbill case '@': 2051530Sbill case 'u'&037: 206324Sbill lp = buf; 207324Sbill putchar('\n'); 208324Sbill continue; 209324Sbill default: 210324Sbill *lp++ = c; 211324Sbill } 212324Sbill } 213324Sbill } 214