|
|
1.1 ! root 1: /* cons.c 4.2 11/9/80 */ ! 2: ! 3: /* ! 4: * Vax console driver and floppy interface ! 5: */ ! 6: #include "../h/param.h" ! 7: #include "../h/conf.h" ! 8: #include "../h/dir.h" ! 9: #include "../h/user.h" ! 10: #include "../h/tty.h" ! 11: #include "../h/systm.h" ! 12: #include "../h/cons.h" ! 13: #include "../h/mtpr.h" ! 14: #include "../h/mx.h" ! 15: ! 16: /* ! 17: * When running dz's using only SAE (silo alarm) on input ! 18: * it is necessary to call dzrint() at clock interrupt time. ! 19: * This is unsafe unless spl5()s in tty code are changed to ! 20: * spl6()s to block clock interrupts. Note that the dh driver ! 21: * currently in use works the same way as the dz, even though ! 22: * we could try to more intelligently manage its silo. ! 23: * Thus don't take this out if you have no dz's unless you ! 24: * change clock.c and dhtimer(). ! 25: */ ! 26: #define spl5 spl6 ! 27: ! 28: #define NL1 000400 ! 29: #define NL2 001000 ! 30: #define CR2 020000 ! 31: #define FF1 040000 ! 32: #define TAB1 002000 ! 33: ! 34: struct tty cons; ! 35: int cnstart(); ! 36: int ttrstrt(); ! 37: char partab[]; ! 38: ! 39: /*ARGSUSED*/ ! 40: cnopen(dev, flag) ! 41: dev_t dev; ! 42: { ! 43: register struct tty *tp; ! 44: ! 45: tp = &cons; ! 46: tp->t_oproc = cnstart; ! 47: tp->t_iproc = NULL; ! 48: if ((tp->t_state&ISOPEN) == 0) { ! 49: ttychars(tp); ! 50: tp->t_state = ISOPEN|CARR_ON; ! 51: tp->t_flags = EVENP|ECHO|XTABS|CRMOD; ! 52: } ! 53: if (tp->t_state&XCLUDE && u.u_uid != 0) { ! 54: u.u_error = EBUSY; ! 55: return; ! 56: } ! 57: mtpr(RXCS, mfpr(RXCS)|RXCS_IE); ! 58: mtpr(TXCS, mfpr(TXCS)|TXCS_IE); ! 59: (*linesw[tp->t_line].l_open)(dev, tp); ! 60: } ! 61: ! 62: /*ARGSUSED*/ ! 63: cnclose(dev) ! 64: dev_t dev; ! 65: { ! 66: register struct tty *tp; ! 67: ! 68: tp = &cons; ! 69: (*linesw[tp->t_line].l_close)(tp); ! 70: ttyclose(tp); ! 71: } ! 72: ! 73: /*ARGSUSED*/ ! 74: cnread(dev) ! 75: dev_t dev; ! 76: { ! 77: register struct tty *tp; ! 78: ! 79: tp = &cons; ! 80: (*linesw[tp->t_line].l_read)(tp); ! 81: } ! 82: ! 83: /*ARGSUSED*/ ! 84: cnwrite(dev) ! 85: dev_t dev; ! 86: { ! 87: register struct tty *tp; ! 88: ! 89: tp = &cons; ! 90: (*linesw[tp->t_line].l_write)(tp); ! 91: } ! 92: ! 93: /* ! 94: * Got a level-20 receive interrupt - ! 95: * the LSI wants to give us a character. ! 96: * Catch the character, and see who it goes to. ! 97: */ ! 98: /*ARGSUSED*/ ! 99: cnrint(dev) ! 100: dev_t dev; ! 101: { ! 102: register int c; ! 103: register struct tty *tp; ! 104: ! 105: c = mfpr(RXDB); ! 106: if (c&RXDB_ID) { ! 107: cnrfl(c); ! 108: return; ! 109: } ! 110: tp = &cons; ! 111: (*linesw[tp->t_line].l_rint)(c, tp); ! 112: } ! 113: ! 114: /*ARGSUSED*/ ! 115: cnioctl(dev, cmd, addr, flag) ! 116: dev_t dev; ! 117: caddr_t addr; ! 118: { ! 119: register struct tty *tp; ! 120: ! 121: tp = &cons; ! 122: cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); ! 123: if (cmd == 0) ! 124: return; ! 125: if (ttioctl(cmd, tp, addr, dev, flag) == 0) ! 126: u.u_error = ENOTTY; ! 127: } ! 128: ! 129: /* ! 130: * Got a level-20 transmission interrupt - ! 131: * the LSI wants another character. First, ! 132: * see if we can send something to the typewriter. ! 133: * If not, try the floppy. ! 134: */ ! 135: /*ARGSUSED*/ ! 136: cnxint(dev) ! 137: dev_t dev; ! 138: { ! 139: register struct tty *tp; ! 140: ! 141: tp = &cons; ! 142: tp->t_state &= ~BUSY; ! 143: if (tp->t_line) ! 144: (*linesw[tp->t_line].l_start)(tp); ! 145: else ! 146: cnstart(tp); ! 147: if ((tp->t_state & BUSY) == 0) ! 148: conxfl(); ! 149: } ! 150: ! 151: cnstart(tp) ! 152: register struct tty *tp; ! 153: { ! 154: register c; ! 155: register s; ! 156: ! 157: s = spl5(); ! 158: if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) ! 159: goto out; ! 160: if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 161: tp->t_state &= ~ASLEEP; ! 162: if (tp->t_chan) ! 163: mcstart(tp->t_chan, (caddr_t)&tp->t_outq); ! 164: else ! 165: wakeup((caddr_t)&tp->t_outq); ! 166: } ! 167: if (tp->t_outq.c_cc == 0) ! 168: goto out; ! 169: if ((mfpr(TXCS)&TXCS_RDY) == 0) ! 170: return; ! 171: if ((c=getc(&tp->t_outq)) >= 0) { ! 172: if (tp->t_flags&RAW) ! 173: mtpr(TXDB, c&0xff); ! 174: else if (c<=0177) ! 175: mtpr(TXDB, (c | (partab[c]&0200))&0xff); ! 176: else { ! 177: timeout(ttrstrt, (caddr_t)tp, (c&0177)); ! 178: tp->t_state |= TIMEOUT; ! 179: goto out; ! 180: } ! 181: } ! 182: tp->t_state |= BUSY; ! 183: out: ! 184: splx(s); ! 185: } ! 186: ! 187: /* ! 188: * Print a character on console. ! 189: * Attempts to save and restore device ! 190: * status. ! 191: */ ! 192: cnputc(c) ! 193: register c; ! 194: { ! 195: register s, timo; ! 196: ! 197: timo = 30000; ! 198: /* ! 199: * Try waiting for the console tty to come ready, ! 200: * otherwise give up after a reasonable time. ! 201: */ ! 202: while((mfpr(TXCS)&TXCS_RDY) == 0) ! 203: if(--timo == 0) ! 204: break; ! 205: if(c == 0) ! 206: return; ! 207: s = mfpr(TXCS); ! 208: mtpr(TXCS, 0); ! 209: mtpr(TXDB, c&0xff); ! 210: if(c == '\n') ! 211: cnputc('\r'); ! 212: cnputc(0); ! 213: mtpr(TXCS, s); ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.