Annotation of 43BSDReno/sys/vaxuba/ps.c, revision 1.1.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.5 (Berkeley) 4/3/90
                      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 "user.h"
                     32: #include "uio.h"
                     33: 
                     34: #include "ubareg.h"
                     35: #include "ubavar.h"
                     36: #include "psreg.h"
                     37: 
                     38: int    psprobe(), psattach(), psextsync();
                     39: int    psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();
                     40: struct uba_device *psdinfo[NPS];
                     41: u_short        psstd[] = { 0 };
                     42: struct uba_driver psdriver = 
                     43:     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
                     44: 
                     45: #define        PSUNIT(dev)     (minor(dev))
                     46: 
                     47: #define MAXAUTOREFRESH 4
                     48: #define MAXAUTOMAP     4
                     49: #define MAXDBSIZE      (0177777/2)
                     50: 
                     51: #define PSPRI          (PZERO+1)
                     52: 
                     53: #define PSWAIT(psaddr) { \
                     54:        register short i = 20000, j; \
                     55:        while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \
                     56:                ;\
                     57: }
                     58: 
                     59: struct psrefresh {
                     60:        enum {
                     61:                SINGLE_STEP_RF,
                     62:                AUTO_RF,
                     63:                TIME_RF
                     64:        } state;
                     65:        enum {
                     66:                RUNNING_RF,
                     67:                SYNCING_RF,
                     68:                WAITING_MAP,
                     69:                STOPPED_RF
                     70:        } mode;
                     71:        u_short sraddrs[MAXAUTOREFRESH];
                     72:        short   nsraddrs;
                     73:        short   srcntr;
                     74:        char    waiting;
                     75:        char    stop;
                     76:        int     icnt;
                     77:        int     timecnt;
                     78: };
                     79: 
                     80: struct psdbuffer {
                     81:        enum {
                     82:                ON_DB,
                     83:                OFF_DB
                     84:        } state;
                     85:        u_short dbaddrs[2];
                     86:        u_short dbsize;
                     87:        short   rbuffer;
                     88: };
                     89: 
                     90: struct psmap {
                     91:        enum {
                     92:                SINGLE_STEP_MAP,
                     93:                AUTO_MAP
                     94:        } state;
                     95:        enum {
                     96:                RUNNING_MAP,
                     97:                WAITING_RF,
                     98:                WAITING_START,
                     99:                STOPPED_MAP
                    100:        } mode;
                    101:        u_short maddrs[MAXAUTOMAP];
                    102:        short   nmaddrs;
                    103:        short   mcntr;
                    104:        short   outputstart;
                    105:        char    waiting;
                    106:        char    stop;
                    107:        int     icnt;
                    108: };
                    109: 
                    110: /*
                    111:  * PS2 software state.
                    112:  */
                    113: struct ps {
                    114:        char    ps_open;                /* device is open */
                    115:        uid_t   ps_uid;                 /* uid of device owner */
                    116:        struct  psrefresh ps_refresh;   /* refresh state */
                    117:        struct  psdbuffer ps_dbuffer;   /* double buffering state */
                    118:        struct  psmap ps_map;           /* segment map state */
                    119:        int     ps_clockticks;          /* clock ints between refresh */
                    120:        int     ps_clockmiss;           /* clock ints w/o refresh */
                    121:        int     ps_clockcnt;            /* count of clock interrupts */
                    122:        int     ps_hitcnt;              /* count of hit interrupts */
                    123:        int     ps_strayintr;           /* count of stray interrupts */
                    124:        int     ps_icnt;                /* count of system interrupts */
                    125: /* BEGIN GROT */
                    126:        int     ps_lastrequest;
                    127:        int     ps_lastrequest2;
                    128:        int     ps_lastfunnyrequest;
                    129:        int     ps_funnycnt;
                    130: /* END GROT */
                    131: } ps[NPS];
                    132: 
                    133: psprobe(reg)
                    134:        caddr_t reg;
                    135: {
                    136:        register int br, cvec;
                    137:        register struct psdevice *psaddr = (struct psdevice *)reg;
                    138: 
                    139: #ifdef lint
                    140:        br = 0; cvec = br; br = cvec;
                    141:        psclockintr((dev_t)0); pssystemintr((dev_t)0);
                    142:        psdeviceintr((dev_t)0); psdmaintr((dev_t)0);
                    143:        psextsync(0, 0);
                    144: #endif
                    145:        psaddr->ps_iostat = PSRESET;
                    146:        DELAY(200);
                    147:        psaddr->ps_addr = RTCIE;
                    148:        PSWAIT(psaddr); psaddr->ps_data = 01;
                    149:        psaddr->ps_iostat = PSIE;
                    150:        psaddr->ps_addr = RTCSR;
                    151:        PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN;
                    152:        DELAY(200000);
                    153:        psaddr->ps_addr = RTCREQ;
                    154:        PSWAIT(psaddr); psaddr->ps_data = 01;
                    155:        psaddr->ps_iostat = 0;
                    156:        psaddr->ps_iostat = PSRESET;
                    157:        return (sizeof (struct psdevice));
                    158: }
                    159: 
                    160: /*ARGSUSED*/
                    161: psattach(ui)
                    162:        struct uba_device *ui;
                    163: {
                    164: 
                    165: }
                    166: 
                    167: psopen(dev)
                    168:        dev_t dev;
                    169: {
                    170:        register struct ps *psp;
                    171:        register struct uba_device *ui;
                    172:        register int unit = PSUNIT(dev);
                    173: 
                    174:        if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
                    175:            (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
                    176:                return (ENXIO);
                    177:        psp->ps_open = 1;
                    178:        psp->ps_uid = u.u_uid;
                    179:        psp->ps_strayintr = 0;
                    180:        psp->ps_refresh.state = SINGLE_STEP_RF;
                    181:        psp->ps_refresh.mode = STOPPED_RF;
                    182:        psp->ps_refresh.waiting = 0;
                    183:        psp->ps_refresh.stop = 0;
                    184:        psp->ps_dbuffer.state = OFF_DB;
                    185:        psp->ps_map.state = SINGLE_STEP_MAP;
                    186:        psp->ps_map.mode = STOPPED_MAP;
                    187:        psp->ps_map.waiting = 0;
                    188:        psp->ps_map.stop = 0;
                    189:        psp->ps_clockticks = 0;
                    190:        psp->ps_clockmiss = 0;
                    191:        psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0;
                    192:        psp->ps_hitcnt = 0;
                    193:        psp->ps_icnt = 0;
                    194:        maptouser(ui->ui_addr);
                    195:        return (0);
                    196: }
                    197: 
                    198: psclose(dev)
                    199:        dev_t dev;
                    200: {
                    201:        register struct psdevice *psaddr = 
                    202:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    203: 
                    204:        ps[PSUNIT(dev)].ps_open = 0;
                    205:        psaddr->ps_iostat = 0;                   /* clear IENABLE */
                    206:        PSWAIT(psaddr); psaddr->ps_addr = RFSR;  /* set in auto refresh mode */
                    207:        PSWAIT(psaddr); psaddr->ps_data = AUTOREF;
                    208:        unmaptouser((caddr_t)psaddr);
                    209:        return (0);
                    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, error = 0;
                    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:                        if (error = tsleep(&psp->ps_refresh.waiting,
                    329:                            PSPRI | PCATCH, devwait, 0))
                    330:                                break;
                    331:                (void) spl0();
                    332:                if (error)
                    333:                        return (error);
                    334:                if (cmd == PSIOSTOPREFRESH)
                    335:                        psp->ps_refresh.mode = STOPPED_RF;
                    336:                if (psp->ps_refresh.state == TIME_RF)
                    337:                        psp->ps_refresh.state = SINGLE_STEP_RF;
                    338:                break;
                    339: 
                    340:        case PSIOWAITMAP:
                    341:                if (psp->ps_map.mode != RUNNING_MAP)    /* not running */
                    342:                        return (0);                     /* dont wait */
                    343:                /* fall into ... */
                    344: 
                    345:        case PSIOSTOPMAP:
                    346:                if (cmd == PSIOSTOPMAP)
                    347:                        psp->ps_map.stop = 1;
                    348:                (void) spl5();
                    349:                psp->ps_map.waiting = 1;
                    350:                while (psp->ps_map.waiting)
                    351:                        if (error = tsleep(&psp->ps_map.waiting, PSPRI | PCATCH,
                    352:                            devwait, 0))
                    353:                                break;
                    354:                (void) spl0();
                    355:                break;
                    356: 
                    357:        default:
                    358:                return (ENOTTY);
                    359:                break;
                    360:        }
                    361:        return (error);
                    362: }
                    363: 
                    364: #define SAVEPSADDR(psaddr, savepsaddr) { \
                    365:        register short i, xx1; \
                    366:        xx1 = splclock(); \
                    367:        i = psaddr->ps_addr; \
                    368:        while ((psaddr->ps_iostat & DIOREADY) == 0) \
                    369:                ; \
                    370:        savepsaddr = psaddr->ps_data; \
                    371:        splx(xx1); \
                    372: }
                    373: #define RESTORPSADDR(psaddr, savepsaddr) { \
                    374:        register short xx2; \
                    375:        xx2 = splclock(); \
                    376:        while ((psaddr->ps_iostat & DIOREADY) == 0) \
                    377:                ;\
                    378:        psaddr->ps_addr = savepsaddr; \
                    379:        splx(xx2); \
                    380: }
                    381: 
                    382: psclockintr(dev)
                    383:        dev_t dev;
                    384: {
                    385:        register struct psdevice *psaddr =
                    386:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    387:        register struct ps *psp = &ps[PSUNIT(dev)];
                    388:        int savepsaddr;
                    389: 
                    390:        if (!psp->ps_open)
                    391:                return;
                    392:        psp->ps_clockcnt++;
                    393:        SAVEPSADDR(psaddr, savepsaddr);
                    394: #ifndef EXTERNAL_SYNC
                    395:        if (psp->ps_refresh.state == AUTO_RF) {
                    396:                if (psp->ps_refresh.mode == SYNCING_RF &&
                    397:                    psp->ps_refresh.state != TIME_RF) {
                    398:                        (void) psrfnext(psp, psaddr);
                    399:                } else {
                    400:                        psp->ps_clockticks++;
                    401:                        psp->ps_clockmiss++;
                    402:                }
                    403:        }
                    404: #endif
                    405:        PSWAIT(psaddr); psaddr->ps_addr = RTCREQ;
                    406:        PSWAIT(psaddr); psaddr->ps_data = 01;   /* clear the request bits */
                    407:        RESTORPSADDR(psaddr, savepsaddr);
                    408: }
                    409: 
                    410: /*ARGSUSED*/
                    411: pssystemintr(dev)
                    412:        dev_t dev;
                    413: {
                    414:        register struct psdevice *psaddr =
                    415:            (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
                    416:        register struct ps *psp = &ps[PSUNIT(dev)];
                    417:        short request, tmp;
                    418:        register int savepsaddr, x;
                    419: 
                    420:        if (!psp->ps_open)
                    421:                return;
                    422:        psp->ps_icnt++;
                    423:        SAVEPSADDR(psaddr, savepsaddr);
                    424:        PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    425:        PSWAIT(psaddr); request = psaddr->ps_data;
                    426:        request = request&0377;
                    427:        psp->ps_lastrequest2 = psp->ps_lastrequest;
                    428:        psp->ps_lastrequest = request;
                    429:        if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) {
                    430:                psp->ps_lastfunnyrequest = request;
                    431:                psp->ps_funnycnt++;
                    432:        }
                    433:        PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    434:        tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */
                    435:        PSWAIT(psaddr); psaddr->ps_data = tmp;
                    436: 
                    437:        if (request & (MOSTOP_REQ|HALT_REQ)) {  /* Map stopped */
                    438:                psp->ps_map.icnt++;
                    439:                psmapstop(psaddr, psp, request);/* kill it dead */
                    440:                if (psp->ps_map.waiting) {
                    441:                        psp->ps_map.waiting = 0;
                    442:                        wakeup(&psp->ps_map.waiting);
                    443:                        if (psp->ps_map.stop) {
                    444:                                psp->ps_map.stop = 0;
                    445:                                goto tryrf;
                    446:                        }
                    447:                }
                    448:                if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) {
                    449:                        psp->ps_map.mcntr = 0;
                    450:                        /* prepare for next round */
                    451:                        pssetmapbounds(psp, psaddr);
                    452:                        if (psp->ps_refresh.state == AUTO_RF) {
                    453:                                if (psp->ps_refresh.mode == WAITING_MAP){
                    454:                                        if (psp->ps_dbuffer.state == ON_DB)
                    455:                                                /* fill other db */
                    456:                                                psdbswitch(psp, psaddr);
                    457:                                        else
                    458:                                                psp->ps_map.mode = WAITING_RF;
                    459: #ifdef EXTERNAL_SYNC
                    460:                                        x = splclock();
                    461: #endif
                    462:                                        (void) psrfnext(psp, psaddr);
                    463: #ifdef EXTERNAL_SYNC
                    464:                                        splx(x);
                    465: #endif
                    466:                                } else
                    467:                                        psp->ps_map.mode = WAITING_RF;
                    468:                        } else {        /* no auto refresh */
                    469:                                if (psp->ps_dbuffer.state == ON_DB)
                    470:                                        /* fill other db */
                    471:                                        psdbswitch(psp, psaddr);
                    472:                                else
                    473:                                        (void) psmapnext(psp, psaddr);
                    474:                        }
                    475:                }
                    476:        }
                    477: tryrf:
                    478:        if (request & RFSTOP_REQ) {             /* Refresh stopped */
                    479:                psp->ps_refresh.icnt++;
                    480:                if (psp->ps_refresh.state == TIME_RF)
                    481:                        if (--psp->ps_refresh.timecnt > 0)
                    482:                                goto tryhit;
                    483:                psrfstop(psaddr, psp);
                    484:                if (psp->ps_refresh.waiting) {
                    485:                        psp->ps_refresh.waiting = 0;
                    486:                        wakeup(&psp->ps_refresh.waiting);
                    487:                        if (psp->ps_refresh.stop) {
                    488:                                psp->ps_refresh.stop = 0;
                    489:                                goto tryhit;
                    490:                        }
                    491:                }
                    492:                if (psp->ps_refresh.state == AUTO_RF)
                    493:                        if (!psrfnext(psp, psaddr)) {   /* at end of refresh cycle */
                    494:                                if (psp->ps_map.state == AUTO_MAP && 
                    495:                                    psp->ps_map.mode == WAITING_RF) {
                    496:                                        if (psp->ps_dbuffer.state == ON_DB)
                    497:                                                psdbswitch(psp, psaddr);
                    498:                                        else
                    499:                                                (void) psmapnext(psp, psaddr);
                    500:                                }
                    501:                                psp->ps_refresh.srcntr = 0;
                    502: #ifdef EXTERNAL_SYNC
                    503:                                x = splclock();
                    504: #endif
                    505:                                psp->ps_refresh.mode = SYNCING_RF;
                    506:                                if (psp->ps_clockticks)
                    507:                                        (void) psrfnext(psp, psaddr);
                    508:                                psp->ps_clockticks = 0;
                    509: #ifdef EXTERNAL_SYNC
                    510:                                splx(x);
                    511: #endif
                    512:                        }
                    513:        }
                    514: tryhit:
                    515:        if (request & HIT_REQ)                  /* Hit request */
                    516:                psp->ps_hitcnt++;
                    517:        if (request == 0)
                    518:                psp->ps_strayintr++;
                    519:        RESTORPSADDR(psaddr, savepsaddr);
                    520: }
                    521: 
                    522: psrfnext(psp, psaddr)
                    523:        register struct ps *psp;
                    524:        register struct psdevice *psaddr;
                    525: {
                    526:        u_short start, last;
                    527: 
                    528:        if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) {
                    529:                psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
                    530:                    0, psp, psaddr);
                    531:                return (1);
                    532:        }
                    533:        if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs &&
                    534:            psp->ps_dbuffer.state == ON_DB) {
                    535:                start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer];
                    536:                last = start+psp->ps_dbuffer.dbsize;
                    537:                psrfstart(start, last, psp, psaddr);
                    538:                psp->ps_refresh.srcntr++;       /* flag for after dbuffer */
                    539:                return (1);
                    540:        }
                    541:        return (0);
                    542: }
                    543: 
                    544: psrfstart(dfaddr, last, psp, psaddr)
                    545:        u_short dfaddr, last;
                    546:        register struct ps *psp;
                    547:        register struct psdevice *psaddr;
                    548: {
                    549:        short dummy;
                    550: 
                    551:        PSWAIT(psaddr); psaddr->ps_addr = RFASA;
                    552:        PSWAIT(psaddr); psaddr->ps_data = dfaddr;
                    553:        PSWAIT(psaddr);
                    554:        if (last != 0)
                    555:                psaddr->ps_data = last;
                    556:        else
                    557:                dummy = psaddr->ps_data;/* just access to get to status reg */
                    558:        PSWAIT(psaddr); psaddr->ps_data = RFSTART;      /* may want | here */
                    559:        psp->ps_refresh.mode = RUNNING_RF;
                    560: }
                    561: 
                    562: /*ARGSUSED*/
                    563: psrfstop(psaddr, psp)
                    564:        register struct psdevice *psaddr;
                    565:        register struct ps *psp;
                    566: {
                    567: 
                    568:        PSWAIT(psaddr); psaddr->ps_addr = RFSR;
                    569:        PSWAIT(psaddr); psaddr->ps_data = 0;
                    570: }
                    571: 
                    572: psdbswitch(psp, psaddr)
                    573:        register struct ps *psp;
                    574:        register struct psdevice *psaddr;
                    575: {
                    576: 
                    577:        psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
                    578:        pssetmapbounds(psp, psaddr);
                    579:        (void) psmapnext(psp, psaddr);
                    580: }
                    581: 
                    582: psmapnext(psp, psaddr)
                    583:        register struct ps *psp;
                    584:        register struct psdevice *psaddr;
                    585: {
                    586: 
                    587:        if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) {
                    588:                psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++],
                    589:                    psp, psaddr);
                    590:                return (1);
                    591:        }
                    592:        return (0);
                    593: }
                    594: 
                    595: pssetmapbounds(psp, psaddr)
                    596:        register struct ps *psp;
                    597:        register struct psdevice *psaddr;
                    598: {
                    599:        u_short start, last;
                    600: 
                    601:        PSWAIT(psaddr); psaddr->ps_addr = MAOL;
                    602:        PSWAIT(psaddr);
                    603:        if (psp->ps_dbuffer.state == ON_DB) {
                    604:                start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer];
                    605:                last = start+psp->ps_dbuffer.dbsize-2;   /* 2 for halt cmd */
                    606:                psaddr->ps_data = last;
                    607:                PSWAIT(psaddr); psaddr->ps_data = start;
                    608:        } else {
                    609:                start = psaddr->ps_data;        /* dummy: don't update limit */
                    610:                PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart;
                    611:        }
                    612: }
                    613: 
                    614: psmapstart(dfaddr, psp, psaddr)
                    615:        u_short dfaddr;
                    616:        register struct ps *psp;
                    617:        register struct psdevice *psaddr;
                    618: {
                    619: 
                    620:        PSWAIT(psaddr); psaddr->ps_addr = MAIA;
                    621:        PSWAIT(psaddr); psaddr->ps_data = dfaddr;
                    622:        PSWAIT(psaddr); psaddr->ps_data = MAO|MAI;      /* may want more here */
                    623:        psp->ps_map.mode = RUNNING_MAP;
                    624: }
                    625: 
                    626: int pskillcnt = 1;
                    627: 
                    628: psmapstop(psaddr, psp, request)
                    629:        register struct psdevice *psaddr;
                    630:        register struct ps *psp;
                    631:        short request;
                    632: {
                    633:        register int i;
                    634: 
                    635:        request &= HALT_REQ|MOSTOP_REQ;         /* overkill?? */
                    636:        for (i = 0; i < pskillcnt; i++) {
                    637:                PSWAIT(psaddr); psaddr->ps_addr = MASR;
                    638:                PSWAIT(psaddr); psaddr->ps_data = IOUT; /* zero MAI & MAO */
                    639:                PSWAIT(psaddr); psaddr->ps_addr = MAIA;
                    640:                PSWAIT(psaddr); psaddr->ps_data = 0;    /* 0 input addr reg */
                    641:                PSWAIT(psaddr); psaddr->ps_addr = MAOA;
                    642:                PSWAIT(psaddr); psaddr->ps_data = 0;    /* 0 output addr reg */
                    643:                PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
                    644:                PSWAIT(psaddr); psaddr->ps_data = request;
                    645:        }
                    646:        psp->ps_map.mode = STOPPED_MAP;
                    647: }
                    648: 
                    649: /*ARGSUSED*/
                    650: psdeviceintr(dev)
                    651:        dev_t dev;
                    652: {
                    653: 
                    654:        printf("ps device intr\n");
                    655: }
                    656: 
                    657: /*ARGSUSED*/
                    658: psdmaintr(dev)
                    659:        dev_t dev;
                    660: {
                    661: 
                    662:        printf("ps dma intr\n");
                    663: }
                    664: 
                    665: /*ARGSUSED*/
                    666: psreset(uban)
                    667:        int uban;
                    668: {
                    669: 
                    670: }
                    671: 
                    672: /*ARGSUSED*/
                    673: psextsync(PC, PS)
                    674: {
                    675:        register int n;
                    676:        register struct psdevice *psaddr;
                    677:        register struct ps *psp;
                    678:        register int savepsaddr;
                    679: 
                    680: #ifdef EXTERNAL_SYNC
                    681:        for (psp = ps, n = 0; n < NPS; psp++, n++) {
                    682:                if (!psp->ps_open)
                    683:                        continue;
                    684:                if (psp->ps_refresh.mode == SYNCING_RF &&
                    685:                    psp->ps_refresh.state != TIME_RF) {
                    686:                        psaddr = (struct psdevice *)psdinfo[n]->ui_addr;
                    687:                        SAVEPSADDR(psaddr, savepsaddr);
                    688:                        (void) psrfnext(psp, psaddr);
                    689:                        RESTORPSADDR(psaddr, savepsaddr);
                    690:                } else {
                    691:                        psp->ps_clockticks++;
                    692:                        psp->ps_clockmiss++;
                    693:                }
                    694:        }
                    695: #endif
                    696: }
                    697: #endif

unix.superglobalmegacorp.com

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