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