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) 04/03/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 698