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

Defined functions

psattach defined in line 162; used 2 times
psclockintr defined in line 376; used 2 times
psclose defined in line 199; never used
psdbswitch defined in line 566; used 3 times
psdeviceintr defined in line 644; used 2 times
psdmaintr defined in line 652; used 2 times
psextsync defined in line 667; used 3 times
psioctl defined in line 227; never used
psmapnext defined in line 576; used 4 times
psmapstart defined in line 608; used 1 times
psmapstop defined in line 622; used 1 times
psopen defined in line 168; never used
psprobe defined in line 134; used 2 times
psread defined in line 213; never used
psreset defined in line 660; never used
psrfnext defined in line 516; used 5 times
psrfstart defined in line 538; used 2 times
psrfstop defined in line 557; used 1 times
pssetmapbounds defined in line 589; used 2 times
pssystemintr defined in line 405; used 2 times
pswrite defined in line 220; never used

Defined variables

ps defined in line 132; used 6 times
psdinfo defined in line 41; used 7 times
psdriver defined in line 43; never used
pskillcnt defined in line 620; used 1 times
psstd defined in line 42; used 1 times
  • in line 44

Defined struct's

ps defined in line 114; used 26 times
psdbuffer defined in line 81; used 2 times
  • in line 118(2)
psmap defined in line 91; used 2 times
  • in line 119(2)
psrefresh defined in line 60; used 2 times
  • in line 117(2)

Defined macros

EXTERNAL_SYNC defined in line 21; used 6 times
MAXAUTOMAP defined in line 49; used 2 times
MAXAUTOREFRESH defined in line 48; used 2 times
MAXDBSIZE defined in line 50; used 1 times
PSPRI defined in line 52; used 2 times
PSUNIT defined in line 46; used 9 times
PSWAIT defined in line 54; used 32 times
RESTORPSADDR defined in line 367; used 3 times
SAVEPSADDR defined in line 358; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2632
Valid CSS Valid XHTML 1.0 Strict