8100: # / * general TTY subroutines */ 8101: 8102: #include "../param.h" 8103: #include "../systm.h" 8104: #include "../user.h" 8105: #include "../tty.h" 8106: #include "../proc.h" 8107: #include "../inode.h" 8108: #include "../file.h" 8109: #include "../reg.h" 8110: #include "../conf.h" 8111: 8112: /* Input mapping table-- if an entry is non-zero, when the 8113: * corresponding character is typed preceded by "\" the escape 8114: * sequence is replaced by the table value. Mostly used for 8115: * upper-case only terminals. 8116: */ 8117: char maptab[] 8118: { 8119: 000,000,000,000,004,000,000,000, 8120: 000,000,000,000,000,000,000,000, 8121: 000,000,000,000,000,000,000,000, 8122: 000,000,000,000,000,000,000,000, 8123: 000,'|',000,'#',000,000,000,'`', 8124: '{','}',000,000,000,000,000,000, 8125: 000,000,000,000,000,000,000,000, 8126: 000,000,000,000,000,000,000,000, 8127: '@',000,000,000,000,000,000,000, 8128: 000,000,000,000,000,000,000,000, 8129: 000,000,000,000,000,000,000,000, 8130: 000,000,000,000,000,000,'~',000, 8131: 000,'A','B','C','D','E','F','G', 8132: 'H','I','J','K','L','M','N','O', 8133: 'P','Q','R','S','T','U','V','W', 8134: 'X','Y','Z',000,000,000,000,000, 8135: }; 8136: /* --------------------------- */ 8137: /* The actual structure of a clist block manipulated by 8138: * getc and putc (mch.s) 8139: */ 8140: struct cblock { 8141: struct cblock *c_next; 8142: char info[6]; 8143: }; 8144: /* --------------------------- */ 8145: /* The character lists-- space for 6*NCLIST characters */ 8146: struct cblock cfree[NCLIST]; 8147: /* List head for unused character blocks. */ 8148: struct cblock *cfreelist; 8149: 8150: /* structure of device registers for KL, DL, and DC 8151: * interfaces-- more particularly, those for which the 8152: * SSTART bit is off and can be treated by general routines 8153: * (that is, not DH). 8154: */ 8155: struct { 8156: int ttrcsr; 8157: int ttrbuf; 8158: int tttcsr; 8159: int tttbuf; 8160: }; 8161: /* --------------------------- */ 8162: /* The routine implementing the gtty system call. 8163: * Just call lower level routine and pass back values. 8164: */ 8165: gtty() 8166: { 8167: int v[3]; 8168: register *up, *vp; 8169: 8170: vp = v; 8171: sgtty(vp); 8172: if (u.u_error) 8173: return; 8174: up = u.u_arg[0]; 8175: suword(up, *vp++); 8176: suword(++up, *vp++); 8177: suword(++up, *vp++); 8178: } 8179: /* --------------------------- */ 8180: /* The routine implementing the stty system call. 8181: * Read in values and call lower level. 8182: */ 8183: stty() 8184: { 8185: register int *up; 8186: 8187: up = u.u_arg[0]; 8188: u.u_arg[0] = fuword(up); 8189: u.u_arg[1] = fuword(++up); 8190: u.u_arg[2] = fuword(++up); 8191: sgtty(0); 8192: } 8193: /* --------------------------- */ 8194: /* Stuff common to stty and gtty. 8195: * Check legality and switch out to individual 8196: * device routine. 8197: * v is 0 for stty; the parameters are taken from u.u_arg[]. 8198: * c is non-zero for gtty and is the place in which the device 8199: * routines place their information. 8200: */ 8201: sgtty(v) 8202: int *v; 8203: { 8204: register struct file *fp; 8205: register struct inode *ip; 8206: if ((fp = getf(u.u_ar0[R0])) == NULL) 8207: return; 8208: ip = fp->f_inode; 8209: if ((ip->i_mode&IFMT) != IFCHR) { 8210: u.u_error = ENOTTY; 8211: return; 8212: } 8213: (*cdevsw[ip->i_addr[0].d_major].d_sgtty)(ip->i_addr[0], v); 8214: } 8215: /* --------------------------- */ 8216: /* Wait for output to drain, then flush input waiting. */ 8217: wflushtty(atp) 8218: struct tty *atp; 8219: { 8220: register struct tty *tp; 8221: tp = atp; 8222: spl5(); 8223: while (tp->t_outq.c_cc) { 8224: tp->t_state =| ASLEEP; 8225: sleep(&tp->t_outq, TTOPRI); 8226: } 8227: flushtty(tp); 8228: spl0(); 8229: } 8230: /* --------------------------- */ 8231: /* Initialize clist by freeing all character blocks, then count 8232: * number of character devices. (Once-only routine) 8233: */ 8234: cinit() 8235: { 8236: register int ccp; 8237: register struct cblock *cp; 8238: register struct cdevsw *cdp; 8239: ccp = cfree; 8240: for (cp=(ccp+07)&~07; cp <= &cfree[NCLIST-1]; cp++) { 8241: cp->c_next = cfreelist; 8242: cfreelist = cp; 8243: } 8244: ccp = 0; 8245: for(cdp = cdevsw; cdp->d_open; cdp++) 8246: ccp++; 8247: nchrdev = ccp; 8248: } 8249: /* --------------------------- */ 8250: /* flush all TTY queues 8251: */ 8252: flushtty(atp) 8253: struct tty *atp; 8254: { 8255: register struct tty *tp; 8256: register int sps; 8257: tp = atp; 8258: while (getc(&tp->t_canq) >= 0); 8259: while (getc(&tp->t_outq) >= 0); 8260: wakeup(&tp->t_rawq); 8261: wakeup(&tp->t_outq); 8262: sps = PS->integ; 8263: spl5(); 8264: while (getc(&tp->t_rawq) >= 0); 8265: tp->t_delct = 0; 8266: PS->integ = sps; 8267: } 8268: /* --------------------------- */ 8269: /* transfer raw input list to canonical list, 8270: * doing erase-kill processing and handling escapes. 8271: * It waits until a full line has been typed in cooked mode, 8272: * or until any character has been typed in raw mode. 8273: */ 8274: canon(atp) 8275: struct tty *atp; 8276: { 8277: register char *bp; 8278: char *bp1; 8279: register struct tty *tp; 8280: register int c; 8281: 8282: tp = atp; 8283: spl5(); 8284: while (tp->t_delct==0) { 8285: if ((tp->t_state&CARR_ON)==0) 8286: return(0); 8287: sleep(&tp->t_rawq, TTIPRI); 8288: } 8289: spl0(); 8290: loop: 8291: bp = &canonb[2]; 8292: while ((c=getc(&tp->t_rawq)) >= 0) { 8293: if (c==0377) { 8294: tp->t_delct--; 8295: break; 8296: } 8297: if ((tp->t_flags&RAW)==0) { 8298: if (bp[-1]!='\\') { 8299: if (c==tp->t_erase) { 8300: if (bp > &canonb[2]) 8301: bp--; 8302: continue; 8303: } 8304: if (c==tp->t_kill) 8305: goto loop; 8306: if (c==CEOT) 8307: continue; 8308: } else 8309: if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) { 8310: if (bp[-2] != '\\') 8311: c = maptab[c]; 8312: bp--; 8313: } 8314: } 8315: *bp++ = c; 8316: if (bp>=canonb+CANBSIZ) 8317: break; 8318: } 8319: bp1 = bp; 8320: bp = &canonb[2]; 8321: c = &tp->t_canq; 8322: while (bp<bp1) 8323: putc(*bp++, c); 8324: return(1); 8325: } 8326: /* --------------------------- */ 8327: /* Place a character on raw TTY input queue, putting in delimiters 8328: * and waking up top half as needed. 8329: * Also echo if required. 8330: * The arguments are the character and the appropriate 8331: * tty structure. 8332: */ 8333: ttyinput(ac, atp) 8334: struct tty *atp; 8335: { 8336: register int t_flags, c; 8337: register struct tty *tp; 8338: 8339: tp = atp; 8340: c = ac; 8341: t_flags = tp->t_flags; 8342: if ((c =& 0177) == '\r' && t_flags&CRMOD) 8343: c = '\n'; 8344: if ((t_flags&RAW)==0 && (c==CQUIT || c==CINTR)) { 8345: signal(tp, c==CINTR? SIGINT:SIGQIT); 8346: flushtty(tp); 8347: return; 8348: } 8349: if (tp->t_rawq.c_cc>=TTYHOG) { 8350: flushtty(tp); 8351: return; 8352: } 8353: if (t_flags&LCASE && c>='A' && c<='Z') 8354: c =+ 'a'-'A'; 8355: putc(c, &tp->t_rawq); 8356: if (t_flags&RAW || c=='\n' || c==004) { 8357: wakeup(&tp->t_rawq); 8358: if (putc(0377, &tp->t_rawq)==0) 8359: tp->t_delct++; 8360: } 8361: if (t_flags&ECHO) { 8362: ttyoutput(c, tp); 8363: ttstart(tp); 8364: } 8365: } 8366: /* --------------------------- */ 8367: /* put character on TTY output queue, adding delays, 8368: * expanding tabs, and handling the CR/NL bit. 8369: * It is called both from the top half for output, and from 8370: * interrupt level for echoing. 8371: * The arguments are the character and the tty structure. 8372: */ 8373: ttyoutput(ac, tp) 8374: struct tty *tp; 8375: { 8376: register int c; 8377: register struct tty *rtp; 8378: register char *colp; 8379: int ctype; 8380: 8381: rtp = tp; 8382: c = ac&0177; 8383: /* Ignore EOT in normal mode to avoid hanging up 8384: * certain terminals. 8385: */ 8386: if (c==004 && (rtp->t_flags&RAW)==0) 8387: return; 8388: /* Turn tabs to spaces as required 8389: */ 8390: if (c=='\t' && rtp->t_flags&XTABS) { 8391: do 8392: ttyoutput(' ', rtp); 8393: while (rtp->t_col&07); 8394: return; 8395: } 8396: /* for upper-case-only terminals, 8397: * generate escapes. 8398: */ 8399: if (rtp->t_flags&LCASE) { 8400: colp = "({)}!|^~'`"; 8401: while(*colp++) 8402: if(c == *colp++) { 8403: ttyoutput('\\', rtp); 8404: c = colp[-2]; 8405: break; 8406: } 8407: if ('a'<=c && c<='z') 8408: c =+ 'A' - 'a'; 8409: } 8410: /* turn <nl> to <cr><lf> if desired. 8411: */ 8412: if (c=='\n' && rtp->t_flags&CRMOD) 8413: ttyoutput('\r', rtp); 8414: if (putc(c, &rtp->t_outq)) 8415: return; 8416: /* Calculate delays. 8417: * The numbers here represent clock ticks 8418: * and are not necessarily optimal for all terminals. 8419: * The delays are indicated by characters above 0200, 8420: * thus (unfortunately) restricting the transmission 8421: * path to 7 bits. 8422: */ 8423: colp = &rtp->t_col; 8424: ctype = partab[c]; 8425: c = 0; 8426: switch (ctype&077) { 8427: /* ordinary */ 8428: case 0: 8429: (*colp)++; 8430: /* non-printing */ 8431: case 1: 8432: break; 8433: /* backspace */ 8434: case 2: 8435: if (*colp) 8436: (*colp)--; 8437: break; 8438: /* newline */ 8439: case 3: 8440: ctype = (rtp->t_flags >> 8) & 03; 8441: if(ctype == 1) { /* tty 37 */ 8442: if (*colp) 8443: c = max((*colp>>4) + 3, 6); 8444: } else 8445: if(ctype == 2) { /* vt05 */ 8446: c = 6; 8447: } 8448: *colp = 0; 8449: break; 8450: /* tab */ 8451: case 4: 8452: ctype = (rtp->t_flags >> 10) & 03; 8453: if(ctype == 1) { /* tty 37 */ 8454: c = 1 - (*colp | ~07); 8455: if(c < 5) 8456: c = 0; 8457: } 8458: *colp =| 07; 8459: (*colp)++; 8460: break; 8461: /* vertical motion */ 8462: case 5: 8463: if(rtp->t_flags & VTDELAY) /* tty 37 */ 8464: c = 0177; 8465: break; 8466: /* carriage return */ 8467: case 6: 8468: ctype = (rtp->t_flags >> 12) & 03; 8469: if(ctype == 1) { /* tn 300 */ 8470: c = 5; 8471: } else 8472: if(ctype == 2) { /* ti 700 */ 8473: c = 10; 8474: } 8475: *colp = 0; 8476: } 8477: if(c) 8478: putc(c|0200, &rtp->t_outq); 8479: } 8480: /* --------------------------- */ 8481: /* Restart typewriter output following a delay 8482: * timeout. 8483: * The name of the routine is passed to the timeout 8484: * subroutine and it is called during a clock interrupt. 8485: */ 8486: ttrstrt(atp) 8487: { 8488: register struct tty *tp; 8489: 8490: tp = atp; 8491: tp->t_state =& ~TIMEOUT; 8492: ttstart(tp); 8493: } 8494: /* --------------------------- */ 8495: /* 8496: * Start output on the typewriter. It is used from the top half 8497: * after some characters have been put on the output queue, 8498: * from the interrupt routine to transmit the next 8499: * character, and after a timeout has finished. 8500: * If the SSTART bit is off for the tty the work is done here, 8501: * using the protocol of the single-line interfaces (KL, DL, DC); 8502: * otherwise the address word of the tty structure is 8503: * taken to be the name of the device-dependent startup routine. 8504: */ 8505: ttstart(atp) 8506: struct tty *atp; 8507: { 8508: register int *addr, c; 8509: register struct tty *tp; 8510: struct { int (*func)(); }; 8511: 8512: tp = atp; 8513: addr = tp->t_addr; 8514: if (tp->t_state&SSTART) { 8515: (*addr.func)(tp); 8516: return; 8517: } 8518: if ((addr->tttcsr&DONE)==0 || tp->t_state&TIMEOUT) 8519: return; 8520: if ((c=getc(&tp->t_outq)) >= 0) { 8521: if (c<=0177) 8522: addr->tttbuf = c | (partab[c]&0200); 8523: else { 8524: timeout(ttrstrt, tp, c&0177); 8525: tp->t_state =| TIMEOUT; 8526: } 8527: } 8528: } 8529: /* --------------------------- */ 8530: /* Called from device's read routine after it has 8531: * calculated the tty-structure given as argument. 8532: * The pc is backed up for the duration of this call. 8533: * In case of a caught interrupt, an RTI will re-execute. 8534: */ 8535: ttread(atp) 8536: struct tty *atp; 8537: { 8538: register struct tty *tp; 8539: 8540: tp = atp; 8541: if ((tp->t_state&CARR_ON)==0) 8542: return; 8543: if (tp->t_canq.c_cc || canon(tp)) 8544: while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0); 8545: } 8546: /* --------------------------- */ 8547: /* Called from the device's write routine after it has 8548: * calculated the tty-structure given as argument. 8549: */ 8550: ttwrite(atp) 8551: struct tty *atp; 8552: { 8553: register struct tty *tp; 8554: register int c; 8555: tp = atp; 8556: if ((tp->t_state&CARR_ON)==0) 8557: return; 8558: while ((c=cpass())>=0) { 8559: spl5(); 8560: while (tp->t_outq.c_cc > TTHIWAT) { 8561: ttstart(tp); 8562: tp->t_state =| ASLEEP; 8563: sleep(&tp->t_outq, TTOPRI); 8564: } 8565: spl0(); 8566: ttyoutput(c, tp); 8567: } 8568: ttstart(tp); 8569: } 8570: /* --------------------------- */ 8571: /* Common code for gtty and stty functions on typewriters. 8572: * If v is non-zero then gtty is being done and information is 8573: * passed back therein; 8574: * if it is zero stty is being done and the input information is in the 8575: * u_arg array. 8576: */ 8577: ttystty(atp, av) 8578: int *atp, *av; 8579: { 8580: register *tp, *v; 8581: tp = atp; 8582: if(v = av) { 8583: *v++ = tp->t_speeds; 8584: v->lobyte = tp->t_erase; 8585: v->hibyte = tp->t_kill; 8586: v[1] = tp->t_flags; 8587: return(1); 8588: } 8589: wflushtty(tp); 8590: v = u.u_arg; 8591: tp->t_speeds = *v++; 8592: tp->t_erase = v->lobyte; 8593: tp->t_kill = v->hibyte; 8594: tp->t_flags = v[1]; 8595: return(0); 8596: } 8597: /* --------------------------- */