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