Annotation of coherent/d/286_KERNEL/USRSRC/io/ms.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.