1*1939Swnj /* vp.c 4.3 12/19/80 */ 244Sbill 3*1939Swnj #include "vp.h" 41565Sbill #if NVP > 0 51565Sbill /* 61565Sbill * Versatec matrix printer/plotter 71565Sbill * dma interface driver 81565Sbill */ 944Sbill #include "../h/param.h" 1044Sbill #include "../h/dir.h" 1144Sbill #include "../h/user.h" 1244Sbill #include "../h/buf.h" 1344Sbill #include "../h/systm.h" 1444Sbill #include "../h/map.h" 1544Sbill #include "../h/pte.h" 1644Sbill #include "../h/uba.h" 1744Sbill 1844Sbill int vpbdp = 1; 1944Sbill 2044Sbill unsigned minvpph(); 2144Sbill 2244Sbill #define VPPRI (PZERO-1) 2344Sbill 2444Sbill struct vpregs { 2544Sbill short plbcr; 261903Swnj short pbxaddr; 2744Sbill short prbcr; 2844Sbill unsigned short pbaddr; 2944Sbill short plcsr; 3044Sbill short plbuf; 3144Sbill short prcsr; 3244Sbill unsigned short prbuf; 3344Sbill }; 3444Sbill 3544Sbill #define ERROR 0100000 3644Sbill #define DTCINTR 040000 3744Sbill #define DMAACT 020000 3844Sbill #define READY 0200 3944Sbill #define IENABLE 0100 4044Sbill #define TERMCOM 040 4144Sbill #define FFCOM 020 4244Sbill #define EOTCOM 010 4344Sbill #define CLRCOM 04 4444Sbill #define RESET 02 4544Sbill #define SPP 01 4644Sbill 4744Sbill struct { 4844Sbill int vp_state; 4944Sbill int vp_count; 5044Sbill int vp_bufp; 51288Sbill struct buf *vp_bp; 5244Sbill } vp11; 5344Sbill int vp_ubinfo; 5444Sbill 5544Sbill struct buf rvpbuf; 5644Sbill 5744Sbill #define VISOPEN 01 5844Sbill #define CMNDS 076 5944Sbill #define MODE 0700 6044Sbill #define PRINT 0100 6144Sbill #define PLOT 0200 6244Sbill #define PPLOT 0400 6344Sbill #define VBUSY 01000 6444Sbill 6544Sbill vpopen() 6644Sbill { 6744Sbill 6844Sbill if (vp11.vp_state & VISOPEN) { 6944Sbill u.u_error = ENXIO; 7044Sbill return; 7144Sbill } 7244Sbill vp11.vp_state = VISOPEN | PRINT | CLRCOM | RESET; 7344Sbill vp11.vp_count = 0; 7444Sbill VPADDR->prcsr = IENABLE | DTCINTR; 7544Sbill vptimo(); 7644Sbill while (vp11.vp_state & CMNDS) { 77134Sbill (void) spl4(); 7844Sbill if (vperror(READY)) { 7944Sbill vpclose(); 8044Sbill u.u_error = EIO; 8144Sbill return; 8244Sbill } 8344Sbill vpstart(); 84134Sbill (void) spl0(); 8544Sbill } 8644Sbill } 8744Sbill 8844Sbill vpstrategy(bp) 8944Sbill register struct buf *bp; 9044Sbill { 9144Sbill register int e; 9244Sbill 93134Sbill (void) spl4(); 9444Sbill while (vp11.vp_state & VBUSY) 9544Sbill sleep((caddr_t)&vp11, VPPRI); 9644Sbill vp11.vp_state |= VBUSY; 97288Sbill vp11.vp_bp = bp; 9844Sbill vp_ubinfo = ubasetup(bp, vpbdp); 9944Sbill vp11.vp_bufp = vp_ubinfo & 0x3ffff; 10044Sbill if (e = vperror(READY)) 10144Sbill goto brkout; 10244Sbill vp11.vp_count = bp->b_bcount; 10344Sbill vpstart(); 10444Sbill while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT) 10544Sbill sleep((caddr_t)&vp11, VPPRI); 10644Sbill vp11.vp_count = 0; 10744Sbill vp11.vp_bufp = 0; 10844Sbill if ((vp11.vp_state&MODE) == PPLOT) 10944Sbill vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT; 110134Sbill (void) spl0(); 11144Sbill brkout: 11244Sbill ubafree(vp_ubinfo), vp_ubinfo = 0; 11344Sbill vp11.vp_state &= ~VBUSY; 114288Sbill vp11.vp_bp = 0; 11544Sbill iodone(bp); 11644Sbill if (e) 11744Sbill u.u_error = EIO; 11844Sbill wakeup((caddr_t)&vp11); 11944Sbill } 12044Sbill 12144Sbill int vpblock = 16384; 12244Sbill 12344Sbill unsigned 12444Sbill minvpph(bp) 12544Sbill struct buf *bp; 12644Sbill { 12744Sbill 12844Sbill if (bp->b_bcount > vpblock) 12944Sbill bp->b_bcount = vpblock; 13044Sbill } 13144Sbill 13244Sbill /*ARGSUSED*/ 13344Sbill vpwrite(dev) 13444Sbill { 13544Sbill 13644Sbill physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph); 13744Sbill } 13844Sbill 13944Sbill vperror(bit) 14044Sbill { 14144Sbill register int state, e; 14244Sbill 14344Sbill state = vp11.vp_state & PLOT; 14444Sbill while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0) 14544Sbill sleep((caddr_t)&vp11, VPPRI); 14644Sbill return (e & ERROR); 14744Sbill } 14844Sbill 14944Sbill vpstart() 15044Sbill { 15144Sbill register short bit; 15244Sbill 15344Sbill if (vp11.vp_count) { 15444Sbill VPADDR->pbaddr = vp11.vp_bufp; 1551903Swnj VPADDR->pbxaddr = (vp11.vp_bufp>>12)&0x30; 15644Sbill if (vp11.vp_state & (PRINT|PPLOT)) 15744Sbill VPADDR->prbcr = vp11.vp_count; 15844Sbill else 15944Sbill VPADDR->plbcr = vp11.vp_count; 16044Sbill return; 16144Sbill } 16244Sbill for (bit = 1; bit != 0; bit <<= 1) 16344Sbill if (vp11.vp_state&bit&CMNDS) { 16444Sbill VPADDR->plcsr |= bit; 16544Sbill vp11.vp_state &= ~bit; 16644Sbill return; 16744Sbill } 16844Sbill } 16944Sbill 17044Sbill /*ARGSUSED*/ 17144Sbill vpioctl(dev, cmd, addr, flag) 17244Sbill register caddr_t addr; 17344Sbill { 17444Sbill register int m; 17544Sbill 17644Sbill switch (cmd) { 17744Sbill 17844Sbill case ('v'<<8)+0: 179134Sbill (void) suword(addr, vp11.vp_state); 18044Sbill return; 18144Sbill 18244Sbill case ('v'<<8)+1: 18344Sbill m = fuword(addr); 18444Sbill if (m == -1) { 18544Sbill u.u_error = EFAULT; 18644Sbill return; 18744Sbill } 18844Sbill vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS)); 18944Sbill break; 19044Sbill 19144Sbill default: 19244Sbill u.u_error = ENOTTY; 19344Sbill return; 19444Sbill } 195134Sbill (void) spl4(); 196134Sbill (void) vperror(READY); 19744Sbill if (vp11.vp_state&PPLOT) 19844Sbill VPADDR->plcsr |= SPP; 19944Sbill else 20044Sbill VPADDR->plcsr &= ~SPP; 20144Sbill vp11.vp_count = 0; 20244Sbill while (CMNDS & vp11.vp_state) { 203134Sbill (void) vperror(READY); 20444Sbill vpstart(); 20544Sbill } 206134Sbill (void) spl0(); 20744Sbill } 20844Sbill 20944Sbill vptimo() 21044Sbill { 21144Sbill 21244Sbill if (vp11.vp_state&VISOPEN) 21344Sbill timeout(vptimo, (caddr_t)0, HZ/10); 21444Sbill vpintr(0); 21544Sbill } 21644Sbill 21744Sbill /*ARGSUSED*/ 21844Sbill vpintr(dev) 21944Sbill { 22044Sbill 22144Sbill wakeup((caddr_t)&vp11); 22244Sbill } 22344Sbill 22444Sbill vpclose() 22544Sbill { 22644Sbill 22744Sbill vp11.vp_state = 0; 22844Sbill vp11.vp_count = 0; 22944Sbill vp11.vp_bufp = 0; 23044Sbill VPADDR->plcsr = 0; 23144Sbill } 232288Sbill 233288Sbill vpreset() 234288Sbill { 235288Sbill 236288Sbill if ((vp11.vp_state & VISOPEN) == 0) 237288Sbill return; 238288Sbill printf(" vp"); 239288Sbill VPADDR->prcsr = IENABLE | DTCINTR; 240288Sbill if ((vp11.vp_state & VBUSY) == 0) 241288Sbill return; 242288Sbill if (vp_ubinfo) { 243288Sbill printf("<%d>", (vp_ubinfo>>28)&0xf); 244288Sbill ubafree(vp_ubinfo), vp_ubinfo = 0; 245288Sbill } 246288Sbill vp11.vp_bufp = vp_ubinfo & 0x3ffff; 247288Sbill vp11.vp_count = vp11.vp_bp->b_bcount; 248288Sbill vpstart(); 249288Sbill } 2501565Sbill #endif 251