Annotation of coherent/d/PS2_KERNEL/io.286/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/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: }

unix.superglobalmegacorp.com

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