1*45796Sbostic /* prf.c 1.7 90/12/16 */ 225870Ssam /* prf.c 4.3 81/05/05 */ 325870Ssam 4*45796Sbostic #include "../include/mtpr.h" 525870Ssam 643457Sroot #include "sys/param.h" 7*45796Sbostic #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++) != '%') { 4629979Skarels 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))) { 8329979Skarels putchar(any? ',' : '<'); 8425870Ssam any = 1; 8525870Ssam for (; (c = *s) > 32; s++) 8625870Ssam putchar(c); 8725870Ssam } else 8825870Ssam for (; *s > 32; s++) 8925870Ssam ; 9025870Ssam } 9129979Skarels if (any) 9229979Skarels 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 * Print a character on console. 10825870Ssam */ 10925870Ssam struct cpdcb_o cpout; 11025870Ssam struct cpdcb_i cpin; 11125870Ssam 11225870Ssam /* console requires even parity */ 11325870Ssam #define EVENP 11429979Skarels 11525870Ssam putchar(c) 11629979Skarels char c; 11725870Ssam { 11825870Ssam int time; 11925870Ssam #ifdef EVENP 12025870Ssam register mask, par; 12125870Ssam 12229979Skarels for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1) 12325870Ssam par ^= c&mask; 12425870Ssam c |= par; 12525870Ssam #endif EVENP 12625870Ssam cpout.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 12725870Ssam cpout.cp_hdr.cp_comm = CPWRITE; 12825870Ssam cpout.cp_hdr.cp_count = 1; 12925870Ssam cpout.cp_buf[0] = c; 13025870Ssam mtpr(CPMDCB, &cpout); 13125870Ssam time = 100000; /* Delay loop */ 13225870Ssam while (time--) { 13329979Skarels uncache(&cpout.cp_hdr.cp_unit); 13429979Skarels if (cpout.cp_hdr.cp_unit & CPDONE) 13529979Skarels break; 13625870Ssam } 13729979Skarels if (c == '\n') 13829979Skarels putchar ('\r'); 13925870Ssam } 14025870Ssam 14125870Ssam getchar() 14225870Ssam { 14329979Skarels char c; 14425870Ssam 14525870Ssam cpin.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 14625870Ssam cpin.cp_hdr.cp_comm = CPREAD; 14725870Ssam cpin.cp_hdr.cp_count = 1; 14825870Ssam mtpr(CPMDCB, &cpin); 14925870Ssam while ((cpin.cp_hdr.cp_unit & CPDONE) == 0) 15029979Skarels uncache(&cpin.cp_hdr.cp_unit); 15129979Skarels uncache(&cpin.cpi_buf[0]); 15225870Ssam c = cpin.cpi_buf[0] & 0x7f; 15329979Skarels if (c == '\r') 15429979Skarels c = '\n'; 15529979Skarels if (c != '\b' && c != '\177') 15629979Skarels putchar(c); 15729979Skarels return (c); 15825870Ssam } 15933638Sbostic 16033638Sbostic trap(ps) 16133638Sbostic int ps; 16233638Sbostic { 16333638Sbostic printf("Trap %o\n", ps); 16433638Sbostic for (;;) 16533638Sbostic ; 16633638Sbostic } 16733638Sbostic 16833638Sbostic uncache (addr) 16933638Sbostic char *addr; 17033638Sbostic { 17133638Sbostic /* Return *(addr-0x4000); DIRTY assumes this address is valid */ 17233638Sbostic mtpr(PDCS, addr); 17333638Sbostic } 174