|
|
1.1 ! root 1: /* prf.c 4.3 81/05/05 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../machine/mtpr.h" ! 5: #include "../h/cp.h" ! 6: #ifdef NOIO ! 7: #define CINADR 0xf0000 /* Dummy keyboard (memory mapped) */ ! 8: #define COUTADR 0xf1000 /* Dummy screen -,,- */ ! 9: #endif ! 10: ! 11: /* ! 12: * Scaled down version of C Library printf. ! 13: * Used to print diagnostic information directly on console tty. ! 14: * Since it is not interrupt driven, all system activities are ! 15: * suspended. Printf should not be used for chit-chat. ! 16: * ! 17: * One additional format: %b is supported to decode error registers. ! 18: * Usage is: ! 19: * printf("reg=%b\n", regval, "<base><arg>*"); ! 20: * Where <base> is the output base expressed as a control character, ! 21: * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of ! 22: * characters, the first of which gives the bit number to be inspected ! 23: * (origin 1), and the next characters (up to a control character, i.e. ! 24: * a character <= 32), give the name of the register. Thus ! 25: * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); ! 26: * would produce output: ! 27: * reg=2<BITTWO,BITONE> ! 28: */ ! 29: /*VARARGS1*/ ! 30: printf(fmt, x1) ! 31: char *fmt; ! 32: unsigned x1; ! 33: { ! 34: ! 35: prf(fmt, &x1); ! 36: } ! 37: ! 38: prf(fmt, adx) ! 39: register char *fmt; ! 40: register u_int *adx; ! 41: { ! 42: register int b, c, i; ! 43: char *s; ! 44: int any; ! 45: ! 46: loop: ! 47: while ((c = *fmt++) != '%') { ! 48: if(c == '\0') ! 49: return; ! 50: putchar(c); ! 51: } ! 52: again: ! 53: c = *fmt++; ! 54: /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */ ! 55: switch (c) { ! 56: ! 57: case 'l': ! 58: goto again; ! 59: case 'x': case 'X': ! 60: b = 16; ! 61: goto number; ! 62: case 'd': case 'D': ! 63: case 'u': /* what a joke */ ! 64: b = 10; ! 65: goto number; ! 66: case 'o': case 'O': ! 67: b = 8; ! 68: number: ! 69: printn((u_long)*adx, b); ! 70: break; ! 71: case 'c': ! 72: b = *adx; ! 73: for (i = 24; i >= 0; i -= 8) ! 74: if (c = (b >> i) & 0x7f) ! 75: putchar(c); ! 76: break; ! 77: case 'b': ! 78: b = *adx++; ! 79: s = (char *)*adx; ! 80: printn((u_long)b, *s++); ! 81: any = 0; ! 82: if (b) { ! 83: putchar('<'); ! 84: while (i = *s++) { ! 85: if (b & (1 << (i-1))) { ! 86: if (any) ! 87: putchar(','); ! 88: any = 1; ! 89: for (; (c = *s) > 32; s++) ! 90: putchar(c); ! 91: } else ! 92: for (; *s > 32; s++) ! 93: ; ! 94: } ! 95: putchar('>'); ! 96: } ! 97: break; ! 98: ! 99: case 's': ! 100: s = (char *)*adx; ! 101: while (c = *s++) ! 102: putchar(c); ! 103: break; ! 104: } ! 105: adx++; ! 106: goto loop; ! 107: } ! 108: ! 109: /* ! 110: * Printn prints a number n in base b. ! 111: * We don't use recursion to avoid deep kernel stacks. ! 112: */ ! 113: printn(n, b) ! 114: u_long n; ! 115: { ! 116: char prbuf[11]; ! 117: register char *cp; ! 118: ! 119: if (b == 10 && (int)n < 0) { ! 120: putchar('-'); ! 121: n = (unsigned)(-(int)n); ! 122: } ! 123: cp = prbuf; ! 124: do { ! 125: *cp++ = "0123456789abcdef"[n%b]; ! 126: n /= b; ! 127: } while (n); ! 128: do ! 129: putchar(*--cp); ! 130: while (cp > prbuf); ! 131: } ! 132: ! 133: /* ! 134: * Print a character on console. ! 135: * Attempts to save and restore device ! 136: * status. ! 137: * ! 138: * Whether or not printing is inhibited, ! 139: * the last MSGBUFS characters ! 140: * are saved in msgbuf for inspection later. ! 141: */ ! 142: #ifdef NOIO ! 143: char *coutadr=(char *)COUTADR; ! 144: putchar(c) ! 145: register c; ! 146: { ! 147: *coutadr++ = c; ! 148: } ! 149: ! 150: char *cinadr=(char *)CINADR; ! 151: getchar() ! 152: { ! 153: return( *cinadr++ ); ! 154: } ! 155: ! 156: #else ! 157: struct cpdcb_o cpout; ! 158: struct cpdcb_i cpin; ! 159: ! 160: /* console requires even parity */ ! 161: #define EVENP ! 162: putchar(c) ! 163: char c; ! 164: { ! 165: int time; ! 166: #ifdef EVENP ! 167: register mask, par; ! 168: ! 169: for(par=0, mask=1; mask!=0200; mask<<=1, par<<=1) ! 170: par ^= c&mask; ! 171: c |= par; ! 172: #endif EVENP ! 173: cpout.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ ! 174: cpout.cp_hdr.cp_comm = CPWRITE; ! 175: cpout.cp_hdr.cp_count = 1; ! 176: cpout.cp_buf[0] = c; ! 177: mtpr(&cpout, CPMDCB); ! 178: #ifdef SIMIO ! 179: simout(&cpout); ! 180: #endif ! 181: time = 100000; /* Delay loop */ ! 182: while (time--) { ! 183: uncache (&cpout.cp_hdr.cp_unit) ; ! 184: if (cpout.cp_hdr.cp_unit & CPDONE) break; ! 185: } ! 186: if (c == '\n') putchar ('\r'); ! 187: } ! 188: ! 189: #ifdef SIMIO ! 190: simout(addr) ! 191: { ! 192: asm(".byte 0x4"); ! 193: } ! 194: simin(addr) ! 195: { ! 196: asm(".byte 0x3"); ! 197: } ! 198: #endif ! 199: ! 200: getchar() ! 201: { ! 202: char c; ! 203: ! 204: cpin.cp_hdr.cp_unit = CPCONS; /* Resets done bit */ ! 205: cpin.cp_hdr.cp_comm = CPREAD; ! 206: cpin.cp_hdr.cp_count = 1; ! 207: mtpr(&cpin, CPMDCB); ! 208: #ifdef SIMIO ! 209: simin(&cpin); ! 210: #endif ! 211: while ((cpin.cp_hdr.cp_unit & CPDONE) == 0) ! 212: uncache (&cpin.cp_hdr.cp_unit); ! 213: uncache (&cpin.cpi_buf[0]); ! 214: c = cpin.cpi_buf[0] & 0x7f; ! 215: if (c == '\r') c = '\n'; ! 216: putchar(c); ! 217: return(c); ! 218: } ! 219: #endif ! 220: ! 221: ! 222: gets(buf) ! 223: char *buf; ! 224: { ! 225: register char *lp; ! 226: register c; ! 227: ! 228: lp = buf; ! 229: for (;;) { ! 230: c = getchar() & 0177; ! 231: store: ! 232: switch(c) { ! 233: case '\n': ! 234: case '\r': ! 235: c = '\n'; ! 236: *lp++ = '\0'; ! 237: return; ! 238: case '\b': ! 239: case '#': ! 240: lp--; ! 241: if (lp < buf) ! 242: lp = buf; ! 243: continue; ! 244: case '@': ! 245: case 'u'&037: ! 246: lp = buf; ! 247: putchar('\n'); ! 248: continue; ! 249: default: ! 250: *lp++ = c; ! 251: } ! 252: } ! 253: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.