|
|
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.