1 /* prf.c 1.4 88/03/03 */ 2 /* prf.c 4.3 81/05/05 */ 3 4 #include "../machine/mtpr.h" 5 6 #include "param.h" 7 #include "../tahoe/cp.h" 8 9 /* 10 * Scaled down version of C Library printf. 11 * Used to print diagnostic information directly on console tty. 12 * Since it is not interrupt driven, all system activities are 13 * suspended. Printf should not be used for chit-chat. 14 * 15 * One additional format: %b is supported to decode error registers. 16 * Usage is: 17 * printf("reg=%b\n", regval, "<base><arg>*"); 18 * Where <base> is the output base expressed as a control character, 19 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 20 * characters, the first of which gives the bit number to be inspected 21 * (origin 1), and the next characters (up to a control character, i.e. 22 * a character <= 32), give the name of the register. Thus 23 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 24 * would produce output: 25 * reg=2<BITTWO,BITONE> 26 */ 27 /*VARARGS1*/ 28 printf(fmt, x1) 29 char *fmt; 30 unsigned x1; 31 { 32 33 prf(fmt, &x1); 34 } 35 36 prf(fmt, adx) 37 register char *fmt; 38 register u_int *adx; 39 { 40 register int b, c, i; 41 char *s; 42 int any; 43 44 loop: 45 while ((c = *fmt++) != '%') { 46 if (c == '\0') 47 return; 48 putchar(c); 49 } 50 again: 51 c = *fmt++; 52 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ 53 switch (c) { 54 55 case 'l': 56 goto again; 57 case 'x': case 'X': 58 b = 16; 59 goto number; 60 case 'd': case 'D': 61 case 'u': /* what a joke */ 62 b = 10; 63 goto number; 64 case 'o': case 'O': 65 b = 8; 66 number: 67 printn((u_long)*adx, b); 68 break; 69 case 'c': 70 b = *adx; 71 for (i = 24; i >= 0; i -= 8) 72 if (c = (b >> i) & 0x7f) 73 putchar(c); 74 break; 75 case 'b': 76 b = *adx++; 77 s = (char *)*adx; 78 printn((u_long)b, *s++); 79 any = 0; 80 if (b) { 81 while (i = *s++) { 82 if (b & (1 << (i-1))) { 83 putchar(any? ',' : '<'); 84 any = 1; 85 for (; (c = *s) > 32; s++) 86 putchar(c); 87 } else 88 for (; *s > 32; s++) 89 ; 90 } 91 if (any) 92 putchar('>'); 93 } 94 break; 95 96 case 's': 97 s = (char *)*adx; 98 while (c = *s++) 99 putchar(c); 100 break; 101 } 102 adx++; 103 goto loop; 104 } 105 106 /* 107 * Print a character on console. 108 */ 109 struct cpdcb_o cpout; 110 struct cpdcb_i cpin; 111 112 /* console requires even parity */ 113 #define EVENP 114 115 putchar(c) 116 char c; 117 { 118 int time; 119 #ifdef EVENP 120 register mask, par; 121 122 for (par = 0, mask = 1; mask != 0200; mask <<= 1, par <<= 1) 123 par ^= c&mask; 124 c |= par; 125 #endif EVENP 126 cpout.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 127 cpout.cp_hdr.cp_comm = CPWRITE; 128 cpout.cp_hdr.cp_count = 1; 129 cpout.cp_buf[0] = c; 130 mtpr(CPMDCB, &cpout); 131 time = 100000; /* Delay loop */ 132 while (time--) { 133 uncache(&cpout.cp_hdr.cp_unit); 134 if (cpout.cp_hdr.cp_unit & CPDONE) 135 break; 136 } 137 if (c == '\n') 138 putchar ('\r'); 139 } 140 141 getchar() 142 { 143 char c; 144 145 cpin.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ 146 cpin.cp_hdr.cp_comm = CPREAD; 147 cpin.cp_hdr.cp_count = 1; 148 mtpr(CPMDCB, &cpin); 149 while ((cpin.cp_hdr.cp_unit & CPDONE) == 0) 150 uncache(&cpin.cp_hdr.cp_unit); 151 uncache(&cpin.cpi_buf[0]); 152 c = cpin.cpi_buf[0] & 0x7f; 153 if (c == '\r') 154 c = '\n'; 155 if (c != '\b' && c != '\177') 156 putchar(c); 157 return (c); 158 } 159 160 trap(ps) 161 int ps; 162 { 163 printf("Trap %o\n", ps); 164 for (;;) 165 ; 166 } 167 168 uncache (addr) 169 char *addr; 170 { 171 /* Return *(addr-0x4000); DIRTY assumes this address is valid */ 172 mtpr(PDCS, addr); 173 } 174