xref: /original-bsd/sys/vax/uba/ps.c (revision a05d0f95)
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 
psprobe(reg)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 
psopen(dev)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 
psclose(dev)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*/
psread(dev,uio)214 psread(dev, uio)
215 	dev_t dev;
216 	struct uio *uio;
217 {
218 }
219 
220 /*ARGSUSED*/
pswrite(dev,uio)221 pswrite(dev, uio)
222 	dev_t dev;
223 	struct uio *uio;
224 {
225 }
226 
227 /*ARGSUSED*/
psioctl(dev,cmd,data,flag)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 
psclockintr(dev)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*/
pssystemintr(dev)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 
psrfnext(psp,psaddr)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 
psrfstart(dfaddr,last,psp,psaddr)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*/
psrfstop(psaddr,psp)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 
psdbswitch(psp,psaddr)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 
psmapnext(psp,psaddr)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 
pssetmapbounds(psp,psaddr)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 
psmapstart(dfaddr,psp,psaddr)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 
psmapstop(psaddr,psp,request)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*/
psdeviceintr(dev)651 psdeviceintr(dev)
652 	dev_t dev;
653 {
654 
655 	printf("ps device intr\n");
656 }
657 
658 /*ARGSUSED*/
psdmaintr(dev)659 psdmaintr(dev)
660 	dev_t dev;
661 {
662 
663 	printf("ps dma intr\n");
664 }
665 
666 /*ARGSUSED*/
psreset(uban)667 psreset(uban)
668 	int uban;
669 {
670 
671 }
672 
673 /*ARGSUSED*/
psextsync(PC,PS)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