Annotation of 43BSD/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.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.