1 /*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ps.c 7.7 (Berkeley) 05/09/91 8 */ 9 10 /* 11 * Evans and Sutherland Picture System 2 driver -- Bill Reeves. 12 */ 13 14 /* 15 * Still to be done: 16 * WAIT_HIT 17 */ 18 19 #include "ps.h" 20 #if NPS > 0 21 22 #define EXTERNAL_SYNC 23 24 #include "../include/pte.h" 25 26 #include "sys/param.h" 27 #include "sys/systm.h" 28 #include "sys/ioctl.h" 29 #include "sys/map.h" 30 #include "sys/buf.h" 31 #include "sys/conf.h" 32 #include "sys/user.h" 33 #include "sys/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 return (0); 211 } 212 213 /*ARGSUSED*/ 214 psread(dev, uio) 215 dev_t dev; 216 struct uio *uio; 217 { 218 } 219 220 /*ARGSUSED*/ 221 pswrite(dev, uio) 222 dev_t dev; 223 struct uio *uio; 224 { 225 } 226 227 /*ARGSUSED*/ 228 psioctl(dev, cmd, data, flag) 229 register caddr_t data; 230 { 231 register struct uba_device *ui = psdinfo[PSUNIT(dev)]; 232 register struct ps *psp = &ps[PSUNIT(dev)]; 233 int *waddr = *(int **)data; 234 int n, arg, i, error = 0; 235 236 switch (cmd) { 237 238 case PSIOGETADDR: 239 *(caddr_t *)data = ui->ui_addr; 240 break; 241 242 case PSIOAUTOREFRESH: 243 n = fuword((caddr_t)waddr++); 244 if (n == -1) 245 return (EFAULT); 246 if (n < 0 || n > MAXAUTOREFRESH) 247 return (EINVAL); 248 for (i = 0; i < n; i++) { 249 if ((arg = fuword((caddr_t)waddr++)) == -1) 250 return (EFAULT); 251 psp->ps_refresh.sraddrs[i] = arg; 252 } 253 psp->ps_refresh.state = AUTO_RF; 254 psp->ps_refresh.nsraddrs = n; 255 psp->ps_refresh.srcntr = 0; 256 psp->ps_refresh.mode = WAITING_MAP; 257 break; 258 259 case PSIOAUTOMAP: 260 n = fuword((caddr_t)waddr++); 261 if (n == -1) 262 return (EFAULT); 263 if (n < 0 || n > MAXAUTOMAP) 264 return (EINVAL); 265 for (i = 0; i < n; i++) { 266 if ((arg = fuword((caddr_t)waddr++)) == -1) 267 return (EFAULT); 268 psp->ps_map.maddrs[i] = arg; 269 } 270 if ((arg = fuword((caddr_t)waddr++)) == -1) 271 return (EFAULT); 272 psp->ps_map.outputstart = arg; 273 psp->ps_map.state = AUTO_MAP; 274 psp->ps_map.nmaddrs = n; 275 psp->ps_map.mcntr = 0; 276 psp->ps_map.mode = WAITING_START; 277 break; 278 279 case PSIOSINGLEREFRESH: 280 psp->ps_refresh.state = SINGLE_STEP_RF; 281 break; 282 283 case PSIOSINGLEMAP: 284 psp->ps_map.state = SINGLE_STEP_MAP; 285 break; 286 287 case PSIODOUBLEBUFFER: 288 if ((arg = fuword((caddr_t)waddr++)) == -1) 289 return (EFAULT); 290 psp->ps_dbuffer.dbaddrs[0] = arg; 291 if ((arg = fuword((caddr_t)waddr++)) == -1) 292 return (EFAULT); 293 if (arg <= 0 || arg > MAXDBSIZE) 294 return (EINVAL); 295 psp->ps_dbuffer.dbsize = arg; 296 psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg; 297 psp->ps_dbuffer.state = ON_DB; 298 psp->ps_dbuffer.rbuffer = 0; 299 break; 300 301 case PSIOSINGLEBUFFER: 302 psp->ps_dbuffer.state = OFF_DB; 303 break; 304 305 case PSIOTIMEREFRESH: 306 if (psp->ps_refresh.state != SINGLE_STEP_RF) 307 return (EINVAL); 308 if ((arg = fuword((caddr_t)waddr++)) == -1) 309 return (EFAULT); 310 psp->ps_refresh.state = TIME_RF; 311 psp->ps_refresh.timecnt = arg; 312 break; 313 314 case PSIOWAITREFRESH: 315 if (psp->ps_refresh.mode != RUNNING_RF) /* not running */ 316 return (0); /* dont wait */ 317 /* fall into ... */ 318 319 case PSIOSTOPREFRESH: 320 if (cmd == PSIOSTOPREFRESH) { 321 if (psp->ps_refresh.mode == STOPPED_RF && 322 psp->ps_refresh.state != TIME_RF) 323 return (0); 324 psp->ps_refresh.stop = 1; 325 } 326 (void) spl5(); 327 psp->ps_refresh.waiting = 1; 328 while (psp->ps_refresh.waiting) 329 if (error = tsleep(&psp->ps_refresh.waiting, 330 PSPRI | PCATCH, devwait, 0)) 331 break; 332 (void) spl0(); 333 if (error) 334 return (error); 335 if (cmd == PSIOSTOPREFRESH) 336 psp->ps_refresh.mode = STOPPED_RF; 337 if (psp->ps_refresh.state == TIME_RF) 338 psp->ps_refresh.state = SINGLE_STEP_RF; 339 break; 340 341 case PSIOWAITMAP: 342 if (psp->ps_map.mode != RUNNING_MAP) /* not running */ 343 return (0); /* dont wait */ 344 /* fall into ... */ 345 346 case PSIOSTOPMAP: 347 if (cmd == PSIOSTOPMAP) 348 psp->ps_map.stop = 1; 349 (void) spl5(); 350 psp->ps_map.waiting = 1; 351 while (psp->ps_map.waiting) 352 if (error = tsleep(&psp->ps_map.waiting, PSPRI | PCATCH, 353 devwait, 0)) 354 break; 355 (void) spl0(); 356 break; 357 358 default: 359 return (ENOTTY); 360 break; 361 } 362 return (error); 363 } 364 365 #define SAVEPSADDR(psaddr, savepsaddr) { \ 366 register short i, xx1; \ 367 xx1 = splclock(); \ 368 i = psaddr->ps_addr; \ 369 while ((psaddr->ps_iostat & DIOREADY) == 0) \ 370 ; \ 371 savepsaddr = psaddr->ps_data; \ 372 splx(xx1); \ 373 } 374 #define RESTORPSADDR(psaddr, savepsaddr) { \ 375 register short xx2; \ 376 xx2 = splclock(); \ 377 while ((psaddr->ps_iostat & DIOREADY) == 0) \ 378 ;\ 379 psaddr->ps_addr = savepsaddr; \ 380 splx(xx2); \ 381 } 382 383 psclockintr(dev) 384 dev_t dev; 385 { 386 register struct psdevice *psaddr = 387 (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr; 388 register struct ps *psp = &ps[PSUNIT(dev)]; 389 int savepsaddr; 390 391 if (!psp->ps_open) 392 return; 393 psp->ps_clockcnt++; 394 SAVEPSADDR(psaddr, savepsaddr); 395 #ifndef EXTERNAL_SYNC 396 if (psp->ps_refresh.state == AUTO_RF) { 397 if (psp->ps_refresh.mode == SYNCING_RF && 398 psp->ps_refresh.state != TIME_RF) { 399 (void) psrfnext(psp, psaddr); 400 } else { 401 psp->ps_clockticks++; 402 psp->ps_clockmiss++; 403 } 404 } 405 #endif 406 PSWAIT(psaddr); psaddr->ps_addr = RTCREQ; 407 PSWAIT(psaddr); psaddr->ps_data = 01; /* clear the request bits */ 408 RESTORPSADDR(psaddr, savepsaddr); 409 } 410 411 /*ARGSUSED*/ 412 pssystemintr(dev) 413 dev_t dev; 414 { 415 register struct psdevice *psaddr = 416 (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr; 417 register struct ps *psp = &ps[PSUNIT(dev)]; 418 short request, tmp; 419 register int savepsaddr, x; 420 421 if (!psp->ps_open) 422 return; 423 psp->ps_icnt++; 424 SAVEPSADDR(psaddr, savepsaddr); 425 PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; 426 PSWAIT(psaddr); request = psaddr->ps_data; 427 request = request&0377; 428 psp->ps_lastrequest2 = psp->ps_lastrequest; 429 psp->ps_lastrequest = request; 430 if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) { 431 psp->ps_lastfunnyrequest = request; 432 psp->ps_funnycnt++; 433 } 434 PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; 435 tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */ 436 PSWAIT(psaddr); psaddr->ps_data = tmp; 437 438 if (request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */ 439 psp->ps_map.icnt++; 440 psmapstop(psaddr, psp, request);/* kill it dead */ 441 if (psp->ps_map.waiting) { 442 psp->ps_map.waiting = 0; 443 wakeup(&psp->ps_map.waiting); 444 if (psp->ps_map.stop) { 445 psp->ps_map.stop = 0; 446 goto tryrf; 447 } 448 } 449 if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) { 450 psp->ps_map.mcntr = 0; 451 /* prepare for next round */ 452 pssetmapbounds(psp, psaddr); 453 if (psp->ps_refresh.state == AUTO_RF) { 454 if (psp->ps_refresh.mode == WAITING_MAP){ 455 if (psp->ps_dbuffer.state == ON_DB) 456 /* fill other db */ 457 psdbswitch(psp, psaddr); 458 else 459 psp->ps_map.mode = WAITING_RF; 460 #ifdef EXTERNAL_SYNC 461 x = splclock(); 462 #endif 463 (void) psrfnext(psp, psaddr); 464 #ifdef EXTERNAL_SYNC 465 splx(x); 466 #endif 467 } else 468 psp->ps_map.mode = WAITING_RF; 469 } else { /* no auto refresh */ 470 if (psp->ps_dbuffer.state == ON_DB) 471 /* fill other db */ 472 psdbswitch(psp, psaddr); 473 else 474 (void) psmapnext(psp, psaddr); 475 } 476 } 477 } 478 tryrf: 479 if (request & RFSTOP_REQ) { /* Refresh stopped */ 480 psp->ps_refresh.icnt++; 481 if (psp->ps_refresh.state == TIME_RF) 482 if (--psp->ps_refresh.timecnt > 0) 483 goto tryhit; 484 psrfstop(psaddr, psp); 485 if (psp->ps_refresh.waiting) { 486 psp->ps_refresh.waiting = 0; 487 wakeup(&psp->ps_refresh.waiting); 488 if (psp->ps_refresh.stop) { 489 psp->ps_refresh.stop = 0; 490 goto tryhit; 491 } 492 } 493 if (psp->ps_refresh.state == AUTO_RF) 494 if (!psrfnext(psp, psaddr)) { /* at end of refresh cycle */ 495 if (psp->ps_map.state == AUTO_MAP && 496 psp->ps_map.mode == WAITING_RF) { 497 if (psp->ps_dbuffer.state == ON_DB) 498 psdbswitch(psp, psaddr); 499 else 500 (void) psmapnext(psp, psaddr); 501 } 502 psp->ps_refresh.srcntr = 0; 503 #ifdef EXTERNAL_SYNC 504 x = splclock(); 505 #endif 506 psp->ps_refresh.mode = SYNCING_RF; 507 if (psp->ps_clockticks) 508 (void) psrfnext(psp, psaddr); 509 psp->ps_clockticks = 0; 510 #ifdef EXTERNAL_SYNC 511 splx(x); 512 #endif 513 } 514 } 515 tryhit: 516 if (request & HIT_REQ) /* Hit request */ 517 psp->ps_hitcnt++; 518 if (request == 0) 519 psp->ps_strayintr++; 520 RESTORPSADDR(psaddr, savepsaddr); 521 } 522 523 psrfnext(psp, psaddr) 524 register struct ps *psp; 525 register struct psdevice *psaddr; 526 { 527 u_short start, last; 528 529 if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) { 530 psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++], 531 0, psp, psaddr); 532 return (1); 533 } 534 if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs && 535 psp->ps_dbuffer.state == ON_DB) { 536 start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer]; 537 last = start+psp->ps_dbuffer.dbsize; 538 psrfstart(start, last, psp, psaddr); 539 psp->ps_refresh.srcntr++; /* flag for after dbuffer */ 540 return (1); 541 } 542 return (0); 543 } 544 545 psrfstart(dfaddr, last, psp, psaddr) 546 u_short dfaddr, last; 547 register struct ps *psp; 548 register struct psdevice *psaddr; 549 { 550 short dummy; 551 552 PSWAIT(psaddr); psaddr->ps_addr = RFASA; 553 PSWAIT(psaddr); psaddr->ps_data = dfaddr; 554 PSWAIT(psaddr); 555 if (last != 0) 556 psaddr->ps_data = last; 557 else 558 dummy = psaddr->ps_data;/* just access to get to status reg */ 559 PSWAIT(psaddr); psaddr->ps_data = RFSTART; /* may want | here */ 560 psp->ps_refresh.mode = RUNNING_RF; 561 } 562 563 /*ARGSUSED*/ 564 psrfstop(psaddr, psp) 565 register struct psdevice *psaddr; 566 register struct ps *psp; 567 { 568 569 PSWAIT(psaddr); psaddr->ps_addr = RFSR; 570 PSWAIT(psaddr); psaddr->ps_data = 0; 571 } 572 573 psdbswitch(psp, psaddr) 574 register struct ps *psp; 575 register struct psdevice *psaddr; 576 { 577 578 psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer; 579 pssetmapbounds(psp, psaddr); 580 (void) psmapnext(psp, psaddr); 581 } 582 583 psmapnext(psp, psaddr) 584 register struct ps *psp; 585 register struct psdevice *psaddr; 586 { 587 588 if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) { 589 psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], 590 psp, psaddr); 591 return (1); 592 } 593 return (0); 594 } 595 596 pssetmapbounds(psp, psaddr) 597 register struct ps *psp; 598 register struct psdevice *psaddr; 599 { 600 u_short start, last; 601 602 PSWAIT(psaddr); psaddr->ps_addr = MAOL; 603 PSWAIT(psaddr); 604 if (psp->ps_dbuffer.state == ON_DB) { 605 start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer]; 606 last = start+psp->ps_dbuffer.dbsize-2; /* 2 for halt cmd */ 607 psaddr->ps_data = last; 608 PSWAIT(psaddr); psaddr->ps_data = start; 609 } else { 610 start = psaddr->ps_data; /* dummy: don't update limit */ 611 PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart; 612 } 613 } 614 615 psmapstart(dfaddr, psp, psaddr) 616 u_short dfaddr; 617 register struct ps *psp; 618 register struct psdevice *psaddr; 619 { 620 621 PSWAIT(psaddr); psaddr->ps_addr = MAIA; 622 PSWAIT(psaddr); psaddr->ps_data = dfaddr; 623 PSWAIT(psaddr); psaddr->ps_data = MAO|MAI; /* may want more here */ 624 psp->ps_map.mode = RUNNING_MAP; 625 } 626 627 int pskillcnt = 1; 628 629 psmapstop(psaddr, psp, request) 630 register struct psdevice *psaddr; 631 register struct ps *psp; 632 short request; 633 { 634 register int i; 635 636 request &= HALT_REQ|MOSTOP_REQ; /* overkill?? */ 637 for (i = 0; i < pskillcnt; i++) { 638 PSWAIT(psaddr); psaddr->ps_addr = MASR; 639 PSWAIT(psaddr); psaddr->ps_data = IOUT; /* zero MAI & MAO */ 640 PSWAIT(psaddr); psaddr->ps_addr = MAIA; 641 PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 input addr reg */ 642 PSWAIT(psaddr); psaddr->ps_addr = MAOA; 643 PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 output addr reg */ 644 PSWAIT(psaddr); psaddr->ps_addr = SYSREQ; 645 PSWAIT(psaddr); psaddr->ps_data = request; 646 } 647 psp->ps_map.mode = STOPPED_MAP; 648 } 649 650 /*ARGSUSED*/ 651 psdeviceintr(dev) 652 dev_t dev; 653 { 654 655 printf("ps device intr\n"); 656 } 657 658 /*ARGSUSED*/ 659 psdmaintr(dev) 660 dev_t dev; 661 { 662 663 printf("ps dma intr\n"); 664 } 665 666 /*ARGSUSED*/ 667 psreset(uban) 668 int uban; 669 { 670 671 } 672 673 /*ARGSUSED*/ 674 psextsync(PC, PS) 675 { 676 register int n; 677 register struct psdevice *psaddr; 678 register struct ps *psp; 679 register int savepsaddr; 680 681 #ifdef EXTERNAL_SYNC 682 for (psp = ps, n = 0; n < NPS; psp++, n++) { 683 if (!psp->ps_open) 684 continue; 685 if (psp->ps_refresh.mode == SYNCING_RF && 686 psp->ps_refresh.state != TIME_RF) { 687 psaddr = (struct psdevice *)psdinfo[n]->ui_addr; 688 SAVEPSADDR(psaddr, savepsaddr); 689 (void) psrfnext(psp, psaddr); 690 RESTORPSADDR(psaddr, savepsaddr); 691 } else { 692 psp->ps_clockticks++; 693 psp->ps_clockmiss++; 694 } 695 } 696 #endif 697 } 698 #endif 699