|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.