1 /* vp.c 4.5 12/30/80 */ 2 3 #include "vp.h" 4 #if NVP > 0 5 /* 6 * Versatec matrix printer/plotter 7 * dma interface driver 8 */ 9 #include "../h/param.h" 10 #include "../h/dir.h" 11 #include "../h/user.h" 12 #include "../h/buf.h" 13 #include "../h/systm.h" 14 #include "../h/map.h" 15 #include "../h/pte.h" 16 #include "../h/uba.h" 17 18 int vpbdp = 1; 19 20 unsigned minvpph(); 21 22 #define VPPRI (PZERO-1) 23 24 struct vpregs { 25 short plbcr; 26 short pbxaddr; 27 short prbcr; 28 unsigned short pbaddr; 29 short plcsr; 30 short plbuf; 31 short prcsr; 32 unsigned short prbuf; 33 }; 34 35 #define ERROR 0100000 36 #define DTCINTR 040000 37 #define DMAACT 020000 38 #define READY 0200 39 #define IENABLE 0100 40 #define TERMCOM 040 41 #define FFCOM 020 42 #define EOTCOM 010 43 #define CLRCOM 04 44 #define RESET 02 45 #define SPP 01 46 47 struct { 48 int vp_state; 49 int vp_count; 50 int vp_bufp; 51 struct buf *vp_bp; 52 } vp11; 53 int vp_ubinfo; 54 55 struct buf rvpbuf; 56 57 #define VISOPEN 01 58 #define CMNDS 076 59 #define MODE 0700 60 #define PRINT 0100 61 #define PLOT 0200 62 #define PPLOT 0400 63 #define VBUSY 01000 64 65 vpopen() 66 { 67 68 if (vp11.vp_state & VISOPEN) { 69 u.u_error = ENXIO; 70 return; 71 } 72 vp11.vp_state = VISOPEN | PRINT | CLRCOM | RESET; 73 vp11.vp_count = 0; 74 VPADDR->prcsr = IENABLE | DTCINTR; 75 vptimo(); 76 while (vp11.vp_state & CMNDS) { 77 (void) spl4(); 78 if (vperror(READY)) { 79 vpclose(); 80 u.u_error = EIO; 81 return; 82 } 83 vpstart(); 84 (void) spl0(); 85 } 86 } 87 88 vpstrategy(bp) 89 register struct buf *bp; 90 { 91 register int e; 92 93 (void) spl4(); 94 while (vp11.vp_state & VBUSY) 95 sleep((caddr_t)&vp11, VPPRI); 96 vp11.vp_state |= VBUSY; 97 vp11.vp_bp = bp; 98 vp_ubinfo = ubasetup(bp, vpbdp); 99 vp11.vp_bufp = vp_ubinfo & 0x3ffff; 100 if (e = vperror(READY)) 101 goto brkout; 102 vp11.vp_count = bp->b_bcount; 103 vpstart(); 104 while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT) 105 sleep((caddr_t)&vp11, VPPRI); 106 vp11.vp_count = 0; 107 vp11.vp_bufp = 0; 108 if ((vp11.vp_state&MODE) == PPLOT) 109 vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT; 110 (void) spl0(); 111 brkout: 112 ubarelse(&vp_ubinfo); 113 vp11.vp_state &= ~VBUSY; 114 vp11.vp_bp = 0; 115 iodone(bp); 116 if (e) 117 u.u_error = EIO; 118 wakeup((caddr_t)&vp11); 119 } 120 121 int vpblock = 16384; 122 123 unsigned 124 minvpph(bp) 125 struct buf *bp; 126 { 127 128 if (bp->b_bcount > vpblock) 129 bp->b_bcount = vpblock; 130 } 131 132 /*ARGSUSED*/ 133 vpwrite(dev) 134 { 135 136 physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph); 137 } 138 139 vperror(bit) 140 { 141 register int state, e; 142 143 state = vp11.vp_state & PLOT; 144 while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0) 145 sleep((caddr_t)&vp11, VPPRI); 146 return (e & ERROR); 147 } 148 149 vpstart() 150 { 151 register short bit; 152 153 if (vp11.vp_count) { 154 VPADDR->pbaddr = vp11.vp_bufp; 155 VPADDR->pbxaddr = (vp11.vp_bufp>>12)&0x30; 156 if (vp11.vp_state & (PRINT|PPLOT)) 157 VPADDR->prbcr = vp11.vp_count; 158 else 159 VPADDR->plbcr = vp11.vp_count; 160 return; 161 } 162 for (bit = 1; bit != 0; bit <<= 1) 163 if (vp11.vp_state&bit&CMNDS) { 164 VPADDR->plcsr |= bit; 165 vp11.vp_state &= ~bit; 166 return; 167 } 168 } 169 170 /*ARGSUSED*/ 171 vpioctl(dev, cmd, addr, flag) 172 register caddr_t addr; 173 { 174 register int m; 175 176 switch (cmd) { 177 178 case ('v'<<8)+0: 179 (void) suword(addr, vp11.vp_state); 180 return; 181 182 case ('v'<<8)+1: 183 m = fuword(addr); 184 if (m == -1) { 185 u.u_error = EFAULT; 186 return; 187 } 188 vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); 189 break; 190 191 default: 192 u.u_error = ENOTTY; 193 return; 194 } 195 (void) spl4(); 196 (void) vperror(READY); 197 if (vp11.vp_state&PPLOT) 198 VPADDR->plcsr |= SPP; 199 else 200 VPADDR->plcsr &= ~SPP; 201 vp11.vp_count = 0; 202 while (CMNDS & vp11.vp_state) { 203 (void) vperror(READY); 204 vpstart(); 205 } 206 (void) spl0(); 207 } 208 209 vptimo() 210 { 211 212 if (vp11.vp_state&VISOPEN) 213 timeout(vptimo, (caddr_t)0, HZ/10); 214 vpintr(0); 215 } 216 217 /*ARGSUSED*/ 218 vpintr(dev) 219 { 220 221 wakeup((caddr_t)&vp11); 222 } 223 224 vpclose() 225 { 226 227 vp11.vp_state = 0; 228 vp11.vp_count = 0; 229 vp11.vp_bufp = 0; 230 VPADDR->plcsr = 0; 231 } 232 233 vpreset() 234 { 235 236 if ((vp11.vp_state & VISOPEN) == 0) 237 return; 238 printf(" vp"); 239 VPADDR->prcsr = IENABLE | DTCINTR; 240 if ((vp11.vp_state & VBUSY) == 0) 241 return; 242 if (vp_ubinfo) { 243 printf("<%d>", (vp_ubinfo>>28)&0xf); 244 ubarelse(&vp_ubinfo); 245 } 246 vp11.vp_bufp = vp_ubinfo & 0x3ffff; 247 vp11.vp_count = vp11.vp_bp->b_bcount; 248 vpstart(); 249 } 250 #endif 251