xref: /original-bsd/sys/vax/uba/ps.c (revision 87febec0)
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.2 (Berkeley) 04/25/89
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
692