|
|
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.