Annotation of Net2/arch/vax/uba/ps.c, revision 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.