Commit | Line | Data |
---|---|---|
7780575a | 1 | /* va.c 4.6 %G% */ |
20cc8b5b | 2 | |
66b4fb09 | 3 | #include "va.h" |
a5cc519e BJ |
4 | #if NVA > 0 |
5 | /* | |
6 | * Benson-Varian matrix printer/plotter | |
7 | * dma interface driver | |
8 | */ | |
20cc8b5b BJ |
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 | ||
71357272 | 19 | int vabdp = 1; |
20cc8b5b | 20 | |
71357272 | 21 | unsigned minvaph(); |
20cc8b5b BJ |
22 | |
23 | #define VAPRI (PZERO-1) | |
24 | ||
71357272 BJ |
25 | #define ushort unsigned short |
26 | struct varegs { | |
27 | ushort vaba; | |
28 | short vawc; | |
20cc8b5b | 29 | union { |
71357272 | 30 | short Vacsw; |
20cc8b5b | 31 | struct { |
71357272 BJ |
32 | char Vacsl; |
33 | char Vacsh; | |
34 | } vacsr; | |
35 | } vacs; | |
20cc8b5b BJ |
36 | short vadata; |
37 | }; | |
38 | ||
71357272 BJ |
39 | #define vacsw vacs.Vacsw |
40 | #define vacsh vacs.vacsr.Vacsh | |
41 | #define vacsl vacs.vacsr.Vacsl | |
42 | ||
71357272 BJ |
43 | /* vacsw bits */ |
44 | #define ERROR 0100000 /* Some error has occurred */ | |
a5cc519e BJ |
45 | #define NPRTIMO 01000 /* DMA timeout error */ |
46 | #define NOTREADY 0400 /* Something besides NPRTIMO */ | |
47 | #define DONE 0200 | |
71357272 BJ |
48 | #define IENABLE 0100 /* Interrupt enable */ |
49 | #define SUPPLIESLOW 04 | |
a5cc519e BJ |
50 | #define BOTOFFORM 02 |
51 | #define BYTEREVERSE 01 /* Reverse byte order in words */ | |
71357272 BJ |
52 | |
53 | /* vacsh command bytes */ | |
a5cc519e BJ |
54 | #define VAPLOT 0340 |
55 | #define VAPRINT 0100 | |
56 | #define VAPRINTPLOT 0160 | |
57 | #define VAAUTOSTEP 0244 | |
58 | #define VANOAUTOSTEP 0045 /* unused */ | |
71357272 BJ |
59 | #define VAFORMFEED 0263 /* unused */ |
60 | #define VASLEW 0265 /* unused */ | |
61 | #define VASTEP 0064 /* unused */ | |
20cc8b5b BJ |
62 | |
63 | struct { | |
71357272 | 64 | char va_open; |
20cc8b5b BJ |
65 | char va_busy; |
66 | int va_state; /* State: bits are commands in vcmd.h. */ | |
71357272 | 67 | int va_wc; |
20cc8b5b | 68 | int va_bufp; |
71357272 BJ |
69 | struct buf *va_bp; |
70 | } va11; | |
20cc8b5b BJ |
71 | int va_ubinfo; |
72 | ||
73 | struct buf rvabuf; /* Used by physio for a buffer. */ | |
74 | ||
75 | vaopen() | |
76 | { | |
77 | ||
71357272 | 78 | if (va11.va_open) { |
20cc8b5b BJ |
79 | u.u_error = ENXIO; |
80 | return; | |
81 | } | |
71357272 BJ |
82 | va11.va_open = 1; |
83 | VAADDR->vawc = 0; | |
84 | va11.va_wc = 0; | |
85 | va11.va_state = 0; | |
86 | VAADDR->vacsl = IENABLE; | |
20cc8b5b | 87 | vatimo(); |
71357272 | 88 | vacmd(VPRINT); |
20cc8b5b BJ |
89 | if (u.u_error) |
90 | vaclose(); | |
91 | } | |
92 | ||
93 | vastrategy(bp) | |
94 | register struct buf *bp; | |
95 | { | |
96 | register int e; | |
97 | ||
81263dba | 98 | (void) spl4(); |
71357272 BJ |
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; | |
20cc8b5b BJ |
105 | if (e = vaerror(DONE)) |
106 | goto brkout; | |
71357272 | 107 | va11.va_wc = -(bp->b_bcount/2); |
20cc8b5b | 108 | vastart(); |
71357272 BJ |
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. | |
20cc8b5b | 119 | */ |
71357272 BJ |
120 | if (va11.va_state & VPRINTPLOT) { |
121 | va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT; | |
122 | VAADDR->vacsh = VAAUTOSTEP; | |
20cc8b5b BJ |
123 | e |= vaerror(DONE); |
124 | } | |
81263dba | 125 | (void) spl0(); |
20cc8b5b | 126 | brkout: |
b28deaf8 | 127 | ubarelse(&va_ubinfo); |
71357272 BJ |
128 | va11.va_bp = 0; |
129 | va11.va_busy = 0; | |
20cc8b5b BJ |
130 | iodone(bp); |
131 | if (e) | |
132 | u.u_error = EIO; | |
71357272 | 133 | wakeup((caddr_t)&va11); |
20cc8b5b BJ |
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 | ||
71357272 BJ |
160 | while ((e = VAADDR->vacsw & (bit|ERROR)) == 0) |
161 | sleep((caddr_t)&va11, VAPRI); | |
20cc8b5b BJ |
162 | return (e & ERROR); |
163 | } | |
164 | ||
20cc8b5b BJ |
165 | vastart() |
166 | { | |
71357272 BJ |
167 | if (va11.va_wc) { |
168 | VAADDR->vaba = va11.va_bufp; | |
3bfdaa99 | 169 | VAADDR->vacsl = (va11.va_bufp >> 12) & 0x30; |
71357272 | 170 | VAADDR->vawc = va11.va_wc; |
20cc8b5b BJ |
171 | return; |
172 | } | |
173 | } | |
174 | ||
175 | /*ARGSUSED*/ | |
176 | vaioctl(dev, cmd, addr, flag) | |
177 | register caddr_t addr; | |
178 | { | |
179 | register int vcmd; | |
180 | ||
181 | switch (cmd) { | |
182 | ||
183 | case VGETSTATE: | |
71357272 | 184 | (void) suword(addr, va11.va_state); |
20cc8b5b BJ |
185 | return; |
186 | ||
187 | case VSETSTATE: | |
188 | vcmd = fuword(addr); | |
189 | if (vcmd == -1) { | |
190 | u.u_error = EFAULT; | |
191 | return; | |
192 | } | |
193 | vacmd(vcmd); | |
194 | return; | |
195 | ||
196 | default: | |
197 | u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ | |
198 | return; | |
199 | } | |
200 | } | |
201 | ||
71357272 BJ |
202 | /* |
203 | * Send a command code to the va, and wait for it to complete. | |
204 | * If an error occurs, u.u_error is set to EIO. | |
205 | * In any case, update va11.va_state. | |
20cc8b5b | 206 | */ |
20cc8b5b BJ |
207 | vacmd(vcmd) |
208 | { | |
81263dba | 209 | (void) spl4(); |
71357272 | 210 | (void) vaerror(DONE); /* Wait for va to be ready */ |
20cc8b5b BJ |
211 | switch (vcmd) { |
212 | ||
213 | case VPLOT: | |
214 | /* Must turn on plot AND autostep modes. */ | |
71357272 | 215 | VAADDR->vacsh = VAPLOT; |
20cc8b5b BJ |
216 | if (vaerror(DONE)) |
217 | u.u_error = EIO; | |
71357272 | 218 | VAADDR->vacsh = VAAUTOSTEP; |
20cc8b5b BJ |
219 | break; |
220 | ||
221 | case VPRINT: | |
71357272 | 222 | VAADDR->vacsh = VAPRINT; |
20cc8b5b BJ |
223 | break; |
224 | ||
225 | case VPRINTPLOT: | |
71357272 | 226 | VAADDR->vacsh = VAPRINTPLOT; |
20cc8b5b BJ |
227 | break; |
228 | } | |
71357272 BJ |
229 | va11.va_state = |
230 | (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd; | |
20cc8b5b BJ |
231 | |
232 | if (vaerror(DONE)) /* Wait for command to complete. */ | |
233 | u.u_error = EIO; | |
81263dba | 234 | (void) spl0(); |
20cc8b5b BJ |
235 | } |
236 | ||
237 | vatimo() | |
238 | { | |
71357272 | 239 | if (va11.va_open) |
7780575a | 240 | timeout(vatimo, (caddr_t)0, hz/10); |
20cc8b5b BJ |
241 | vaintr(0); |
242 | } | |
243 | ||
244 | /*ARGSUSED*/ | |
245 | vaintr(dev) | |
246 | { | |
71357272 | 247 | wakeup((caddr_t)&va11); |
20cc8b5b BJ |
248 | } |
249 | ||
250 | vaclose() | |
251 | { | |
252 | ||
71357272 BJ |
253 | va11.va_open = 0; |
254 | va11.va_busy = 0; | |
255 | va11.va_state = 0; | |
256 | va11.va_wc = 0; | |
257 | va11.va_bufp = 0; | |
258 | VAADDR->vacsl = 0; | |
259 | } | |
260 | ||
261 | #define DELAY(N) { register int d; d = N; while (--d > 0); } | |
262 | ||
263 | vareset() | |
264 | { | |
265 | ||
266 | if (va11.va_open == 0) | |
267 | return; | |
268 | printf(" va"); | |
269 | VAADDR->vacsl = IENABLE; | |
270 | if (va11.va_state & VPLOT) { | |
271 | VAADDR->vacsh = VAPLOT; | |
272 | DELAY(10000); | |
273 | VAADDR->vacsh = VAAUTOSTEP; | |
274 | } else if (va11.va_state & VPRINTPLOT) | |
275 | VAADDR->vacsh = VPRINTPLOT; | |
276 | else | |
277 | VAADDR->vacsh = VAPRINTPLOT; | |
278 | DELAY(10000); | |
279 | if (va11.va_busy == 0) | |
280 | return; | |
281 | if (va_ubinfo) { | |
282 | printf("<%d>", (va_ubinfo>>28)&0xf); | |
b28deaf8 | 283 | ubarelse(&va_ubinfo); |
71357272 BJ |
284 | } |
285 | /* This code belongs in vastart() */ | |
286 | va_ubinfo = ubasetup(va11.va_bp, vabdp); | |
287 | va11.va_bufp = va_ubinfo & 0x3ffff; | |
288 | va11.va_wc = (-va11.va_bp->b_bcount/2); | |
289 | /* End badly placed code */ | |
290 | vastart(); | |
20cc8b5b | 291 | } |
a5cc519e | 292 | #endif |