|
|
1.1 root 1: /* vp.c 4.1 11/9/80 */
2:
3: #include "../conf/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 fill;
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: ubafree(vp_ubinfo), vp_ubinfo = 0;
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: if (vp11.vp_state & (PRINT|PPLOT))
156: VPADDR->prbcr = vp11.vp_count;
157: else
158: VPADDR->plbcr = vp11.vp_count;
159: return;
160: }
161: for (bit = 1; bit != 0; bit <<= 1)
162: if (vp11.vp_state&bit&CMNDS) {
163: VPADDR->plcsr |= bit;
164: vp11.vp_state &= ~bit;
165: return;
166: }
167: }
168:
169: /*ARGSUSED*/
170: vpioctl(dev, cmd, addr, flag)
171: register caddr_t addr;
172: {
173: register int m;
174:
175: switch (cmd) {
176:
177: case ('v'<<8)+0:
178: (void) suword(addr, vp11.vp_state);
179: return;
180:
181: case ('v'<<8)+1:
182: m = fuword(addr);
183: if (m == -1) {
184: u.u_error = EFAULT;
185: return;
186: }
187: vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS));
188: break;
189:
190: default:
191: u.u_error = ENOTTY;
192: return;
193: }
194: (void) spl4();
195: (void) vperror(READY);
196: if (vp11.vp_state&PPLOT)
197: VPADDR->plcsr |= SPP;
198: else
199: VPADDR->plcsr &= ~SPP;
200: vp11.vp_count = 0;
201: while (CMNDS & vp11.vp_state) {
202: (void) vperror(READY);
203: vpstart();
204: }
205: (void) spl0();
206: }
207:
208: vptimo()
209: {
210:
211: if (vp11.vp_state&VISOPEN)
212: timeout(vptimo, (caddr_t)0, HZ/10);
213: vpintr(0);
214: }
215:
216: /*ARGSUSED*/
217: vpintr(dev)
218: {
219:
220: wakeup((caddr_t)&vp11);
221: }
222:
223: vpclose()
224: {
225:
226: vp11.vp_state = 0;
227: vp11.vp_count = 0;
228: vp11.vp_bufp = 0;
229: VPADDR->plcsr = 0;
230: }
231:
232: vpreset()
233: {
234:
235: if ((vp11.vp_state & VISOPEN) == 0)
236: return;
237: printf(" vp");
238: VPADDR->prcsr = IENABLE | DTCINTR;
239: if ((vp11.vp_state & VBUSY) == 0)
240: return;
241: if (vp_ubinfo) {
242: printf("<%d>", (vp_ubinfo>>28)&0xf);
243: ubafree(vp_ubinfo), vp_ubinfo = 0;
244: }
245: vp11.vp_bufp = vp_ubinfo & 0x3ffff;
246: vp11.vp_count = vp11.vp_bp->b_bcount;
247: vpstart();
248: }
249: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.