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