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

  1. /*
  2.  *  Versatec matrix printer/plotter 
  3.  *  dma interface driver
  4.  */
  5.  
  6. #include "../h/param.h"
  7. #include "../h/dir.h"
  8. #include "../h/user.h"
  9. #include "../h/buf.h"
  10. #include "../h/systm.h"
  11.  
  12. #define    VPPRI    (PZERO+8)
  13.  
  14. /* device registers */
  15. struct vpregs {
  16.     int    plbcr;
  17.     int    fill;
  18.     int    prbcr;
  19.     caddr_t    pbaddr;
  20.     int    plcsr;
  21.     int    plbuf;
  22.     int    prcsr;
  23.     caddr_t    prbuf;
  24. };
  25.  
  26. #define    VPADDR    ((struct vpregs *)0177500)
  27.  
  28. /* status bits */
  29. #define    ERROR    0100000
  30. #define    DTCINTR    040000
  31. #define    DMAACT    020000
  32. #define    READY    0200
  33. #define    IENABLE    0100
  34. #define TERMCOM    040
  35. #define    FFCOM    020
  36. #define    EOTCOM    010
  37. #define    CLRCOM    04
  38. #define    RESET    02
  39. #define    SPP    01
  40.  
  41. struct {
  42.     int    vp_state;
  43.     int    vp_count;
  44.     struct    buf    *vp_buf;
  45.     caddr_t    vp_bufp;
  46. }    vp11;
  47.  
  48. /*states */
  49. #define    ISOPEN    01
  50. #define    CMNDS    076
  51. #define    MODE    0700
  52. #define    PRINT    0100
  53. #define    PLOT    0200
  54. #define    PPLOT    0400
  55. #define    BUSY    01000
  56.  
  57. vpopen()
  58. {
  59.     if (vp11.vp_state & ISOPEN) {
  60.         u.u_error = ENXIO;
  61.         return;
  62.     }
  63.     vp11.vp_state = ISOPEN | PRINT | CLRCOM | FFCOM | RESET;
  64.     vp11.vp_count = 0;
  65.     vp11.vp_buf = geteblk();
  66.     vp11.vp_bufp = vp11.vp_buf->b_un.b_addr;
  67.     VPADDR->prcsr = IENABLE | DTCINTR;
  68.     vptimo();
  69.     while(vp11.vp_state & CMNDS) {
  70.         spl4();
  71.         if (vperror(READY)) {
  72.             vpclose();
  73.             u.u_error = EIO;
  74.             return;
  75.         }
  76.         vpstart();
  77.         spl0();
  78.     }
  79. }
  80.  
  81. vpwrite()
  82. {
  83.     register int i, e;
  84.  
  85.     if (u.u_count == 0)
  86.         return;
  87.     spl4();
  88.     while(vp11.vp_state & BUSY)
  89.         sleep((caddr_t)&vp11, VPPRI);
  90.     vp11.vp_state |= BUSY;
  91.     spl0();
  92.     while(i = vp11.vp_count = min(512,u.u_count)) {
  93.         u.u_offset = 0;        /* Make even, speed up iomove */
  94.         iomove(vp11.vp_buf->b_un.b_addr, i, B_WRITE);
  95.         spl4();
  96.         if (e = vperror(READY))
  97.             break;
  98.         vpstart();
  99.         while ((vp11.vp_state&PLOT?VPADDR->plcsr:VPADDR->prcsr)&DMAACT)
  100.             sleep((caddr_t)&vp11, VPPRI);
  101.         if ((vp11.vp_state&MODE) == PPLOT)
  102.             vp11.vp_state = vp11.vp_state&~MODE | PLOT;
  103.         spl0();
  104.     }
  105.     vp11.vp_state &= ~BUSY;
  106.     if (e)
  107.         u.u_error = EIO;
  108.     wakeup((caddr_t)&vp11);
  109. }
  110.  
  111. vperror(bit)
  112. {
  113.     register state, e;
  114.  
  115.     state = vp11.vp_state&PLOT;
  116.     while((e=(state?VPADDR->plcsr:VPADDR->prcsr) & (bit|ERROR)) == 0)
  117.         sleep((caddr_t)&vp11, VPPRI);
  118.     return(e&ERROR);
  119. }
  120.  
  121. vpstart()
  122. {
  123.     register bit;
  124.  
  125.     if (vp11.vp_count) {
  126.         VPADDR->pbaddr = vp11.vp_bufp;
  127.         if (vp11.vp_state & (PRINT|PPLOT))
  128.             VPADDR->prbcr = vp11.vp_count;
  129.         else
  130.             VPADDR->plbcr = vp11.vp_count;
  131.         return;
  132.     }
  133.     for (bit=1; bit!=0; bit <<= 1)
  134.         if (vp11.vp_state&bit&CMNDS) {
  135.             VPADDR->plcsr |= bit;
  136.             vp11.vp_state &= ~bit;
  137.             return;
  138.         }
  139. }
  140.  
  141. vpioctl(dev, cmd, addr, flag)
  142. register caddr_t addr;
  143. {
  144.     register m;
  145.  
  146.     switch(cmd) {
  147.  
  148.     /* get mode */
  149.     case ('v'<<8)+0:
  150.         suword(addr, vp11.vp_state);
  151.         return;
  152.  
  153.     /* set mode */
  154.     case ('v'<<8)+1:
  155.         m = fuword(addr);
  156.         if (m == -1) {
  157.             u.u_error = EFAULT;
  158.             return;
  159.         }
  160.         spl4();
  161.         vperror(READY);
  162.         vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS));
  163.         if (vp11.vp_state&PPLOT)
  164.             VPADDR->plcsr |= SPP;
  165.         else
  166.             VPADDR->plcsr &= ~SPP;
  167.         vp11.vp_count = 0;
  168.         while(CMNDS & vp11.vp_state) {
  169.             vperror(READY);
  170.             vpstart();
  171.         }
  172.         spl0();
  173.         return;
  174.  
  175.     default:
  176.         u.u_error = ENOTTY;
  177.         return;
  178.     }
  179. }
  180.  
  181. vptimo()
  182. {
  183.     if (vp11.vp_state&ISOPEN)
  184.         timeout(vptimo, (caddr_t)0, HZ/10);
  185.     vpintr(0);
  186. }
  187.  
  188. vpintr(dev)
  189. {
  190.     wakeup((caddr_t)&vp11);
  191. }
  192.  
  193. vpclose()
  194. {
  195.     brelse(vp11.vp_buf);
  196.     vp11.vp_state = 0;
  197.     vp11.vp_count = 0;
  198.     vp11.vp_buf = 0;
  199.     vp11.vp_bufp = 0;
  200.     VPADDR->plcsr = 0;
  201. }
  202.