|
|
1.1 root 1: /* va.c 4.1 11/9/80 */
2:
3: #include "../conf/va.h"
4: #if NVA > 0
5: /*
6: * Benson-Varian 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: #include "../h/vcmd.h"
18:
19: int vabdp = 1;
20:
21: unsigned minvaph();
22:
23: #define VAPRI (PZERO-1)
24:
25: #define ushort unsigned short
26: struct varegs {
27: ushort vaba;
28: short vawc;
29: union {
30: short Vacsw;
31: struct {
32: char Vacsl;
33: char Vacsh;
34: } vacsr;
35: } vacs;
36: short vadata;
37: };
38:
39: #define vacsw vacs.Vacsw
40: #define vacsh vacs.vacsr.Vacsh
41: #define vacsl vacs.vacsr.Vacsl
42:
43: /* vacsw bits */
44: #define ERROR 0100000 /* Some error has occurred */
45: #define NPRTIMO 01000 /* DMA timeout error */
46: #define NOTREADY 0400 /* Something besides NPRTIMO */
47: #define DONE 0200
48: #define IENABLE 0100 /* Interrupt enable */
49: #define SUPPLIESLOW 04
50: #define BOTOFFORM 02
51: #define BYTEREVERSE 01 /* Reverse byte order in words */
52:
53: /* vacsh command bytes */
54: #define VAPLOT 0340
55: #define VAPRINT 0100
56: #define VAPRINTPLOT 0160
57: #define VAAUTOSTEP 0244
58: #define VANOAUTOSTEP 0045 /* unused */
59: #define VAFORMFEED 0263 /* unused */
60: #define VASLEW 0265 /* unused */
61: #define VASTEP 0064 /* unused */
62:
63: struct {
64: char va_open;
65: char va_busy;
66: int va_state; /* State: bits are commands in vcmd.h. */
67: int va_wc;
68: int va_bufp;
69: struct buf *va_bp;
70: } va11;
71: int va_ubinfo;
72:
73: struct buf rvabuf; /* Used by physio for a buffer. */
74:
75: vaopen()
76: {
77:
78: if (va11.va_open) {
79: u.u_error = ENXIO;
80: return;
81: }
82: va11.va_open = 1;
83: VAADDR->vawc = 0;
84: va11.va_wc = 0;
85: va11.va_state = 0;
86: VAADDR->vacsl = IENABLE;
87: vatimo();
88: vacmd(VPRINT);
89: if (u.u_error)
90: vaclose();
91: }
92:
93: vastrategy(bp)
94: register struct buf *bp;
95: {
96: register int e;
97:
98: (void) spl4();
99: while (va11.va_busy)
100: sleep((caddr_t)&va11, VAPRI);
101: va11.va_busy = 1;
102: va11.va_bp = bp;
103: va_ubinfo = ubasetup(bp, vabdp);
104: va11.va_bufp = va_ubinfo & 0x3ffff;
105: if (e = vaerror(DONE))
106: goto brkout;
107: va11.va_wc = -(bp->b_bcount/2);
108: vastart();
109: e = vaerror(DONE); /* Wait for DMA to complete */
110: va11.va_wc = 0;
111: va11.va_bufp = 0;
112:
113: /*
114: * After printing a line of characters, VPRINTPLOT mode essentially
115: * reverts to VPLOT mode, plotting things until a new mode is set.
116: * This change is indicated by sending a VAAUTOSTEP command to
117: * the va. We also change va_state to reflect this effective
118: * mode change.
119: */
120: if (va11.va_state & VPRINTPLOT) {
121: va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT;
122: VAADDR->vacsh = VAAUTOSTEP;
123: e |= vaerror(DONE);
124: }
125: (void) spl0();
126: brkout:
127: ubafree(va_ubinfo), va_ubinfo = 0;
128: va11.va_bp = 0;
129: va11.va_busy = 0;
130: iodone(bp);
131: if (e)
132: u.u_error = EIO;
133: wakeup((caddr_t)&va11);
134: }
135:
136: int vablock = 16384;
137:
138: unsigned
139: minvaph(bp)
140: struct buf *bp;
141: {
142: if (bp->b_bcount > vablock)
143: bp->b_bcount = vablock;
144: }
145:
146: /*ARGSUSED*/
147: vawrite(dev)
148: {
149: physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph);
150: }
151:
152: /*
153: * Vaerror waits until bit or ERROR gets set, then returns non-zero if
154: * if it was ERROR that was set.
155: */
156: vaerror(bit)
157: {
158: register int e;
159:
160: while ((e = VAADDR->vacsw & (bit|ERROR)) == 0)
161: sleep((caddr_t)&va11, VAPRI);
162: return (e & ERROR);
163: }
164:
165: vastart()
166: {
167: if (va11.va_wc) {
168: VAADDR->vaba = va11.va_bufp;
169: VAADDR->vawc = va11.va_wc;
170: return;
171: }
172: }
173:
174: /*ARGSUSED*/
175: vaioctl(dev, cmd, addr, flag)
176: register caddr_t addr;
177: {
178: register int vcmd;
179:
180: switch (cmd) {
181:
182: case VGETSTATE:
183: (void) suword(addr, va11.va_state);
184: return;
185:
186: case VSETSTATE:
187: vcmd = fuword(addr);
188: if (vcmd == -1) {
189: u.u_error = EFAULT;
190: return;
191: }
192: vacmd(vcmd);
193: return;
194:
195: default:
196: u.u_error = ENOTTY; /* Not a legal ioctl cmd. */
197: return;
198: }
199: }
200:
201: /*
202: * Send a command code to the va, and wait for it to complete.
203: * If an error occurs, u.u_error is set to EIO.
204: * In any case, update va11.va_state.
205: */
206: vacmd(vcmd)
207: {
208: (void) spl4();
209: (void) vaerror(DONE); /* Wait for va to be ready */
210: switch (vcmd) {
211:
212: case VPLOT:
213: /* Must turn on plot AND autostep modes. */
214: VAADDR->vacsh = VAPLOT;
215: if (vaerror(DONE))
216: u.u_error = EIO;
217: VAADDR->vacsh = VAAUTOSTEP;
218: break;
219:
220: case VPRINT:
221: VAADDR->vacsh = VAPRINT;
222: break;
223:
224: case VPRINTPLOT:
225: VAADDR->vacsh = VAPRINTPLOT;
226: break;
227: }
228: va11.va_state =
229: (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd;
230:
231: if (vaerror(DONE)) /* Wait for command to complete. */
232: u.u_error = EIO;
233: (void) spl0();
234: }
235:
236: vatimo()
237: {
238: if (va11.va_open)
239: timeout(vatimo, (caddr_t)0, HZ/10);
240: vaintr(0);
241: }
242:
243: /*ARGSUSED*/
244: vaintr(dev)
245: {
246: wakeup((caddr_t)&va11);
247: }
248:
249: vaclose()
250: {
251:
252: va11.va_open = 0;
253: va11.va_busy = 0;
254: va11.va_state = 0;
255: va11.va_wc = 0;
256: va11.va_bufp = 0;
257: VAADDR->vacsl = 0;
258: }
259:
260: #define DELAY(N) { register int d; d = N; while (--d > 0); }
261:
262: vareset()
263: {
264:
265: if (va11.va_open == 0)
266: return;
267: printf(" va");
268: VAADDR->vacsl = IENABLE;
269: if (va11.va_state & VPLOT) {
270: VAADDR->vacsh = VAPLOT;
271: DELAY(10000);
272: VAADDR->vacsh = VAAUTOSTEP;
273: } else if (va11.va_state & VPRINTPLOT)
274: VAADDR->vacsh = VPRINTPLOT;
275: else
276: VAADDR->vacsh = VAPRINTPLOT;
277: DELAY(10000);
278: if (va11.va_busy == 0)
279: return;
280: if (va_ubinfo) {
281: printf("<%d>", (va_ubinfo>>28)&0xf);
282: ubafree(va_ubinfo), va_ubinfo = 0;
283: }
284: /* This code belongs in vastart() */
285: va_ubinfo = ubasetup(va11.va_bp, vabdp);
286: va11.va_bufp = va_ubinfo & 0x3ffff;
287: va11.va_wc = (-va11.va_bp->b_bcount/2);
288: /* End badly placed code */
289: vastart();
290: }
291: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.