home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / 2014.11.minnie.tuhs.org.tar / minnie.tuhs.org / UnixArchive / PDP-11 / Trees / V6 / usr / sys / dmr / dh.c < prev    next >
C/C++ Source or Header  |  1975-07-17  |  5KB  |  301 lines

  1. #
  2. /*
  3.  */
  4.  
  5. /*
  6.  *    DH-11 driver
  7.  *    This driver calls on the DHDM driver.
  8.  *    If the DH has no DM11-BB, then the latter will
  9.  *    be fake. To insure loading of the correct DM code,
  10.  *    lib2 should have dhdm.o, dh.o and dhfdm.o in that order.
  11.  */
  12.  
  13. #include "../param.h"
  14. #include "../conf.h"
  15. #include "../user.h"
  16. #include "../tty.h"
  17. #include "../proc.h"
  18.  
  19. #define    DHADDR    0160020
  20. #define    NDH11    16    /* number of lines */
  21. #define    DHNCH    8    /* max number of DMA chars */
  22.  
  23. struct    tty dh11[NDH11];
  24. /*
  25.  * Place from which to do DMA on output
  26.  */
  27. char    dh_clist[NDH11][DHNCH];
  28.  
  29. /*
  30.  * Used to communicate the number of lines to the DM
  31.  */
  32. int    ndh11    NDH11;
  33.  
  34. /*
  35.  * Hardware control bits
  36.  */
  37. #define    BITS6    01
  38. #define    BITS7    02
  39. #define    BITS8    03
  40. #define    TWOSB    04
  41. #define    PENABLE    020
  42. /* DEC manuals incorrectly say this bit causes generation of even parity. */
  43. #define    OPAR    040
  44. #define    HDUPLX    040000
  45.  
  46. #define    IENABLE    030100
  47. #define    PERROR    010000
  48. #define    FRERROR    020000
  49. #define    XINT    0100000
  50. #define    SSPEED    7    /* standard speed: 300 baud */
  51.  
  52. /*
  53.  * Software copy of last dhbar
  54.  */
  55. int    dhsar;
  56.  
  57. struct dhregs {
  58.     int dhcsr;
  59.     int dhnxch;
  60.     int dhlpr;
  61.     int dhcar;
  62.     int dhbcr;
  63.     int dhbar;
  64.     int dhbreak;
  65.     int dhsilo;
  66. };
  67.  
  68. /*
  69.  * Open a DH11 line.
  70.  */
  71. dhopen(dev, flag)
  72. {
  73.     register struct tty *tp;
  74.     extern dhstart();
  75.  
  76.     if (dev.d_minor >= NDH11) {
  77.         u.u_error = ENXIO;
  78.         return;
  79.     }
  80.     tp = &dh11[dev.d_minor];
  81.     tp->t_addr = dhstart;
  82.     tp->t_dev = dev;
  83.     DHADDR->dhcsr =| IENABLE;
  84.     tp->t_state =| WOPEN|SSTART;
  85.     if ((tp->t_state&ISOPEN) == 0) {
  86.         tp->t_erase = CERASE;
  87.         tp->t_kill = CKILL;
  88.         tp->t_speeds = SSPEED | (SSPEED<<8);
  89.         tp->t_flags = ODDP|EVENP|ECHO;
  90.         dhparam(tp);
  91.     }
  92.     dmopen(dev);
  93.     tp->t_state =& ~WOPEN;
  94.     tp->t_state =| ISOPEN;
  95.     if (u.u_procp->p_ttyp == 0)
  96.         u.u_procp->p_ttyp = tp;
  97. }
  98.  
  99. /*
  100.  * Close a DH11 line.
  101.  */
  102. dhclose(dev)
  103. {
  104.     register struct tty *tp;
  105.  
  106.     tp = &dh11[dev.d_minor];
  107.     dmclose(dev);
  108.     tp->t_state =& (CARR_ON|SSTART);
  109.     wflushtty(tp);
  110. }
  111.  
  112. /*
  113.  * Read from a DH11 line.
  114.  */
  115. dhread(dev)
  116. {
  117.     ttread(&dh11[dev.d_minor]);
  118. }
  119.  
  120. /*
  121.  * write on a DH11 line
  122.  */
  123. dhwrite(dev)
  124. {
  125.     ttwrite(&dh11[dev.d_minor]);
  126. }
  127.  
  128. /*
  129.  * DH11 receiver interrupt.
  130.  */
  131. dhrint()
  132. {
  133.     register struct tty *tp;
  134.     register int c;
  135.  
  136.     while ((c = DHADDR->dhnxch) < 0) {    /* char. present */
  137.         tp = &dh11[(c>>8)&017];
  138.         if (tp >= &dh11[NDH11])
  139.             continue;
  140.         if((tp->t_state&ISOPEN)==0 || (c&PERROR)) {
  141.             wakeup(tp);
  142.             continue;
  143.         }
  144.         if (c&FRERROR)        /* break */
  145.             if (tp->t_flags&RAW)
  146.                 c = 0;        /* null (for getty) */
  147.             else
  148.                 c = 0177;    /* DEL (intr) */
  149.         ttyinput(c, tp);
  150.     }
  151. }
  152.  
  153. /*
  154.  * stty/gtty for DH11
  155.  */
  156. dhsgtty(dev, av)
  157. int *av;
  158. {
  159.     register struct tty *tp;
  160.     register r;
  161.  
  162.     tp = &dh11[dev.d_minor];
  163.     if (ttystty(tp, av))
  164.         return;
  165.     dhparam(tp);
  166. }
  167.  
  168. /*
  169.  * Set parameters from open or stty into the DH hardware
  170.  * registers.
  171.  */
  172. dhparam(atp)
  173. struct tty *atp;
  174. {
  175.     register struct tty *tp;
  176.     register int lpr;
  177.  
  178.     tp = atp;
  179.     spl5();
  180.     DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
  181.     /*
  182.      * Hang up line?
  183.      */
  184.     if (tp->t_speeds.lobyte==0) {
  185.         tp->t_flags =| HUPCL;
  186.         dmclose(tp->t_dev);
  187.         return;
  188.     }
  189.     lpr = (tp->t_speeds.hibyte<<10) | (tp->t_speeds.lobyte<<6);
  190.     if (tp->t_speeds.lobyte == 4)        /* 134.5 baud */
  191.         lpr =| BITS6|PENABLE|HDUPLX; else
  192.         if (tp->t_flags&EVENP)
  193.             if (tp->t_flags&ODDP)
  194.                 lpr =| BITS8; else
  195.                 lpr =| BITS7|PENABLE; else
  196.             lpr =| BITS7|OPAR|PENABLE;
  197.     if (tp->t_speeds.lobyte == 3)    /* 110 baud */
  198.         lpr =| TWOSB;
  199.     DHADDR->dhlpr = lpr;
  200.     spl0();
  201. }
  202.  
  203. /*
  204.  * DH11 transmitter interrupt.
  205.  * Restart each line which used to be active but has
  206.  * terminated transmission since the last interrupt.
  207.  */
  208. dhxint()
  209. {
  210.     register struct tty *tp;
  211.     register ttybit, bar;
  212.  
  213.     bar = dhsar & ~DHADDR->dhbar;
  214.     DHADDR->dhcsr =& ~XINT;
  215.     ttybit = 1;
  216.     for (tp = dh11; bar; tp++) {
  217.         if(bar&ttybit) {
  218.             dhsar =& ~ttybit;
  219.             bar =& ~ttybit;
  220.             tp->t_state =& ~BUSY;
  221.             dhstart(tp);
  222.         }
  223.         ttybit =<< 1;
  224.     }
  225. }
  226.  
  227. /*
  228.  * Start (restart) transmission on the given DH11 line.
  229.  */
  230. dhstart(atp)
  231. struct tty *atp;
  232. {
  233.     extern ttrstrt();
  234.     register c, nch;
  235.     register struct tty *tp;
  236.     int sps;
  237.     char *cp;
  238.  
  239.     sps = PS->integ;
  240.     spl5();
  241.     tp = atp;
  242.     /*
  243.      * If it's currently active, or delaying,
  244.      * no need to do anything.
  245.      */
  246.     if (tp->t_state&(TIMEOUT|BUSY))
  247.         goto out;
  248.     /*
  249.      * t_char is a delay indicator which may have been
  250.      * left over from the last start.
  251.      * Arrange for the delay.
  252.      */
  253.     if (c = tp->t_char) {
  254.         tp->t_char = 0;
  255.         timeout(ttrstrt, tp, (c&0177)+6);
  256.         tp->t_state =| TIMEOUT;
  257.         goto out;
  258.     }
  259.     cp = dh_clist[tp->t_dev.d_minor];
  260.     nch = 0;
  261.     /*
  262.      * Copy DHNCH characters, or up to a delay indicator,
  263.      * to the DMA area.
  264.      */
  265.     while (nch > -DHNCH && (c = getc(&tp->t_outq))>=0) {
  266.         if (c >= 0200) {
  267.             tp->t_char = c;
  268.             break;
  269.         }
  270.         *cp++ = c;
  271.         nch--;
  272.     }
  273.     /*
  274.      * If the writer was sleeping on output overflow,
  275.      * wake him when low tide is reached.
  276.      */
  277.     if (tp->t_outq.c_cc<=TTLOWAT && tp->t_state&ASLEEP) {
  278.         tp->t_state =& ~ASLEEP;
  279.         wakeup(&tp->t_outq);
  280.     }
  281.     /*
  282.      * If any characters were set up, start transmission;
  283.      * otherwise, check for possible delay.
  284.      */
  285.     if (nch) {
  286.         DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
  287.         DHADDR->dhcar = cp+nch;
  288.         DHADDR->dhbcr = nch;
  289.         c = 1<<tp->t_dev.d_minor;
  290.         DHADDR->dhbar =| c;
  291.         dhsar =| c;
  292.         tp->t_state =| BUSY;
  293.     } else if (c = tp->t_char) {
  294.         tp->t_char = 0;
  295.         timeout(ttrstrt, tp, (c&0177)+6);
  296.         tp->t_state =| TIMEOUT;
  297.     }
  298.     out:
  299.     PS->integ = sps;
  300. }
  301.