xref: /original-bsd/sys/vax/uba/ps.c (revision a64d8d4e)
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.6 (Berkeley) 12/16/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 "../include/pte.h"
24 
25 #include "sys/param.h"
26 #include "sys/systm.h"
27 #include "sys/ioctl.h"
28 #include "sys/map.h"
29 #include "sys/buf.h"
30 #include "sys/conf.h"
31 #include "sys/user.h"
32 #include "sys/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