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