home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / sys / dev / kl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-03  |  3.5 KB  |  202 lines

  1. /*
  2.  *   KL/DL-11 driver
  3.  */
  4. #include "../h/param.h"
  5. #include "../h/conf.h"
  6. #include    "../h/dir.h"
  7. #include "../h/user.h"
  8. #include "../h/tty.h"
  9. #include "../h/systm.h"
  10.  
  11. /* base address */
  12. #define    KLADDR    ((struct device *)0177560)    /* console */
  13. #define    KLBASE    ((struct device *)0176500)    /* kl and dl11-a */
  14. #define    DLBASE    ((struct device *)0175610)    /* dl-e */
  15. #define    NKL11    1
  16. #define    NDL11    0
  17. #define DSRDY    02
  18. #define    RDRENB    01
  19. #define    DLDELAY    4    /* Extra delay for DL's (double buff) */
  20.  
  21. #define    NL1    000400
  22. #define    NL2    001000
  23. #define    CR2    020000
  24. #define    FF1    040000
  25. #define    TAB1    002000
  26.  
  27. struct    tty kl11[NKL11+NDL11];
  28. int    klstart();
  29. int    ttrstrt();
  30. char    partab[];
  31.  
  32. struct device {
  33.     int    rcsr;
  34.     int    rbuf;
  35.     int    tcsr;
  36.     int    tbuf;
  37. };
  38.  
  39. klopen(dev, flag)
  40. dev_t dev;
  41. {
  42.     register struct device *addr;
  43.     register struct tty *tp;
  44.     register d;
  45.  
  46.     d = minor(dev);
  47.     if(d >= NKL11+NDL11) {
  48.         u.u_error = ENXIO;
  49.         return;
  50.     }
  51.     tp = &kl11[d];
  52.     /*
  53.      * set up minor 0 to address KLADDR
  54.      * set up minor 1 thru NKL11-1 to address from KLBASE
  55.      * set up minor NKL11 on to address from DLBASE
  56.      */
  57.     if(d == 0)
  58.         addr = KLADDR;
  59.     else if(d < NKL11)
  60.         addr = KLBASE + (d-1);
  61.     else
  62.         addr = DLBASE + (d-NKL11);
  63.     tp->t_addr = (caddr_t)addr;
  64.     tp->t_oproc = klstart;
  65.     if ((tp->t_state&ISOPEN) == 0) {
  66.         tp->t_state = ISOPEN|CARR_ON;
  67.         tp->t_flags = EVENP|ECHO|XTABS|CRMOD|CR2;
  68.         ttychars(tp);
  69.     }
  70.     addr->rcsr |= IENABLE|DSRDY|RDRENB;
  71.     addr->tcsr |= IENABLE;
  72.     ttyopen(dev, tp);
  73. }
  74.  
  75. klclose(dev, flag)
  76. dev_t dev;
  77. int flag;
  78. {
  79.     register struct tty *tp;
  80.  
  81.     tp = &kl11[minor(dev)];
  82.     ttyclose(tp);
  83. }
  84.  
  85. klread(dev)
  86. dev_t dev;
  87. {
  88.     ttread(&kl11[minor(dev)]);
  89. }
  90.  
  91. klwrite(dev)
  92. dev_t dev;
  93. {
  94.     ttwrite(&kl11[minor(dev)]);
  95. }
  96.  
  97. klxint(dev)
  98. dev_t dev;
  99. {
  100.     register struct tty *tp;
  101.  
  102.     tp = &kl11[minor(dev)];
  103.     ttstart(tp);
  104.     if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT)
  105.         if (tp->t_chan)
  106.             mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
  107.         else
  108.             wakeup((caddr_t)&tp->t_outq);
  109. }
  110.  
  111. klrint(dev)
  112. dev_t dev;
  113. {
  114.     register int c;
  115.     register struct device *addr;
  116.     register struct tty *tp;
  117.  
  118.     tp = &kl11[minor(dev)];
  119.     addr = (struct device *)tp->t_addr;
  120.     c = addr->rbuf;
  121.     addr->rcsr |= RDRENB;
  122.     ttyinput(c, tp);
  123. }
  124.  
  125. klioctl(dev, cmd, addr, flag)
  126. caddr_t addr;
  127. dev_t dev;
  128. {
  129.     if (ttioccom(cmd, &kl11[minor(dev)], addr, dev)==0)
  130.         u.u_error = ENOTTY;
  131. }
  132.  
  133. klstart(tp)
  134. register struct tty *tp;
  135. {
  136.     register c;
  137.     register struct device *addr;
  138.  
  139.     addr = (struct device *)tp->t_addr;
  140.     if((addr->tcsr&DONE) == 0)
  141.         return;
  142.     if ((c=getc(&tp->t_outq)) >= 0) {
  143.         if (tp->t_flags&RAW)
  144.             addr->tbuf = c;
  145.         else if (c<=0177)
  146.             addr->tbuf = c | (partab[c]&0200);
  147.         else {
  148.             timeout(ttrstrt, (caddr_t)tp, (c&0177) + DLDELAY);
  149.             tp->t_state |= TIMEOUT;
  150.         }
  151.     }
  152. }
  153.  
  154. char    *msgbufp = msgbuf;    /* Next saved printf character */
  155. /*
  156.  * Print a character on console.
  157.  * Attempts to save and restore device
  158.  * status.
  159.  * If the switches are 0, all
  160.  * printing is inhibited.
  161.  *
  162.  * Whether or not printing is inhibited,
  163.  * the last MSGBUFS characters
  164.  * are saved in msgbuf for inspection later.
  165.  */
  166. putchar(c)
  167. register c;
  168. {
  169.     register s, timo;
  170.  
  171.     if (c != '\0' && c != '\r' && c != 0177) {
  172.         *msgbufp++ = c;
  173.         if(msgbufp >= &msgbuf[MSGBUFS])
  174.             msgbufp = msgbuf;
  175.     }
  176.     /*
  177.      *  If last char was a break or null, don't print
  178.     */
  179.     if ((KLADDR->rbuf&0177) == 0)
  180.         return;
  181.     timo = 30000;
  182.     /*
  183.      * Try waiting for the console tty to come ready,
  184.      * otherwise give up after a reasonable time.
  185.      */
  186.     while((KLADDR->tcsr&0200) == 0)
  187.         if(--timo == 0)
  188.             break;
  189.     if(c == 0)
  190.         return;
  191.     s = KLADDR->tcsr;
  192.     KLADDR->tcsr = 0;
  193.     KLADDR->tbuf = c;
  194.     if(c == '\n') {
  195.         putchar('\r');
  196.         putchar(0177);
  197.         putchar(0177);
  198.     }
  199.     putchar(0);
  200.     KLADDR->tcsr = s;
  201. }
  202.