Annotation of Net2/arch/vax/uba/ps.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1982, 1986 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)ps.c        7.7 (Berkeley) 5/9/91
                     34:  */
                     35: 
                     36: /*
                     37:  * Evans and Sutherland Picture System 2 driver -- Bill Reeves.
                     38:  */
                     39: 
                     40: /*
                     41:  *     Still to be done:
                     42:  *             WAIT_HIT
                     43:  */
                     44: 
                     45: #include "ps.h"
                     46: #if NPS > 0
                     47: 
                     48: #define EXTERNAL_SYNC
                     49: 
                     50: #include "../include/pte.h"
                     51: 
                     52: #include "sys/param.h"
                     53: #include "sys/systm.h"
                     54: #include "sys/ioctl.h"
                     55: #include "sys/map.h"
                     56: #include "sys/buf.h"
                     57: #include "sys/conf.h"
                     58: #include "sys/user.h"
                     59: #include "sys/uio.h"
                     60: 
                     61: #include "ubareg.h"
                     62: #include "ubavar.h"
                     63: #include "psreg.h"
                     64: 
                     65: int    psprobe(), psattach(), psextsync();
                     66: int    psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();
                     67: struct uba_device *psdinfo[NPS];
                     68: u_short        psstd[] = { 0 };
                     69: struct uba_driver psdriver = 
                     70:     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
                     71: 
                     72: #define        PSUNIT(dev)     (minor(dev))
                     73: 
                     74: #define MAXAUTOREFRESH 4
                     75: #define MAXAUTOMAP     4
                     76: #define MAXDBSIZE      (0177777/2)
                     77: 
                     78: #define PSPRI          (PZERO+1)
                     79: 
                     80: #define PSWAIT(psaddr) { \
                     81:        register short i = 20000, j; \
                     82:        while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \
                     83:                ;\
                     84: }
                     85: 
                     86: struct psrefresh {
                     87:        enum {
                     88:                SINGLE_STEP_RF,
                     89:                AUTO_RF,
                     90:                TIME_RF
                     91:        } state;
                     92:        enum {
                     93:                RUNNING_RF,
                     94:                SYNCING_RF,
                     95:                WAITING_MAP,
                     96:                STOPPED_RF
                     97:        } mode;
                     98:        u_short sraddrs[MAXAUTOREFRESH];
                     99:        short   nsraddrs;
                    100:        short   srcntr;
                    101:        char    waiting;
                    102:        char    stop;
                    103:        int     icnt;
                    104:        int     timecnt;
                    105: };
                    106: 
                    107: struct psdbuffer {
                    108:        enum {
                    109:                ON_DB,
                    110:                OFF_DB
                    111:        } state;
                    112:        u_short dbaddrs[2];
                    113:        u_short dbsize;
                    114:        short   rbuffer;
                    115: };
                    116: 
                    117: struct psmap {
                    118:        enum {
                    119:                SINGLE_STEP_MAP,
                    120:                AUTO_MAP
                    121:        } state;
                    122:        enum {
                    123:                RUNNING_MAP,
                    124:                WAITING_RF,
                    125:                WAITING_START,
                    126:                STOPPED_MAP
                    127:        } mode;
                    128:        u_short maddrs[MAXAUTOMAP];
                    129:        short   nmaddrs;
                    130:        short   mcntr;
                    131:        short   outputstart;
                    132:        char    waiting;
                    133:        char    stop;
                    134:        int     icnt;
                    135: };
                    136: 
                    137: /*
                    138:  * PS2 software state.
                    139:  */
                    140: struct ps {
                    141:        char    ps_open;                /* device is open */
                    142:        uid_t   ps_uid;                 /* uid of device owner */
                    143:        struct  psrefresh ps_refresh;   /* refresh state */
                    144:        struct  psdbuffer ps_dbuffer;   /* double buffering state */
                    145:        struct  psmap ps_map;           /* segment map state */
                    146:        int     ps_clockticks;          /* clock ints between refresh */
                    147:        int     ps_clockmiss;           /* clock ints w/o refresh */
                    148:        int     ps_clockcnt;            /* count of clock interrupts */
                    149:        int     ps_hitcnt;              /* count of hit interrupts */
                    150:        int     ps_strayintr;           /* count of stray interrupts */
                    151:        int     ps_icnt;                /* count of system interrupts */
                    152: /* BEGIN GROT */
                    153:        int     ps_lastrequest;
                    154:        int     ps_lastrequest2;
                    155:        int     ps_lastfunnyrequest;
                    156:        int     ps_funnycnt;
                    157: /* END GROT */
                    158: } ps[NPS];
                    159: 
                    160: psprobe(reg)
                    161:        caddr_t reg;
                    162: {
                    163:        register int br, cvec;
                    164:        register struct psdevice *psaddr = (struct psdevice *)reg;
                    165: 
                    166: #ifdef lint
                    167:        br = 0; cvec = br; br = cvec;
                    168:        psclockintr((dev_t)0); pssystemintr((dev_t)0);
                    169:        psdeviceintr((dev_t)0); psdmaintr((dev_t)0);
                    170:        psextsync(0, 0);
                    171: #endif
                    172:        psaddr->ps_iostat = PSRESET;
                    173:        DELAY(200);
                    174:        psaddr->ps_addr = RTCIE;
                    175:        PSWAIT(psaddr); psaddr->ps_data = 01;
                    176:        psaddr->ps_iostat = PSIE;
                    177:        psaddr->ps_addr = RTCSR;
                    178:        PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN;
                    179:        DELAY(200000);
                    180:        psaddr->ps_addr = RTCREQ;
                    181:        PSWAIT(psaddr); psaddr->ps_data = 01;
                    182:        psaddr->ps_iostat = 0;
                    183:        psaddr->ps_iostat = PSRESET;
                    184:        return (sizeof (struct psdevice));
                    185: }
                    186: 
                    187: /*ARGSUSED*/
                    188: psattach(ui)
                    189:        struct uba_device *ui;
                    190: {
                    191: 
                    192: }
                    193: 
                    194: psopen(dev)
                    195:        dev_t dev;
                    196: {
                    197:        register struct ps *psp;
                    198:        register struct uba_device *ui;
                    199:        register int unit = PSUNIT(dev);
                    200: 
                    201:        if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
                    202:            (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
                    203:                return (ENXIO);
                    204:        psp->ps_open = 1;
                    205:        psp->ps_uid = u.u_uid;
                    206:        psp->ps_strayintr = 0;
                    207:        psp->ps_refresh.state = SINGLE_STEP_RF;
                    208:        psp->ps_refresh.mode = STOPPED_RF;
                    209:        psp->ps_refresh.waiting = 0;
                    210:        psp->ps_refresh.stop = 0;
                    211:        psp->ps_dbuffer.state = OFF_DB;
                    212:        psp->ps_map.state = SINGLE_STEP_MAP;
                    213:        psp->ps_map.mode = STOPPED_MAP;
                    214:        psp->ps_map.waiting = 0;
                    215:        psp->ps_map.stop = 0;
                    216:        psp->ps_clockticks = 0;
                    217:        psp->ps_clockmiss = 0;
                    218:        psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0;
                    219:        psp->ps_hitcnt = 0;
                    220:        psp->ps_icnt = 0;
                    221:        maptouser(ui->ui_addr);
                    222:        return (0);
                    223: }
                    224: 
                    225: psclose(dev)
                    226:        dev_t dev;
                    227: {
                    228:        register struct psdevice *psaddr = 
                    229:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    230: 
                    231:        ps[PSUNIT(dev)].ps_open = 0;
                    232:        psaddr->ps_iostat = 0;                   /* clear IENABLE */
                    233:        PSWAIT(psaddr); psaddr->ps_addr = RFSR;  /* set in auto refresh mode */
                    234:        PSWAIT(psaddr); psaddr->ps_data = AUTOREF;
                    235:        unmaptouser((caddr_t)psaddr);
                    236:        return (0);
                    237: }
                    238: 
                    239: /*ARGSUSED*/
                    240: psread(dev, uio)
                    241:        dev_t dev;
                    242:        struct uio *uio;
                    243: {
                    244: }
                    245: 
                    246: /*ARGSUSED*/
                    247: pswrite(dev, uio)
                    248:        dev_t dev;
                    249:        struct uio *uio;
                    250: {
                    251: }
                    252: 
                    253: /*ARGSUSED*/
                    254: psioctl(dev, cmd, data, flag)
                    255:        register caddr_t data;
                    256: {
                    257:        register struct uba_device *ui = psdinfo[PSUNIT(dev)];
                    258:        register struct ps *psp = &ps[PSUNIT(dev)];
                    259:        int *waddr = *(int **)data;
                    260:        int n, arg, i, error = 0;
                    261: 
                    262:        switch (cmd) {
                    263: 
                    264:        case PSIOGETADDR:
                    265:                *(caddr_t *)data = ui->ui_addr;
                    266:                break;
                    267: 
                    268:        case PSIOAUTOREFRESH:
                    269:                n = fuword((caddr_t)waddr++);
                    270:                if (n == -1)
                    271:                        return (EFAULT);
                    272:                if (n < 0 || n > MAXAUTOREFRESH)
                    273:                        return (EINVAL);
                    274:                for (i = 0; i < n; i++) {
                    275:                        if ((arg = fuword((caddr_t)waddr++)) == -1)
                    276:                                return (EFAULT);
                    277:                        psp->ps_refresh.sraddrs[i] = arg;
                    278:                }
                    279:                psp->ps_refresh.state = AUTO_RF;
                    280:                psp->ps_refresh.nsraddrs = n;
                    281:                psp->ps_refresh.srcntr = 0;
                    282:                psp->ps_refresh.mode = WAITING_MAP;
                    283:                break;
                    284: 
                    285:        case PSIOAUTOMAP:
                    286:                n = fuword((caddr_t)waddr++);
                    287:                if (n == -1)
                    288:                        return (EFAULT);
                    289:                if (n < 0 || n > MAXAUTOMAP)
                    290:                        return (EINVAL);
                    291:                for (i = 0; i < n; i++) {
                    292:                        if ((arg = fuword((caddr_t)waddr++)) == -1)
                    293:                                return (EFAULT);
                    294:                        psp->ps_map.maddrs[i] = arg;
                    295:                }
                    296:                if ((arg = fuword((caddr_t)waddr++)) == -1)
                    297:                        return (EFAULT);
                    298:                psp->ps_map.outputstart = arg;
                    299:                psp->ps_map.state = AUTO_MAP;
                    300:                psp->ps_map.nmaddrs = n;
                    301:                psp->ps_map.mcntr = 0;
                    302:                psp->ps_map.mode = WAITING_START;
                    303:                break;
                    304: 
                    305:        case PSIOSINGLEREFRESH:
                    306:                psp->ps_refresh.state = SINGLE_STEP_RF;
                    307:                break;
                    308: 
                    309:        case PSIOSINGLEMAP:
                    310:                psp->ps_map.state = SINGLE_STEP_MAP;
                    311:                break;
                    312: 
                    313:        case PSIODOUBLEBUFFER:
                    314:                if ((arg = fuword((caddr_t)waddr++)) == -1)
                    315:                        return (EFAULT);
                    316:                psp->ps_dbuffer.dbaddrs[0] = arg;
                    317:                if ((arg = fuword((caddr_t)waddr++)) == -1)
                    318:                        return (EFAULT);
                    319:                if (arg <= 0 || arg > MAXDBSIZE)
                    320:                        return (EINVAL);
                    321:                psp->ps_dbuffer.dbsize = arg;
                    322:                psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg;
                    323:                psp->ps_dbuffer.state = ON_DB;
                    324:                psp->ps_dbuffer.rbuffer = 0;
                    325:                break;
                    326: 
                    327:        case PSIOSINGLEBUFFER:
                    328:                psp->ps_dbuffer.state = OFF_DB;
                    329:                break;
                    330: 
                    331:        case PSIOTIMEREFRESH:
                    332:                if (psp->ps_refresh.state != SINGLE_STEP_RF)
                    333:                        return (EINVAL);
                    334:                if ((arg = fuword((caddr_t)waddr++)) == -1)
                    335:                        return (EFAULT);
                    336:                psp->ps_refresh.state = TIME_RF;
                    337:                psp->ps_refresh.timecnt = arg;
                    338:                break;
                    339: 
                    340:        case PSIOWAITREFRESH:
                    341:                if (psp->ps_refresh.mode != RUNNING_RF) /* not running */
                    342:                        return (0);                     /* dont wait */
                    343:                /* fall into ... */
                    344: 
                    345:        case PSIOSTOPREFRESH:
                    346:                if (cmd == PSIOSTOPREFRESH) {
                    347:                        if (psp->ps_refresh.mode == STOPPED_RF &&
                    348:                            psp->ps_refresh.state != TIME_RF)
                    349:                                return (0);
                    350:                        psp->ps_refresh.stop = 1;
                    351:                }
                    352:                (void) spl5();
                    353:                psp->ps_refresh.waiting = 1;
                    354:                while (psp->ps_refresh.waiting)
                    355:                        if (error = tsleep(&psp->ps_refresh.waiting,
                    356:                            PSPRI | PCATCH, devwait, 0))
                    357:                                break;
                    358:                (void) spl0();
                    359:                if (error)
                    360:                        return (error);
                    361:                if (cmd == PSIOSTOPREFRESH)
                    362:                        psp->ps_refresh.mode = STOPPED_RF;
                    363:                if (psp->ps_refresh.state == TIME_RF)
                    364:                        psp->ps_refresh.state = SINGLE_STEP_RF;
                    365:                break;
                    366: 
                    367:        case PSIOWAITMAP:
                    368:                if (psp->ps_map.mode != RUNNING_MAP)    /* not running */
                    369:                        return (0);                     /* dont wait */
                    370:                /* fall into ... */
                    371: 
                    372:        case PSIOSTOPMAP:
                    373:                if (cmd == PSIOSTOPMAP)
                    374:                        psp->ps_map.stop = 1;
                    375:                (void) spl5();
                    376:                psp->ps_map.waiting = 1;
                    377:                while (psp->ps_map.waiting)
                    378:                        if (error = tsleep(&psp->ps_map.waiting, PSPRI | PCATCH,
                    379:                            devwait, 0))
                    380:                                break;
                    381:                (void) spl0();
                    382:                break;
                    383: 
                    384:        default:
                    385:                return (ENOTTY);
                    386:                break;
                    387:        }
                    388:        return (error);
                    389: }
                    390: 
                    391: #define SAVEPSADDR(psaddr, savepsaddr) { \
                    392:        register short i, xx1; \
                    393:        xx1 = splclock(); \
                    394:        i = psaddr->ps_addr; \
                    395:        while ((psaddr->ps_iostat & DIOREADY) == 0) \
                    396:                ; \
                    397:        savepsaddr = psaddr->ps_data; \
                    398:        splx(xx1); \
                    399: }
                    400: #define RESTORPSADDR(psaddr, savepsaddr) { \
                    401:        register short xx2; \
                    402:        xx2 = splclock(); \
                    403:        while ((psaddr->ps_iostat & DIOREADY) == 0) \
                    404:                ;\
                    405:        psaddr->ps_addr = savepsaddr; \
                    406:        splx(xx2); \
                    407: }
                    408: 
                    409: psclockintr(dev)
                    410:        dev_t dev;
                    411: {
                    412:        register struct psdevice *psaddr =
                    413:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    414:        register struct ps *psp = &ps[PSUNIT(dev)];
                    415:        int savepsaddr;
                    416: 
                    417:        if (!psp->ps_open)
                    418:                return;
                    419:        psp->ps_clockcnt++;
                    420:        SAVEPSADDR(psaddr, savepsaddr);
                    421: #ifndef EXTERNAL_SYNC
                    422:        if (psp->ps_refresh.state == AUTO_RF) {
                    423:                if (psp->ps_refresh.mode == SYNCING_RF &&
                    424:                    psp->ps_refresh.state != TIME_RF) {
                    425:                        (void) psrfnext(psp, psaddr);
                    426:                } else {
                    427:                        psp->ps_clockticks++;
                    428:                        psp->ps_clockmiss++;
                    429:                }
                    430:        }
                    431: #endif
                    432:        PSWAIT(psaddr); psaddr->ps_addr = RTCREQ;
                    433:        PSWAIT(psaddr); psaddr->ps_data = 01;   /* clear the request bits */
                    434:        RESTORPSADDR(psaddr, savepsaddr);
                    435: }
                    436: 
                    437: /*ARGSUSED*/
                    438: pssystemintr(dev)
                    439:        dev_t dev;
                    440: {
                    441:        register struct psdevice *psaddr =
                    442:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    443:        register struct ps *psp = &ps[PSUNIT(dev)];
                    444:        short request, tmp;
                    445:        register int savepsaddr, x;
                    446: 
                    447:        if (!psp->ps_open)
                    448:                return;
                    449:        psp->ps_icnt++;
                    450:        SAVEPSADDR(psaddr, savepsaddr);
                    451:        PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    452:        PSWAIT(psaddr); request = psaddr->ps_data;
                    453:        request = request&0377;
                    454:        psp->ps_lastrequest2 = psp->ps_lastrequest;
                    455:        psp->ps_lastrequest = request;
                    456:        if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) {
                    457:                psp->ps_lastfunnyrequest = request;
                    458:                psp->ps_funnycnt++;
                    459:        }
                    460:        PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    461:        tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */
                    462:        PSWAIT(psaddr); psaddr->ps_data = tmp;
                    463: 
                    464:        if (request & (MOSTOP_REQ|HALT_REQ)) {  /* Map stopped */
                    465:                psp->ps_map.icnt++;
                    466:                psmapstop(psaddr, psp, request);/* kill it dead */
                    467:                if (psp->ps_map.waiting) {
                    468:                        psp->ps_map.waiting = 0;
                    469:                        wakeup(&psp->ps_map.waiting);
                    470:                        if (psp->ps_map.stop) {
                    471:                                psp->ps_map.stop = 0;
                    472:                                goto tryrf;
                    473:                        }
                    474:                }
                    475:                if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) {
                    476:                        psp->ps_map.mcntr = 0;
                    477:                        /* prepare for next round */
                    478:                        pssetmapbounds(psp, psaddr);
                    479:                        if (psp->ps_refresh.state == AUTO_RF) {
                    480:                                if (psp->ps_refresh.mode == WAITING_MAP){
                    481:                                        if (psp->ps_dbuffer.state == ON_DB)
                    482:                                                /* fill other db */
                    483:                                                psdbswitch(psp, psaddr);
                    484:                                        else
                    485:                                                psp->ps_map.mode = WAITING_RF;
                    486: #ifdef EXTERNAL_SYNC
                    487:                                        x = splclock();
                    488: #endif
                    489:                                        (void) psrfnext(psp, psaddr);
                    490: #ifdef EXTERNAL_SYNC
                    491:                                        splx(x);
                    492: #endif
                    493:                                } else
                    494:                                        psp->ps_map.mode = WAITING_RF;
                    495:                        } else {        /* no auto refresh */
                    496:                                if (psp->ps_dbuffer.state == ON_DB)
                    497:                                        /* fill other db */
                    498:                                        psdbswitch(psp, psaddr);
                    499:                                else
                    500:                                        (void) psmapnext(psp, psaddr);
                    501:                        }
                    502:                }
                    503:        }
                    504: tryrf:
                    505:        if (request & RFSTOP_REQ) {             /* Refresh stopped */
                    506:                psp->ps_refresh.icnt++;
                    507:                if (psp->ps_refresh.state == TIME_RF)
                    508:                        if (--psp->ps_refresh.timecnt > 0)
                    509:                                goto tryhit;
                    510:                psrfstop(psaddr, psp);
                    511:                if (psp->ps_refresh.waiting) {
                    512:                        psp->ps_refresh.waiting = 0;
                    513:                        wakeup(&psp->ps_refresh.waiting);
                    514:                        if (psp->ps_refresh.stop) {
                    515:                                psp->ps_refresh.stop = 0;
                    516:                                goto tryhit;
                    517:                        }
                    518:                }
                    519:                if (psp->ps_refresh.state == AUTO_RF)
                    520:                        if (!psrfnext(psp, psaddr)) {   /* at end of refresh cycle */
                    521:                                if (psp->ps_map.state == AUTO_MAP && 
                    522:                                    psp->ps_map.mode == WAITING_RF) {
                    523:                                        if (psp->ps_dbuffer.state == ON_DB)
                    524:                                                psdbswitch(psp, psaddr);
                    525:                                        else
                    526:                                                (void) psmapnext(psp, psaddr);
                    527:                                }
                    528:                                psp->ps_refresh.srcntr = 0;
                    529: #ifdef EXTERNAL_SYNC
                    530:                                x = splclock();
                    531: #endif
                    532:                                psp->ps_refresh.mode = SYNCING_RF;
                    533:                                if (psp->ps_clockticks)
                    534:                                        (void) psrfnext(psp, psaddr);
                    535:                                psp->ps_clockticks = 0;
                    536: #ifdef EXTERNAL_SYNC
                    537:                                splx(x);
                    538: #endif
                    539:                        }
                    540:        }
                    541: tryhit:
                    542:        if (request & HIT_REQ)                  /* Hit request */
                    543:                psp->ps_hitcnt++;
                    544:        if (request == 0)
                    545:                psp->ps_strayintr++;
                    546:        RESTORPSADDR(psaddr, savepsaddr);
                    547: }
                    548: 
                    549: psrfnext(psp, psaddr)
                    550:        register struct ps *psp;
                    551:        register struct psdevice *psaddr;
                    552: {
                    553:        u_short start, last;
                    554: 
                    555:        if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) {
                    556:                psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
                    557:                    0, psp, psaddr);
                    558:                return (1);
                    559:        }
                    560:        if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs &&
                    561:            psp->ps_dbuffer.state == ON_DB) {
                    562:                start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer];
                    563:                last = start+psp->ps_dbuffer.dbsize;
                    564:                psrfstart(start, last, psp, psaddr);
                    565:                psp->ps_refresh.srcntr++;       /* flag for after dbuffer */
                    566:                return (1);
                    567:        }
                    568:        return (0);
                    569: }
                    570: 
                    571: psrfstart(dfaddr, last, psp, psaddr)
                    572:        u_short dfaddr, last;
                    573:        register struct ps *psp;
                    574:        register struct psdevice *psaddr;
                    575: {
                    576:        short dummy;
                    577: 
                    578:        PSWAIT(psaddr); psaddr->ps_addr = RFASA;
                    579:        PSWAIT(psaddr); psaddr->ps_data = dfaddr;
                    580:        PSWAIT(psaddr);
                    581:        if (last != 0)
                    582:                psaddr->ps_data = last;
                    583:        else
                    584:                dummy = psaddr->ps_data;/* just access to get to status reg */
                    585:        PSWAIT(psaddr); psaddr->ps_data = RFSTART;      /* may want | here */
                    586:        psp->ps_refresh.mode = RUNNING_RF;
                    587: }
                    588: 
                    589: /*ARGSUSED*/
                    590: psrfstop(psaddr, psp)
                    591:        register struct psdevice *psaddr;
                    592:        register struct ps *psp;
                    593: {
                    594: 
                    595:        PSWAIT(psaddr); psaddr->ps_addr = RFSR;
                    596:        PSWAIT(psaddr); psaddr->ps_data = 0;
                    597: }
                    598: 
                    599: psdbswitch(psp, psaddr)
                    600:        register struct ps *psp;
                    601:        register struct psdevice *psaddr;
                    602: {
                    603: 
                    604:        psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
                    605:        pssetmapbounds(psp, psaddr);
                    606:        (void) psmapnext(psp, psaddr);
                    607: }
                    608: 
                    609: psmapnext(psp, psaddr)
                    610:        register struct ps *psp;
                    611:        register struct psdevice *psaddr;
                    612: {
                    613: 
                    614:        if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) {
                    615:                psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++],
                    616:                    psp, psaddr);
                    617:                return (1);
                    618:        }
                    619:        return (0);
                    620: }
                    621: 
                    622: pssetmapbounds(psp, psaddr)
                    623:        register struct ps *psp;
                    624:        register struct psdevice *psaddr;
                    625: {
                    626:        u_short start, last;
                    627: 
                    628:        PSWAIT(psaddr); psaddr->ps_addr = MAOL;
                    629:        PSWAIT(psaddr);
                    630:        if (psp->ps_dbuffer.state == ON_DB) {
                    631:                start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer];
                    632:                last = start+psp->ps_dbuffer.dbsize-2;   /* 2 for halt cmd */
                    633:                psaddr->ps_data = last;
                    634:                PSWAIT(psaddr); psaddr->ps_data = start;
                    635:        } else {
                    636:                start = psaddr->ps_data;        /* dummy: don't update limit */
                    637:                PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart;
                    638:        }
                    639: }
                    640: 
                    641: psmapstart(dfaddr, psp, psaddr)
                    642:        u_short dfaddr;
                    643:        register struct ps *psp;
                    644:        register struct psdevice *psaddr;
                    645: {
                    646: 
                    647:        PSWAIT(psaddr); psaddr->ps_addr = MAIA;
                    648:        PSWAIT(psaddr); psaddr->ps_data = dfaddr;
                    649:        PSWAIT(psaddr); psaddr->ps_data = MAO|MAI;      /* may want more here */
                    650:        psp->ps_map.mode = RUNNING_MAP;
                    651: }
                    652: 
                    653: int pskillcnt = 1;
                    654: 
                    655: psmapstop(psaddr, psp, request)
                    656:        register struct psdevice *psaddr;
                    657:        register struct ps *psp;
                    658:        short request;
                    659: {
                    660:        register int i;
                    661: 
                    662:        request &= HALT_REQ|MOSTOP_REQ;         /* overkill?? */
                    663:        for (i = 0; i < pskillcnt; i++) {
                    664:                PSWAIT(psaddr); psaddr->ps_addr = MASR;
                    665:                PSWAIT(psaddr); psaddr->ps_data = IOUT; /* zero MAI & MAO */
                    666:                PSWAIT(psaddr); psaddr->ps_addr = MAIA;
                    667:                PSWAIT(psaddr); psaddr->ps_data = 0;    /* 0 input addr reg */
                    668:                PSWAIT(psaddr); psaddr->ps_addr = MAOA;
                    669:                PSWAIT(psaddr); psaddr->ps_data = 0;    /* 0 output addr reg */
                    670:                PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    671:                PSWAIT(psaddr); psaddr->ps_data = request;
                    672:        }
                    673:        psp->ps_map.mode = STOPPED_MAP;
                    674: }
                    675: 
                    676: /*ARGSUSED*/
                    677: psdeviceintr(dev)
                    678:        dev_t dev;
                    679: {
                    680: 
                    681:        printf("ps device intr\n");
                    682: }
                    683: 
                    684: /*ARGSUSED*/
                    685: psdmaintr(dev)
                    686:        dev_t dev;
                    687: {
                    688: 
                    689:        printf("ps dma intr\n");
                    690: }
                    691: 
                    692: /*ARGSUSED*/
                    693: psreset(uban)
                    694:        int uban;
                    695: {
                    696: 
                    697: }
                    698: 
                    699: /*ARGSUSED*/
                    700: psextsync(PC, PS)
                    701: {
                    702:        register int n;
                    703:        register struct psdevice *psaddr;
                    704:        register struct ps *psp;
                    705:        register int savepsaddr;
                    706: 
                    707: #ifdef EXTERNAL_SYNC
                    708:        for (psp = ps, n = 0; n < NPS; psp++, n++) {
                    709:                if (!psp->ps_open)
                    710:                        continue;
                    711:                if (psp->ps_refresh.mode == SYNCING_RF &&
                    712:                    psp->ps_refresh.state != TIME_RF) {
                    713:                        psaddr = (struct psdevice *)psdinfo[n]->ui_addr;
                    714:                        SAVEPSADDR(psaddr, savepsaddr);
                    715:                        (void) psrfnext(psp, psaddr);
                    716:                        RESTORPSADDR(psaddr, savepsaddr);
                    717:                } else {
                    718:                        psp->ps_clockticks++;
                    719:                        psp->ps_clockmiss++;
                    720:                }
                    721:        }
                    722: #endif
                    723: }
                    724: #endif

unix.superglobalmegacorp.com

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