Annotation of 43BSDTahoe/sys/vaxuba/ps.c, revision 1.1

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

unix.superglobalmegacorp.com

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