|
|
1.1 root 1: /*-
2: * Copyright (c) 1982, 1986 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)ps.c 7.7 (Berkeley) 5/9/91
34: */
35:
36: /*
37: * Evans and Sutherland Picture System 2 driver -- Bill Reeves.
38: */
39:
40: /*
41: * Still to be done:
42: * WAIT_HIT
43: */
44:
45: #include "ps.h"
46: #if NPS > 0
47:
48: #define EXTERNAL_SYNC
49:
50: #include "../include/pte.h"
51:
52: #include "sys/param.h"
53: #include "sys/systm.h"
54: #include "sys/ioctl.h"
55: #include "sys/map.h"
56: #include "sys/buf.h"
57: #include "sys/conf.h"
58: #include "sys/user.h"
59: #include "sys/uio.h"
60:
61: #include "ubareg.h"
62: #include "ubavar.h"
63: #include "psreg.h"
64:
65: int psprobe(), psattach(), psextsync();
66: int psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();
67: struct uba_device *psdinfo[NPS];
68: u_short psstd[] = { 0 };
69: struct uba_driver psdriver =
70: { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
71:
72: #define PSUNIT(dev) (minor(dev))
73:
74: #define MAXAUTOREFRESH 4
75: #define MAXAUTOMAP 4
76: #define MAXDBSIZE (0177777/2)
77:
78: #define PSPRI (PZERO+1)
79:
80: #define PSWAIT(psaddr) { \
81: register short i = 20000, j; \
82: while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \
83: ;\
84: }
85:
86: struct psrefresh {
87: enum {
88: SINGLE_STEP_RF,
89: AUTO_RF,
90: TIME_RF
91: } state;
92: enum {
93: RUNNING_RF,
94: SYNCING_RF,
95: WAITING_MAP,
96: STOPPED_RF
97: } mode;
98: u_short sraddrs[MAXAUTOREFRESH];
99: short nsraddrs;
100: short srcntr;
101: char waiting;
102: char stop;
103: int icnt;
104: int timecnt;
105: };
106:
107: struct psdbuffer {
108: enum {
109: ON_DB,
110: OFF_DB
111: } state;
112: u_short dbaddrs[2];
113: u_short dbsize;
114: short rbuffer;
115: };
116:
117: struct psmap {
118: enum {
119: SINGLE_STEP_MAP,
120: AUTO_MAP
121: } state;
122: enum {
123: RUNNING_MAP,
124: WAITING_RF,
125: WAITING_START,
126: STOPPED_MAP
127: } mode;
128: u_short maddrs[MAXAUTOMAP];
129: short nmaddrs;
130: short mcntr;
131: short outputstart;
132: char waiting;
133: char stop;
134: int icnt;
135: };
136:
137: /*
138: * PS2 software state.
139: */
140: struct ps {
141: char ps_open; /* device is open */
142: uid_t ps_uid; /* uid of device owner */
143: struct psrefresh ps_refresh; /* refresh state */
144: struct psdbuffer ps_dbuffer; /* double buffering state */
145: struct psmap ps_map; /* segment map state */
146: int ps_clockticks; /* clock ints between refresh */
147: int ps_clockmiss; /* clock ints w/o refresh */
148: int ps_clockcnt; /* count of clock interrupts */
149: int ps_hitcnt; /* count of hit interrupts */
150: int ps_strayintr; /* count of stray interrupts */
151: int ps_icnt; /* count of system interrupts */
152: /* BEGIN GROT */
153: int ps_lastrequest;
154: int ps_lastrequest2;
155: int ps_lastfunnyrequest;
156: int ps_funnycnt;
157: /* END GROT */
158: } ps[NPS];
159:
160: psprobe(reg)
161: caddr_t reg;
162: {
163: register int br, cvec;
164: register struct psdevice *psaddr = (struct psdevice *)reg;
165:
166: #ifdef lint
167: br = 0; cvec = br; br = cvec;
168: psclockintr((dev_t)0); pssystemintr((dev_t)0);
169: psdeviceintr((dev_t)0); psdmaintr((dev_t)0);
170: psextsync(0, 0);
171: #endif
172: psaddr->ps_iostat = PSRESET;
173: DELAY(200);
174: psaddr->ps_addr = RTCIE;
175: PSWAIT(psaddr); psaddr->ps_data = 01;
176: psaddr->ps_iostat = PSIE;
177: psaddr->ps_addr = RTCSR;
178: PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN;
179: DELAY(200000);
180: psaddr->ps_addr = RTCREQ;
181: PSWAIT(psaddr); psaddr->ps_data = 01;
182: psaddr->ps_iostat = 0;
183: psaddr->ps_iostat = PSRESET;
184: return (sizeof (struct psdevice));
185: }
186:
187: /*ARGSUSED*/
188: psattach(ui)
189: struct uba_device *ui;
190: {
191:
192: }
193:
194: psopen(dev)
195: dev_t dev;
196: {
197: register struct ps *psp;
198: register struct uba_device *ui;
199: register int unit = PSUNIT(dev);
200:
201: if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
202: (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
203: return (ENXIO);
204: psp->ps_open = 1;
205: psp->ps_uid = u.u_uid;
206: psp->ps_strayintr = 0;
207: psp->ps_refresh.state = SINGLE_STEP_RF;
208: psp->ps_refresh.mode = STOPPED_RF;
209: psp->ps_refresh.waiting = 0;
210: psp->ps_refresh.stop = 0;
211: psp->ps_dbuffer.state = OFF_DB;
212: psp->ps_map.state = SINGLE_STEP_MAP;
213: psp->ps_map.mode = STOPPED_MAP;
214: psp->ps_map.waiting = 0;
215: psp->ps_map.stop = 0;
216: psp->ps_clockticks = 0;
217: psp->ps_clockmiss = 0;
218: psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0;
219: psp->ps_hitcnt = 0;
220: psp->ps_icnt = 0;
221: maptouser(ui->ui_addr);
222: return (0);
223: }
224:
225: psclose(dev)
226: dev_t dev;
227: {
228: register struct psdevice *psaddr =
229: (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
230:
231: ps[PSUNIT(dev)].ps_open = 0;
232: psaddr->ps_iostat = 0; /* clear IENABLE */
233: PSWAIT(psaddr); psaddr->ps_addr = RFSR; /* set in auto refresh mode */
234: PSWAIT(psaddr); psaddr->ps_data = AUTOREF;
235: unmaptouser((caddr_t)psaddr);
236: return (0);
237: }
238:
239: /*ARGSUSED*/
240: psread(dev, uio)
241: dev_t dev;
242: struct uio *uio;
243: {
244: }
245:
246: /*ARGSUSED*/
247: pswrite(dev, uio)
248: dev_t dev;
249: struct uio *uio;
250: {
251: }
252:
253: /*ARGSUSED*/
254: psioctl(dev, cmd, data, flag)
255: register caddr_t data;
256: {
257: register struct uba_device *ui = psdinfo[PSUNIT(dev)];
258: register struct ps *psp = &ps[PSUNIT(dev)];
259: int *waddr = *(int **)data;
260: int n, arg, i, error = 0;
261:
262: switch (cmd) {
263:
264: case PSIOGETADDR:
265: *(caddr_t *)data = ui->ui_addr;
266: break;
267:
268: case PSIOAUTOREFRESH:
269: n = fuword((caddr_t)waddr++);
270: if (n == -1)
271: return (EFAULT);
272: if (n < 0 || n > MAXAUTOREFRESH)
273: return (EINVAL);
274: for (i = 0; i < n; i++) {
275: if ((arg = fuword((caddr_t)waddr++)) == -1)
276: return (EFAULT);
277: psp->ps_refresh.sraddrs[i] = arg;
278: }
279: psp->ps_refresh.state = AUTO_RF;
280: psp->ps_refresh.nsraddrs = n;
281: psp->ps_refresh.srcntr = 0;
282: psp->ps_refresh.mode = WAITING_MAP;
283: break;
284:
285: case PSIOAUTOMAP:
286: n = fuword((caddr_t)waddr++);
287: if (n == -1)
288: return (EFAULT);
289: if (n < 0 || n > MAXAUTOMAP)
290: return (EINVAL);
291: for (i = 0; i < n; i++) {
292: if ((arg = fuword((caddr_t)waddr++)) == -1)
293: return (EFAULT);
294: psp->ps_map.maddrs[i] = arg;
295: }
296: if ((arg = fuword((caddr_t)waddr++)) == -1)
297: return (EFAULT);
298: psp->ps_map.outputstart = arg;
299: psp->ps_map.state = AUTO_MAP;
300: psp->ps_map.nmaddrs = n;
301: psp->ps_map.mcntr = 0;
302: psp->ps_map.mode = WAITING_START;
303: break;
304:
305: case PSIOSINGLEREFRESH:
306: psp->ps_refresh.state = SINGLE_STEP_RF;
307: break;
308:
309: case PSIOSINGLEMAP:
310: psp->ps_map.state = SINGLE_STEP_MAP;
311: break;
312:
313: case PSIODOUBLEBUFFER:
314: if ((arg = fuword((caddr_t)waddr++)) == -1)
315: return (EFAULT);
316: psp->ps_dbuffer.dbaddrs[0] = arg;
317: if ((arg = fuword((caddr_t)waddr++)) == -1)
318: return (EFAULT);
319: if (arg <= 0 || arg > MAXDBSIZE)
320: return (EINVAL);
321: psp->ps_dbuffer.dbsize = arg;
322: psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg;
323: psp->ps_dbuffer.state = ON_DB;
324: psp->ps_dbuffer.rbuffer = 0;
325: break;
326:
327: case PSIOSINGLEBUFFER:
328: psp->ps_dbuffer.state = OFF_DB;
329: break;
330:
331: case PSIOTIMEREFRESH:
332: if (psp->ps_refresh.state != SINGLE_STEP_RF)
333: return (EINVAL);
334: if ((arg = fuword((caddr_t)waddr++)) == -1)
335: return (EFAULT);
336: psp->ps_refresh.state = TIME_RF;
337: psp->ps_refresh.timecnt = arg;
338: break;
339:
340: case PSIOWAITREFRESH:
341: if (psp->ps_refresh.mode != RUNNING_RF) /* not running */
342: return (0); /* dont wait */
343: /* fall into ... */
344:
345: case PSIOSTOPREFRESH:
346: if (cmd == PSIOSTOPREFRESH) {
347: if (psp->ps_refresh.mode == STOPPED_RF &&
348: psp->ps_refresh.state != TIME_RF)
349: return (0);
350: psp->ps_refresh.stop = 1;
351: }
352: (void) spl5();
353: psp->ps_refresh.waiting = 1;
354: while (psp->ps_refresh.waiting)
355: if (error = tsleep(&psp->ps_refresh.waiting,
356: PSPRI | PCATCH, devwait, 0))
357: break;
358: (void) spl0();
359: if (error)
360: return (error);
361: if (cmd == PSIOSTOPREFRESH)
362: psp->ps_refresh.mode = STOPPED_RF;
363: if (psp->ps_refresh.state == TIME_RF)
364: psp->ps_refresh.state = SINGLE_STEP_RF;
365: break;
366:
367: case PSIOWAITMAP:
368: if (psp->ps_map.mode != RUNNING_MAP) /* not running */
369: return (0); /* dont wait */
370: /* fall into ... */
371:
372: case PSIOSTOPMAP:
373: if (cmd == PSIOSTOPMAP)
374: psp->ps_map.stop = 1;
375: (void) spl5();
376: psp->ps_map.waiting = 1;
377: while (psp->ps_map.waiting)
378: if (error = tsleep(&psp->ps_map.waiting, PSPRI | PCATCH,
379: devwait, 0))
380: break;
381: (void) spl0();
382: break;
383:
384: default:
385: return (ENOTTY);
386: break;
387: }
388: return (error);
389: }
390:
391: #define SAVEPSADDR(psaddr, savepsaddr) { \
392: register short i, xx1; \
393: xx1 = splclock(); \
394: i = psaddr->ps_addr; \
395: while ((psaddr->ps_iostat & DIOREADY) == 0) \
396: ; \
397: savepsaddr = psaddr->ps_data; \
398: splx(xx1); \
399: }
400: #define RESTORPSADDR(psaddr, savepsaddr) { \
401: register short xx2; \
402: xx2 = splclock(); \
403: while ((psaddr->ps_iostat & DIOREADY) == 0) \
404: ;\
405: psaddr->ps_addr = savepsaddr; \
406: splx(xx2); \
407: }
408:
409: psclockintr(dev)
410: dev_t dev;
411: {
412: register struct psdevice *psaddr =
413: (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
414: register struct ps *psp = &ps[PSUNIT(dev)];
415: int savepsaddr;
416:
417: if (!psp->ps_open)
418: return;
419: psp->ps_clockcnt++;
420: SAVEPSADDR(psaddr, savepsaddr);
421: #ifndef EXTERNAL_SYNC
422: if (psp->ps_refresh.state == AUTO_RF) {
423: if (psp->ps_refresh.mode == SYNCING_RF &&
424: psp->ps_refresh.state != TIME_RF) {
425: (void) psrfnext(psp, psaddr);
426: } else {
427: psp->ps_clockticks++;
428: psp->ps_clockmiss++;
429: }
430: }
431: #endif
432: PSWAIT(psaddr); psaddr->ps_addr = RTCREQ;
433: PSWAIT(psaddr); psaddr->ps_data = 01; /* clear the request bits */
434: RESTORPSADDR(psaddr, savepsaddr);
435: }
436:
437: /*ARGSUSED*/
438: pssystemintr(dev)
439: dev_t dev;
440: {
441: register struct psdevice *psaddr =
442: (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;
443: register struct ps *psp = &ps[PSUNIT(dev)];
444: short request, tmp;
445: register int savepsaddr, x;
446:
447: if (!psp->ps_open)
448: return;
449: psp->ps_icnt++;
450: SAVEPSADDR(psaddr, savepsaddr);
451: PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
452: PSWAIT(psaddr); request = psaddr->ps_data;
453: request = request&0377;
454: psp->ps_lastrequest2 = psp->ps_lastrequest;
455: psp->ps_lastrequest = request;
456: if (request &~ (HALT_REQ|RFSTOP_REQ|HIT_REQ)) {
457: psp->ps_lastfunnyrequest = request;
458: psp->ps_funnycnt++;
459: }
460: PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
461: tmp = request&(~(HALT_REQ|MOSTOP_REQ)); /* acknowledge */
462: PSWAIT(psaddr); psaddr->ps_data = tmp;
463:
464: if (request & (MOSTOP_REQ|HALT_REQ)) { /* Map stopped */
465: psp->ps_map.icnt++;
466: psmapstop(psaddr, psp, request);/* kill it dead */
467: if (psp->ps_map.waiting) {
468: psp->ps_map.waiting = 0;
469: wakeup(&psp->ps_map.waiting);
470: if (psp->ps_map.stop) {
471: psp->ps_map.stop = 0;
472: goto tryrf;
473: }
474: }
475: if (psp->ps_map.state == AUTO_MAP && !psmapnext(psp, psaddr)) {
476: psp->ps_map.mcntr = 0;
477: /* prepare for next round */
478: pssetmapbounds(psp, psaddr);
479: if (psp->ps_refresh.state == AUTO_RF) {
480: if (psp->ps_refresh.mode == WAITING_MAP){
481: if (psp->ps_dbuffer.state == ON_DB)
482: /* fill other db */
483: psdbswitch(psp, psaddr);
484: else
485: psp->ps_map.mode = WAITING_RF;
486: #ifdef EXTERNAL_SYNC
487: x = splclock();
488: #endif
489: (void) psrfnext(psp, psaddr);
490: #ifdef EXTERNAL_SYNC
491: splx(x);
492: #endif
493: } else
494: psp->ps_map.mode = WAITING_RF;
495: } else { /* no auto refresh */
496: if (psp->ps_dbuffer.state == ON_DB)
497: /* fill other db */
498: psdbswitch(psp, psaddr);
499: else
500: (void) psmapnext(psp, psaddr);
501: }
502: }
503: }
504: tryrf:
505: if (request & RFSTOP_REQ) { /* Refresh stopped */
506: psp->ps_refresh.icnt++;
507: if (psp->ps_refresh.state == TIME_RF)
508: if (--psp->ps_refresh.timecnt > 0)
509: goto tryhit;
510: psrfstop(psaddr, psp);
511: if (psp->ps_refresh.waiting) {
512: psp->ps_refresh.waiting = 0;
513: wakeup(&psp->ps_refresh.waiting);
514: if (psp->ps_refresh.stop) {
515: psp->ps_refresh.stop = 0;
516: goto tryhit;
517: }
518: }
519: if (psp->ps_refresh.state == AUTO_RF)
520: if (!psrfnext(psp, psaddr)) { /* at end of refresh cycle */
521: if (psp->ps_map.state == AUTO_MAP &&
522: psp->ps_map.mode == WAITING_RF) {
523: if (psp->ps_dbuffer.state == ON_DB)
524: psdbswitch(psp, psaddr);
525: else
526: (void) psmapnext(psp, psaddr);
527: }
528: psp->ps_refresh.srcntr = 0;
529: #ifdef EXTERNAL_SYNC
530: x = splclock();
531: #endif
532: psp->ps_refresh.mode = SYNCING_RF;
533: if (psp->ps_clockticks)
534: (void) psrfnext(psp, psaddr);
535: psp->ps_clockticks = 0;
536: #ifdef EXTERNAL_SYNC
537: splx(x);
538: #endif
539: }
540: }
541: tryhit:
542: if (request & HIT_REQ) /* Hit request */
543: psp->ps_hitcnt++;
544: if (request == 0)
545: psp->ps_strayintr++;
546: RESTORPSADDR(psaddr, savepsaddr);
547: }
548:
549: psrfnext(psp, psaddr)
550: register struct ps *psp;
551: register struct psdevice *psaddr;
552: {
553: u_short start, last;
554:
555: if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs) {
556: psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
557: 0, psp, psaddr);
558: return (1);
559: }
560: if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs &&
561: psp->ps_dbuffer.state == ON_DB) {
562: start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer];
563: last = start+psp->ps_dbuffer.dbsize;
564: psrfstart(start, last, psp, psaddr);
565: psp->ps_refresh.srcntr++; /* flag for after dbuffer */
566: return (1);
567: }
568: return (0);
569: }
570:
571: psrfstart(dfaddr, last, psp, psaddr)
572: u_short dfaddr, last;
573: register struct ps *psp;
574: register struct psdevice *psaddr;
575: {
576: short dummy;
577:
578: PSWAIT(psaddr); psaddr->ps_addr = RFASA;
579: PSWAIT(psaddr); psaddr->ps_data = dfaddr;
580: PSWAIT(psaddr);
581: if (last != 0)
582: psaddr->ps_data = last;
583: else
584: dummy = psaddr->ps_data;/* just access to get to status reg */
585: PSWAIT(psaddr); psaddr->ps_data = RFSTART; /* may want | here */
586: psp->ps_refresh.mode = RUNNING_RF;
587: }
588:
589: /*ARGSUSED*/
590: psrfstop(psaddr, psp)
591: register struct psdevice *psaddr;
592: register struct ps *psp;
593: {
594:
595: PSWAIT(psaddr); psaddr->ps_addr = RFSR;
596: PSWAIT(psaddr); psaddr->ps_data = 0;
597: }
598:
599: psdbswitch(psp, psaddr)
600: register struct ps *psp;
601: register struct psdevice *psaddr;
602: {
603:
604: psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
605: pssetmapbounds(psp, psaddr);
606: (void) psmapnext(psp, psaddr);
607: }
608:
609: psmapnext(psp, psaddr)
610: register struct ps *psp;
611: register struct psdevice *psaddr;
612: {
613:
614: if (psp->ps_map.mcntr < psp->ps_map.nmaddrs) {
615: psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++],
616: psp, psaddr);
617: return (1);
618: }
619: return (0);
620: }
621:
622: pssetmapbounds(psp, psaddr)
623: register struct ps *psp;
624: register struct psdevice *psaddr;
625: {
626: u_short start, last;
627:
628: PSWAIT(psaddr); psaddr->ps_addr = MAOL;
629: PSWAIT(psaddr);
630: if (psp->ps_dbuffer.state == ON_DB) {
631: start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer];
632: last = start+psp->ps_dbuffer.dbsize-2; /* 2 for halt cmd */
633: psaddr->ps_data = last;
634: PSWAIT(psaddr); psaddr->ps_data = start;
635: } else {
636: start = psaddr->ps_data; /* dummy: don't update limit */
637: PSWAIT(psaddr); psaddr->ps_data = psp->ps_map.outputstart;
638: }
639: }
640:
641: psmapstart(dfaddr, psp, psaddr)
642: u_short dfaddr;
643: register struct ps *psp;
644: register struct psdevice *psaddr;
645: {
646:
647: PSWAIT(psaddr); psaddr->ps_addr = MAIA;
648: PSWAIT(psaddr); psaddr->ps_data = dfaddr;
649: PSWAIT(psaddr); psaddr->ps_data = MAO|MAI; /* may want more here */
650: psp->ps_map.mode = RUNNING_MAP;
651: }
652:
653: int pskillcnt = 1;
654:
655: psmapstop(psaddr, psp, request)
656: register struct psdevice *psaddr;
657: register struct ps *psp;
658: short request;
659: {
660: register int i;
661:
662: request &= HALT_REQ|MOSTOP_REQ; /* overkill?? */
663: for (i = 0; i < pskillcnt; i++) {
664: PSWAIT(psaddr); psaddr->ps_addr = MASR;
665: PSWAIT(psaddr); psaddr->ps_data = IOUT; /* zero MAI & MAO */
666: PSWAIT(psaddr); psaddr->ps_addr = MAIA;
667: PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 input addr reg */
668: PSWAIT(psaddr); psaddr->ps_addr = MAOA;
669: PSWAIT(psaddr); psaddr->ps_data = 0; /* 0 output addr reg */
670: PSWAIT(psaddr); psaddr->ps_addr = SYSREQ;
671: PSWAIT(psaddr); psaddr->ps_data = request;
672: }
673: psp->ps_map.mode = STOPPED_MAP;
674: }
675:
676: /*ARGSUSED*/
677: psdeviceintr(dev)
678: dev_t dev;
679: {
680:
681: printf("ps device intr\n");
682: }
683:
684: /*ARGSUSED*/
685: psdmaintr(dev)
686: dev_t dev;
687: {
688:
689: printf("ps dma intr\n");
690: }
691:
692: /*ARGSUSED*/
693: psreset(uban)
694: int uban;
695: {
696:
697: }
698:
699: /*ARGSUSED*/
700: psextsync(PC, PS)
701: {
702: register int n;
703: register struct psdevice *psaddr;
704: register struct ps *psp;
705: register int savepsaddr;
706:
707: #ifdef EXTERNAL_SYNC
708: for (psp = ps, n = 0; n < NPS; psp++, n++) {
709: if (!psp->ps_open)
710: continue;
711: if (psp->ps_refresh.mode == SYNCING_RF &&
712: psp->ps_refresh.state != TIME_RF) {
713: psaddr = (struct psdevice *)psdinfo[n]->ui_addr;
714: SAVEPSADDR(psaddr, savepsaddr);
715: (void) psrfnext(psp, psaddr);
716: RESTORPSADDR(psaddr, savepsaddr);
717: } else {
718: psp->ps_clockticks++;
719: psp->ps_clockmiss++;
720: }
721: }
722: #endif
723: }
724: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.