|
|
1.1 root 1: /* (-lgl
2: * COHERENT Driver Kit Version 1.1.0
3: * Copyright (c) 1982, 1990 by Mark Williams Company.
4: * All rights reserved. May not be copied without permission.
5: -lgl) */
6: /*
7: * Microsoft bus mouse (rodent) driver.
8: */
9:
10: #include <sys/coherent.h>
11: #include <sys/con.h>
12: #include <sys/devices.h>
13: #include <sys/ms.h>
14: #include <errno.h>
15:
16: #define Help(fmt, p) printf(fmt, p)
17: #define Help2(fmt, p, q) printf(fmt, p, q)
18: #define Diag(fmt, p) /* Help(fmt, p) */
19: #define Diag2(fmt, p, q) /* Help2(fmt, p, q) */
20:
21: /*
22: * global patchable definitions
23: */
24: unsigned MSPORT = 0x23C; /* mouse 8255A registers: */
25: /* modified mouse is 0x23C */
26: /* Geac modified mouse is 0x230 */
27: unsigned MSIRQ = 2; /* mouse interrupt # */
28:
29: /*
30: * driver function definitions
31: */
32: int msload();
33: int msunload();
34: int msopen();
35: int msclose();
36: int msioctl();
37: int mspoll();
38: int msintr();
39: int nulldev();
40: int nonedev();
41:
42: /*
43: * configuration table
44: */
45: CON mscon = {
46: DFCHR|DFPOL, /* flags */
47: MS_MAJOR, /* major index */
48: msopen, /* open */
49: msclose, /* close */
50: nonedev, /* block */
51: nonedev, /* read */
52: nonedev, /* write */
53: msioctl, /* ioctl */
54: nulldev, /* power fail */
55: nulldev, /* timeout */
56: msload, /* load */
57: msunload, /* unload */
58: mspoll /* poll */
59: };
60:
61: /*
62: * ioctl function definitions
63: */
64:
65: int ms_setup();
66: int ms_setcrs();
67: int ms_readcrs();
68: int ms_setmick();
69: int ms_readmick();
70: int ms_readbtns();
71: int ms_readstat();
72: int ms_wait();
73:
74: int (*ioctls[])() = {
75: /* 0 1 2 3 4 */
76: ms_setup, ms_setcrs, ms_readcrs, ms_setmick, ms_readmick,
77:
78: /* 5 6 7 */
79: ms_readbtns, ms_readstat, ms_wait
80: };
81:
82: /*
83: * hardware constants
84: */
85: static int porta; /* port A (read/write) */
86: static int portb; /* port B (read/write) */
87: static int portc; /* port C (read/write) */
88: static int portcm; /* control port (write only) */
89:
90: static int u_stts = 0; /* changed-status flags */
91: static int u_mask = 0; /* user condition mask */
92:
93: static event_t ipolls;
94:
95: static struct msparms parms, initparm = {
96: 2, -16, 655, -16, 215, 8, 16
97: };
98:
99: static struct mspos crsr, csav, initcrsr = { 320, 100 };
100:
101: static struct msmick mick, initmick = { 0, 0 };
102:
103: static struct msbuts buttons, initbuttons = {
104: 0,
105: { {0, {320, 100}},
106: {0, {320, 100}},
107: {0, {320, 100}},
108: {0, {320, 100}}
109: }
110: };
111:
112: static int ms_inuse = 0; /* is mouse in use ? */
113:
114: msload()
115: {
116: int s;
117:
118: porta = MSPORT;
119: portb = MSPORT + 1;
120: portc = MSPORT + 2;
121: portcm = MSPORT + 3;
122:
123: s = sphi();
124: outb( portcm, 0x91 ); /* set 8255A mode 9 */
125: outb( portc, 0x10 ); /* disable interrupt */
126: setivec( MSIRQ, msintr ); /* set up irq vector */
127: spl(s);
128:
129: return 0;
130: }
131:
132: /*
133: * Unload function.
134: */
135: msunload()
136: {
137: clrivec( MSIRQ ); /* release irq vector */
138: outb( portcm, 0x91 ); /* set 8255A mode 9 */
139: outb( portc, 0x10 ); /* disable interrupt */
140: }
141:
142: msopen(dev, mode)
143: dev_t dev;
144: {
145: int s;
146:
147: s = sphi(s);
148: if (ms_inuse) {
149: u.u_error = EDBUSY;
150: spl(s);
151: return( -1 );
152: }
153:
154: outb( portcm, 0x91 ); /* set 8255A mode 9 */
155: outb( portb, 0x5a );
156:
157: if( inb( portb ) != 0x5a) { /* hardware installed? */
158: u.u_error = ENXIO;
159: spl(s);
160: return( -1 );
161: }
162:
163: outb( portc, 0x90 );
164: inb( porta );
165: outb( portc, 0xb0 );
166: inb( porta );
167: outb( portc, 0xd0 );
168: inb( porta );
169: outb( portc, 0xf0 );
170: inb( porta );
171: outb( portc, 0 ); /* clear all mouse registers */
172:
173: /* set things */
174: parms = initparm;
175: crsr = csav = initcrsr;
176: mick = initmick;
177: buttons = initbuttons;
178: u_stts = u.u_error = 0;
179: ms_inuse = 1;
180: spl(s);
181:
182: return( 0 );
183: }
184:
185: msclose()
186: {
187: int s;
188:
189: s = sphi();
190: outb( portc, 0x10 ); /* disable interrupt */
191: ms_inuse = u.u_error = 0;
192: spl(s);
193: return( 0 );
194: }
195:
196: msioctl( dev, com, vec )
197: dev_t dev;
198: int com;
199: char *vec;
200: {
201: int s;
202:
203: s = sphi();
204: if (com >= 0 && com < sizeof(ioctls)/sizeof(ioctls[0])) {
205: (*ioctls[com])(vec); /* indirect func call */
206: u.u_error = 0;
207: } else
208: u.u_error = EINVAL;
209: spl(s);
210: if (u.u_error)
211: return( -1 );
212:
213: return( 0 );
214: }
215:
216: /*
217: * Polling routine.
218: * [System V.3 Compatible].
219: */
220: mspoll( dev, ev, msec )
221: dev_t dev;
222: int ev;
223: int msec;
224: {
225: ev &= ~POLLPRI;
226: ev &= ~POLLOUT;
227:
228: /*
229: * No input.
230: */
231: if ( (u_stts & u_mask) == 0 ) {
232: /*
233: * Enable monitor if blocking poll.
234: */
235: if ( msec != 0 )
236: pollopen( &ipolls );
237: /*
238: * Look again to avoid interrupt race.
239: */
240: if ( (u_stts & u_mask) == 0 )
241: ev &= ~POLLIN;
242: }
243:
244: return ev;
245: }
246:
247: /*
248: * write setup structure
249: */
250: ms_setup( newparm )
251: struct msparms *newparm;
252: {
253: ukcopy(newparm, &parms, sizeof(struct msparms));
254: if (parms.h_mpr == 0)
255: parms.h_mpr = 1;
256: if (parms.v_mpr == 0)
257: parms.v_mpr = 1;
258: }
259:
260: /*
261: * write cursor position
262: */
263: ms_setcrs( pos )
264: struct mspos *pos;
265: {
266: ukcopy(pos, &crsr, sizeof(struct mspos));
267: u_stts &= ~MS_S_MOVE; /* clear u_stts pos bit */
268: }
269:
270: /*
271: * read cursor postion
272: */
273: ms_readcrs( pos )
274: struct mspos *pos;
275: {
276: kucopy(&crsr, pos, sizeof(struct mspos));
277: u_stts &= ~MS_S_MOVE; /* clear u_stts pos bit */
278: }
279:
280: /*
281: * write mickey postion
282: */
283: ms_setmick( pos )
284: struct msmick *pos;
285: {
286: ukcopy(pos, &mick, sizeof(struct msmick));
287: }
288:
289: /*
290: * read mickey postion
291: */
292: ms_readmick( pos )
293: struct msmick *pos;
294: {
295: kucopy(&mick, pos, sizeof(struct msmick));
296: }
297:
298: /*
299: * read button status
300: */
301: ms_readbtns( btns )
302: struct msbuts *btns;
303: {
304: kucopy(&buttons, btns, sizeof(struct msbuts));
305: u_stts &= ~MS_S_BUTTONS; /* clear u_stts button bits */
306: }
307:
308: /*
309: * read "changed status" mask
310: */
311: ms_readstat( stat )
312: int *stat;
313: {
314: kucopy(&u_stts, stat, sizeof(int));
315: }
316:
317: /*
318: * wait on "changed status" mask
319: */
320: ms_wait( flag )
321: int *flag;
322: {
323: ukcopy(flag, &u_mask, sizeof(int));
324: while ((u_mask & u_stts) == 0) /* wait until any bit is on */
325: sleep(&u_stts, 0x7fff, 0x7fff, 0);
326: u_mask = 0;
327: }
328:
329: /*
330: * mouse interrupt service routine
331: */
332: msintr()
333: {
334: static int h_fpix = 0; /* fractional pixel */
335: static int v_fpix = 0; /* ditto */
336: int s, n_l, n_h, h_diff, v_diff, tmp, left, right;
337:
338: if (!ms_inuse) /* dev not open - ignore interrupts */
339: return;
340:
341: s = sphi();
342: outb( portc, 0x90 ); /* get horizontal change */
343: n_l = inb( porta );
344: outb( portc, 0xb0 );
345: n_h = inb( porta );
346: h_diff = (char) ((n_l & 0x0f) | (n_h << 4));
347:
348: outb( portc, 0xd0 ); /* get vertical change */
349: n_l = inb( porta );
350: outb( portc, 0xf0 );
351: n_h = inb( porta );
352: v_diff = (char) ((n_l & 0x0f) | (n_h << 4));
353:
354: outb( portc, 0 );
355: left = right = 0; /* set button status */
356: if (!(n_h & 0x80)) left = MS_L_DOWN; /* left button.. */
357: if ((buttons.bbstat & MS_L_DOWN) ^ left) {
358: if (left)
359: button(MS_B_L_PRESS, MS_S_L_PRESS);
360: else
361: button(MS_B_L_RELEASE, MS_S_L_RELEASE);
362: }
363: if (!(n_h & 0x20)) /* right button.. */
364: right = MS_R_DOWN;
365: if ((buttons.bbstat & MS_R_DOWN) ^ right) {
366: if (right)
367: button(MS_B_R_PRESS, MS_S_R_PRESS);
368: else
369: button(MS_B_R_RELEASE, MS_S_R_RELEASE);
370: }
371:
372: buttons.bbstat = left | right; /* set new button status */
373:
374: if (h_diff || v_diff) { /* any motion? */
375: mick.h_mick += h_diff; /* yes - update positions */
376: mick.v_mick += v_diff;
377: if ((abs(h_diff) > parms.accel_t) || (abs(v_diff) > parms.accel_t)) {
378: h_diff *= 2;
379: v_diff *= 2;
380: }
381:
382: if (h_diff) { /* horizontal change */
383: tmp = h_fpix + 8 * h_diff;
384: h_fpix = tmp % parms.h_mpr;
385: tmp = crsr.h_crsr + tmp / parms.h_mpr;
386: crsr.h_crsr = c_range(tmp, parms.h_cmin, parms.h_cmax);
387: }
388:
389: if (v_diff) { /* vertical change */
390: tmp = v_fpix + 8 * v_diff;
391: v_fpix = tmp % parms.v_mpr;
392: tmp = crsr.v_crsr + tmp / parms.v_mpr;
393: crsr.v_crsr = c_range(tmp, parms.v_cmin, parms.v_cmax);
394: }
395:
396: if ((crsr.h_crsr != csav.h_crsr) || (crsr.v_crsr != csav.v_crsr)) {
397: u_stts |= MS_S_MOVE;
398: csav = crsr;
399: }
400: }
401:
402: if (u_stts & u_mask) {
403: wakeup(&u_stts);
404: if ( ipolls.e_procp )
405: pollwake( &ipolls );
406: }
407:
408: spl(s);
409: }
410:
411: /*
412: * update button-press/release data
413: */
414: button( bp, sbit )
415: int bp;
416: unsigned sbit;
417: {
418: ++buttons.buts[bp].cnt;
419: buttons.buts[bp].bpos = crsr;
420: u_stts |= sbit;
421: }
422:
423: /*
424: * force return value to be within specified range
425: */
426: c_range(c, cmin, cmax)
427: int c, cmin, cmax;
428: {
429: if( c < cmin )
430: c = cmin;
431: else if( c > cmax )
432: c = cmax;
433: return( c );
434: }
435:
436: abs(i)
437: int i;
438: {
439: if (i < 0)
440: return (-i);
441: return i;
442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.