xref: /csrg-svn/sys/vax/uba/ps.c (revision 7296)
1*7296Ssam /*	ps.c	4.1	82/06/26	*/
2*7296Ssam 
3*7296Ssam /*
4*7296Ssam  * Evans and Sutherland Picture System 2 driver
5*7296Ssam  */
6*7296Ssam 
7*7296Ssam /*
8*7296Ssam  *	Still to be done:
9*7296Ssam  *		WAIT_HIT
10*7296Ssam  */
11*7296Ssam 
12*7296Ssam #include "ps.h"
13*7296Ssam #if NPS > 0
14*7296Ssam 
15*7296Ssam #define EXTERNAL_SYNC
16*7296Ssam 
17*7296Ssam #include "../h/param.h"
18*7296Ssam #include "../h/systm.h"
19*7296Ssam #include "../h/tty.h"
20*7296Ssam #include "../h/pte.h"
21*7296Ssam #include "../h/map.h"
22*7296Ssam #include "../h/buf.h"
23*7296Ssam #include "../h/ubareg.h"
24*7296Ssam #include "../h/ubavar.h"
25*7296Ssam #include "../h/conf.h"
26*7296Ssam #include "../h/dir.h"
27*7296Ssam #include "../h/user.h"
28*7296Ssam #include "../h/psreg.h"
29*7296Ssam 
30*7296Ssam int	psprobe(), psattach(), psintr();
31*7296Ssam struct	uba_device *psdinfo[NPS];
32*7296Ssam u_short	psstd[] = { 0 };
33*7296Ssam struct	uba_driver psdriver =
34*7296Ssam     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
35*7296Ssam 
36*7296Ssam #define	PSUNIT(dev)	(minor(dev))
37*7296Ssam 
38*7296Ssam #define MAXAUTOREFRESH			(4)
39*7296Ssam #define MAXAUTOMAP			(4)
40*7296Ssam #define MAXDBSIZE			(0177777/2)
41*7296Ssam 
42*7296Ssam #define PSPRI				(PZERO+1)
43*7296Ssam 
44*7296Ssam #define PSWAIT() {register short int i, j; i=20000; while((i-- != 0)\
45*7296Ssam 	&& (((j=psaddr->ps_iostat)&DIOREADY)==0));}
46*7296Ssam 
47*7296Ssam struct ps {
48*7296Ssam 	char		ps_open;
49*7296Ssam 	short int 	ps_uid;
50*7296Ssam 	struct {
51*7296Ssam 		enum { SINGLE_STEP_RF, AUTO_RF } state;
52*7296Ssam 		enum { RUNNING_RF, SYNCING_RF, WAITING_MAP } mode;
53*7296Ssam 		unsigned short int sraddrs[MAXAUTOREFRESH];
54*7296Ssam 		short int nsraddrs;
55*7296Ssam 		short int srcntr;
56*7296Ssam 		char waiting;
57*7296Ssam 		char stop;
58*7296Ssam 		int icnt;
59*7296Ssam 	} ps_refresh;
60*7296Ssam 	struct {
61*7296Ssam 		enum { ON_DB, OFF_DB } state;
62*7296Ssam 		unsigned short int dbaddrs[2];
63*7296Ssam 		unsigned short int dbsize;
64*7296Ssam 		short int rbuffer;
65*7296Ssam 	} ps_dbuffer;
66*7296Ssam 	struct {
67*7296Ssam 		enum { SINGLE_STEP_MAP, AUTO_MAP } state;
68*7296Ssam 		enum { RUNNING_MAP, WAITING_RF, WAITING_START } mode;
69*7296Ssam 		unsigned short int maddrs[MAXAUTOMAP];
70*7296Ssam 		short int nmaddrs;
71*7296Ssam 		short int mcntr;
72*7296Ssam 		short int outputstart;
73*7296Ssam 		char waiting;
74*7296Ssam 		char stop;
75*7296Ssam 		int icnt;
76*7296Ssam 	} ps_map;
77*7296Ssam 	struct {
78*7296Ssam 		short int ticked;
79*7296Ssam 		short int missed;
80*7296Ssam 		int icnt;
81*7296Ssam 	} ps_clock;
82*7296Ssam 	struct {
83*7296Ssam 		int icnt;
84*7296Ssam 	} ps_hit;
85*7296Ssam 	int ps_strayintr;
86*7296Ssam 	int last_request;
87*7296Ssam 	int strayrequest;
88*7296Ssam } ps[NPS];
89*7296Ssam 
90*7296Ssam psprobe(reg)
91*7296Ssam 	caddr_t reg;
92*7296Ssam {
93*7296Ssam 	register int br, cvec;
94*7296Ssam 	register struct psdevice *psaddr = (struct psdevice *) reg;
95*7296Ssam 
96*7296Ssam 	psaddr->ps_iostat = PSRESET;
97*7296Ssam 	DELAY(200);
98*7296Ssam 	psaddr->ps_addr = RTCIE;
99*7296Ssam 	PSWAIT();
100*7296Ssam 	psaddr->ps_data = 01;
101*7296Ssam 	psaddr->ps_iostat = PSIE;
102*7296Ssam 	psaddr->ps_addr = RTCSR;
103*7296Ssam 	PSWAIT();
104*7296Ssam 	psaddr->ps_data = (SYNC|RUN);
105*7296Ssam 	DELAY(200000);
106*7296Ssam 	psaddr->ps_addr = RTCREQ;
107*7296Ssam 	PSWAIT();
108*7296Ssam 	psaddr->ps_data = 01;
109*7296Ssam 	psaddr->ps_iostat = 0;
110*7296Ssam 	psaddr->ps_iostat = PSRESET;
111*7296Ssam }
112*7296Ssam 
113*7296Ssam /*ARGSUSED*/
114*7296Ssam psattach(ui)
115*7296Ssam 	register struct uba_device *ui;
116*7296Ssam {
117*7296Ssam }
118*7296Ssam 
119*7296Ssam 
120*7296Ssam psopen(dev)
121*7296Ssam 	dev_t dev;
122*7296Ssam {
123*7296Ssam 	register struct ps *psp;
124*7296Ssam 	register struct uba_device *ui;
125*7296Ssam 	register int unit = PSUNIT(dev);
126*7296Ssam 
127*7296Ssam 	if(unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
128*7296Ssam 			(ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) {
129*7296Ssam 		u.u_error = ENXIO;
130*7296Ssam 		return;
131*7296Ssam 	}
132*7296Ssam 	psp->ps_open = 1;
133*7296Ssam 	psp->ps_uid = u.u_uid;
134*7296Ssam 	psp->ps_strayintr = 0;
135*7296Ssam 	psp->ps_refresh.state = SINGLE_STEP_RF;
136*7296Ssam 	psp->ps_refresh.waiting = 0;
137*7296Ssam 	psp->ps_refresh.stop = 0;
138*7296Ssam 	psp->ps_dbuffer.state = OFF_DB;
139*7296Ssam 	psp->ps_map.state = SINGLE_STEP_MAP;
140*7296Ssam 	psp->ps_map.waiting = 0;
141*7296Ssam 	psp->ps_map.stop = 0;
142*7296Ssam 	psp->ps_clock.ticked = 0;
143*7296Ssam 	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0;
144*7296Ssam 	maptouser(ui->ui_addr);
145*7296Ssam }
146*7296Ssam 
147*7296Ssam psclose(dev)
148*7296Ssam 	dev_t dev;
149*7296Ssam {
150*7296Ssam 	register struct psdevice *psaddr =
151*7296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
152*7296Ssam 
153*7296Ssam 	ps[PSUNIT(dev)].ps_open = 0;
154*7296Ssam 	psaddr->ps_iostat = 0;		/* clear IENABLE */
155*7296Ssam 	PSWAIT();
156*7296Ssam 	psaddr->ps_addr = RFSR;		/* set in auto refresh mode */
157*7296Ssam 	PSWAIT();
158*7296Ssam 	psaddr->ps_data = AUTOREF;
159*7296Ssam 	unmaptouser(psaddr);
160*7296Ssam }
161*7296Ssam 
162*7296Ssam /*ARGSUSED*/
163*7296Ssam psread(dev)
164*7296Ssam 	dev_t dev;
165*7296Ssam {
166*7296Ssam }
167*7296Ssam 
168*7296Ssam /*ARGSUSED*/
169*7296Ssam pswrite(dev)
170*7296Ssam 	dev_t dev;
171*7296Ssam {
172*7296Ssam }
173*7296Ssam 
174*7296Ssam /*ARGSUSED*/
175*7296Ssam psioctl(dev, cmd, addr, flag)
176*7296Ssam 	register caddr_t addr;
177*7296Ssam {
178*7296Ssam 	register struct uba_device *ui = psdinfo[PSUNIT(dev)];
179*7296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
180*7296Ssam 	int *waddr = (int *) addr;
181*7296Ssam 	int n, arg, i;
182*7296Ssam 
183*7296Ssam 	switch (cmd) {
184*7296Ssam 	case PSGETADDR:
185*7296Ssam 		(void) suword(addr, ui->ui_addr);
186*7296Ssam 		break;
187*7296Ssam 	case PSAUTOREFRESH:
188*7296Ssam 		n = fuword(waddr++);
189*7296Ssam 		if(n == -1)
190*7296Ssam 			u.u_error = EFAULT;
191*7296Ssam 		else if(n < 0 || n > MAXAUTOREFRESH)
192*7296Ssam 			u.u_error = EINVAL;
193*7296Ssam 		else {
194*7296Ssam 			for(i = 0; i < n; i++)
195*7296Ssam 				if((arg = fuword(waddr++)) == -1) {
196*7296Ssam 					u.u_error = EFAULT;
197*7296Ssam 					break;
198*7296Ssam 				}
199*7296Ssam 				else
200*7296Ssam 					psp->ps_refresh.sraddrs[i] = arg;
201*7296Ssam 			if(!u.u_error) {
202*7296Ssam 				psp->ps_refresh.state = AUTO_RF;
203*7296Ssam 				psp->ps_refresh.nsraddrs = n;
204*7296Ssam 				psp->ps_refresh.srcntr = 0;
205*7296Ssam 				psp->ps_refresh.mode = WAITING_MAP;
206*7296Ssam 			}
207*7296Ssam 		}
208*7296Ssam 		break;
209*7296Ssam 	case PSAUTOMAP:
210*7296Ssam 		n = fuword(waddr++);
211*7296Ssam 		if(n == -1)
212*7296Ssam 			u.u_error = EFAULT;
213*7296Ssam 		else if(n < 0 || n > MAXAUTOMAP)
214*7296Ssam 			u.u_error = EINVAL;
215*7296Ssam 		else {
216*7296Ssam 			for(i = 0; i < n; i++)
217*7296Ssam 				if((arg = fuword(waddr++)) == -1) {
218*7296Ssam 					u.u_error = EFAULT;
219*7296Ssam 					break;
220*7296Ssam 				}
221*7296Ssam 				else
222*7296Ssam 					psp->ps_map.maddrs[i] = arg;
223*7296Ssam 			if(!u.u_error)
224*7296Ssam 				if((arg = fuword(waddr++)) == -1)
225*7296Ssam 					u.u_error = EFAULT;
226*7296Ssam 				else
227*7296Ssam 					psp->ps_map.outputstart = arg;
228*7296Ssam 			if(!u.u_error) {
229*7296Ssam 				psp->ps_map.state = AUTO_MAP;
230*7296Ssam 				psp->ps_map.nmaddrs = n;
231*7296Ssam 				psp->ps_map.mcntr = 0;
232*7296Ssam 				psp->ps_map.mode = WAITING_START;
233*7296Ssam 			}
234*7296Ssam 		}
235*7296Ssam 		break;
236*7296Ssam 	case PSSINGLEREFRESH:
237*7296Ssam 		psp->ps_refresh.state = SINGLE_STEP_RF;
238*7296Ssam 		break;
239*7296Ssam 	case PSSINGLEMAP:
240*7296Ssam 		psp->ps_map.state = SINGLE_STEP_MAP;
241*7296Ssam 		break;
242*7296Ssam 	case PSDOUBLEBUFFER:
243*7296Ssam 		if((arg = fuword(waddr++)) == -1)
244*7296Ssam 			u.u_error = EFAULT;
245*7296Ssam 		else {
246*7296Ssam 			psp->ps_dbuffer.dbaddrs[0] = arg;
247*7296Ssam 			if((arg = fuword(waddr++)) == -1)
248*7296Ssam 				u.u_error = EFAULT;
249*7296Ssam 			else if(arg <= 0 || arg > MAXDBSIZE)
250*7296Ssam 				u.u_error = EINVAL;
251*7296Ssam 			else {
252*7296Ssam 				psp->ps_dbuffer.dbsize = arg;
253*7296Ssam 				psp->ps_dbuffer.dbaddrs[1] =
254*7296Ssam 						psp->ps_dbuffer.dbaddrs[0]+arg;
255*7296Ssam 				psp->ps_dbuffer.state = ON_DB;
256*7296Ssam 				psp->ps_dbuffer.rbuffer = 0;
257*7296Ssam 			}
258*7296Ssam 		}
259*7296Ssam 		break;
260*7296Ssam 	case PSSINGLEBUFFER:
261*7296Ssam 		psp->ps_dbuffer.state = OFF_DB;
262*7296Ssam 		break;
263*7296Ssam 	case PSWAITREFRESH:
264*7296Ssam 		if(psp->ps_refresh.mode != RUNNING_RF)	/* not running */
265*7296Ssam 			return;				/* dont wait */
266*7296Ssam 	case PSSTOPREFRESH:
267*7296Ssam 		if(cmd == PSSTOPREFRESH)
268*7296Ssam 			psp->ps_refresh.stop = 1;
269*7296Ssam 		spl5();
270*7296Ssam 		psp->ps_refresh.waiting = 1;
271*7296Ssam 		while(psp->ps_refresh.waiting)
272*7296Ssam 			sleep(&psp->ps_refresh.waiting, PSPRI);
273*7296Ssam 		spl0();
274*7296Ssam 		break;
275*7296Ssam 	case PSWAITMAP:
276*7296Ssam 		if(psp->ps_map.mode != RUNNING_MAP)	/* not running */
277*7296Ssam 			return;				/* dont wait */
278*7296Ssam 	case PSSTOPMAP:
279*7296Ssam 		if(cmd == PSSTOPMAP)
280*7296Ssam 			psp->ps_map.stop = 1;
281*7296Ssam 		spl5();
282*7296Ssam 		psp->ps_map.waiting = 1;
283*7296Ssam 		while(psp->ps_map.waiting)
284*7296Ssam 			sleep(&psp->ps_map.waiting, PSPRI);
285*7296Ssam 		spl0();
286*7296Ssam 		break;
287*7296Ssam 	default:
288*7296Ssam 		u.u_error = ENOTTY;	/* Not a legal ioctl cmd. */
289*7296Ssam 		break;
290*7296Ssam 	}
291*7296Ssam }
292*7296Ssam 
293*7296Ssam #define SAVEPSADDR() {register short int i, x;x=spl6();i=psaddr->ps_addr;\
294*7296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
295*7296Ssam 		savepsaddr=psaddr->ps_data;splx(x);}
296*7296Ssam #define RESTORPSADDR() {register int x,i;x=spl6();\
297*7296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
298*7296Ssam 		psaddr->ps_addr=savepsaddr;splx(x);}
299*7296Ssam 
300*7296Ssam psclockintr(dev)
301*7296Ssam 	dev_t dev;
302*7296Ssam {
303*7296Ssam 	register struct psdevice *psaddr =
304*7296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
305*7296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
306*7296Ssam 	int savepsaddr;
307*7296Ssam 
308*7296Ssam 	if(!psp->ps_open)
309*7296Ssam 		return;
310*7296Ssam 	psp->ps_clock.icnt++;
311*7296Ssam 	SAVEPSADDR();
312*7296Ssam #ifndef EXTERNAL_SYNC
313*7296Ssam 	if(psp->ps_refresh.state == AUTO_RF) {
314*7296Ssam 		if(psp->ps_refresh.mode == SYNCING_RF) {
315*7296Ssam 			psrfnext(psp, psaddr);
316*7296Ssam 		} else {
317*7296Ssam 			psp->ps_clock.ticked++;
318*7296Ssam 			psp->ps_clock.missed++;
319*7296Ssam 		}
320*7296Ssam 	}
321*7296Ssam #endif
322*7296Ssam 	PSWAIT();
323*7296Ssam 	psaddr->ps_addr = RTCREQ;
324*7296Ssam 	PSWAIT();
325*7296Ssam 	psaddr->ps_data = 01;		/* clear the request bits */
326*7296Ssam 	RESTORPSADDR();
327*7296Ssam }
328*7296Ssam 
329*7296Ssam /*ARGSUSED*/
330*7296Ssam pssystemintr(dev)
331*7296Ssam 	dev_t dev;
332*7296Ssam {
333*7296Ssam 	register struct psdevice *psaddr =
334*7296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
335*7296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
336*7296Ssam 	short int request;
337*7296Ssam 	register int savepsaddr, x;
338*7296Ssam 
339*7296Ssam 	if(!psp->ps_open)
340*7296Ssam 		return;
341*7296Ssam 	SAVEPSADDR();
342*7296Ssam 	PSWAIT();
343*7296Ssam 	psaddr->ps_addr = SYSREQ;
344*7296Ssam 	PSWAIT();
345*7296Ssam 	request = psaddr->ps_data;
346*7296Ssam 	psp->last_request = request;
347*7296Ssam 	PSWAIT();
348*7296Ssam 	psaddr->ps_addr = SYSREQ;
349*7296Ssam 	PSWAIT();
350*7296Ssam 	psaddr->ps_data = request&(~(HALT_REQ|MOSTOP_REQ));   /* acknowledge */
351*7296Ssam 
352*7296Ssam 	if(request & (MOSTOP_REQ|HALT_REQ)) {	/* Map stopped */
353*7296Ssam 		psp->ps_map.icnt++;
354*7296Ssam 		psmapstop(psaddr);		/* kill it dead */
355*7296Ssam 		if(psp->ps_map.waiting) {
356*7296Ssam 			psp->ps_map.waiting = 0;
357*7296Ssam 			wakeup(&psp->ps_map.waiting);
358*7296Ssam 			if(psp->ps_map.stop) {
359*7296Ssam 				psp->ps_map.stop = 0;
360*7296Ssam 				goto tryrf;
361*7296Ssam 			}
362*7296Ssam 		}
363*7296Ssam 		if(psp->ps_map.state == AUTO_MAP)
364*7296Ssam 			if(!psmapnext(psp, psaddr)) {
365*7296Ssam 				psp->ps_map.mcntr = 0;
366*7296Ssam 				/* prepare for next round */
367*7296Ssam 				pssetmapbounds(psp, psaddr);
368*7296Ssam 				if(psp->ps_refresh.mode == WAITING_MAP) {
369*7296Ssam 					if(psp->ps_dbuffer.state == ON_DB)
370*7296Ssam 						/* fill other db */
371*7296Ssam 						psdbswitch(psp, psaddr);
372*7296Ssam 					else
373*7296Ssam 						psp->ps_map.mode = WAITING_RF;
374*7296Ssam 					psrfnext(psp, psaddr);	/* start rf */
375*7296Ssam 				} else
376*7296Ssam 					psp->ps_map.mode = WAITING_RF;
377*7296Ssam 			}
378*7296Ssam 	}
379*7296Ssam tryrf:
380*7296Ssam 	if(request & RFSTOP_REQ) {		/* Refresh stopped */
381*7296Ssam 		psp->ps_refresh.icnt++;
382*7296Ssam 		psrfstop(psaddr, psp);
383*7296Ssam 		if(psp->ps_refresh.waiting) {
384*7296Ssam 			psp->ps_refresh.waiting = 0;
385*7296Ssam 			wakeup(&psp->ps_refresh.waiting);
386*7296Ssam 			if(psp->ps_refresh.stop) {
387*7296Ssam 				psp->ps_refresh.stop = 0;
388*7296Ssam 				goto tryhit;
389*7296Ssam 			}
390*7296Ssam 		}
391*7296Ssam 		if(psp->ps_refresh.state == AUTO_RF)
392*7296Ssam 			if(!psrfnext(psp, psaddr)) {	/* at end of refresh cycle */
393*7296Ssam 				if(psp->ps_map.state == AUTO_MAP &&
394*7296Ssam 						psp->ps_map.mode==WAITING_RF) {
395*7296Ssam 					if(psp->ps_dbuffer.state == ON_DB)
396*7296Ssam 						psdbswitch(psp, psaddr);
397*7296Ssam 					else
398*7296Ssam 						psmapnext(psp, psaddr);
399*7296Ssam 				}
400*7296Ssam 				psp->ps_refresh.srcntr = 0;
401*7296Ssam #ifdef EXTERNAL_SYNC
402*7296Ssam 				x = spl6();
403*7296Ssam #endif
404*7296Ssam 				if(!psp->ps_clock.ticked ||
405*7296Ssam 						!psrfnext(psp, psaddr)) {
406*7296Ssam 					psp->ps_refresh.mode = SYNCING_RF;
407*7296Ssam 				}
408*7296Ssam 				psp->ps_clock.ticked = 0;
409*7296Ssam 				psp->ps_refresh.mode = SYNCING_RF;
410*7296Ssam #ifdef EXTERNAL_SYNC
411*7296Ssam 				splx(x);
412*7296Ssam #endif
413*7296Ssam 			}
414*7296Ssam 	}
415*7296Ssam tryhit:
416*7296Ssam 	if(request & HIT_REQ) {		/* Hit request */
417*7296Ssam 		psp->ps_hit.icnt++;
418*7296Ssam 	}
419*7296Ssam 	if(request == 0)
420*7296Ssam 		psp->ps_strayintr++;
421*7296Ssam 	RESTORPSADDR();
422*7296Ssam }
423*7296Ssam 
424*7296Ssam psrfnext(psp, psaddr)
425*7296Ssam 	register struct ps *psp;
426*7296Ssam 	register struct psdevice *psaddr;
427*7296Ssam {
428*7296Ssam 
429*7296Ssam 	if(psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs)
430*7296Ssam 		psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
431*7296Ssam 						psp, psaddr);
432*7296Ssam 	else if(psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs
433*7296Ssam 				&& psp->ps_dbuffer.state == ON_DB) {
434*7296Ssam 		psrfstart(psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer],
435*7296Ssam 						psp, psaddr);
436*7296Ssam 		psp->ps_refresh.srcntr++;	/* flag for after dbuffer */
437*7296Ssam 	} else
438*7296Ssam 		return(0);
439*7296Ssam 	return(1);
440*7296Ssam }
441*7296Ssam 
442*7296Ssam psrfstart(dfaddr, psp, psaddr)
443*7296Ssam 	short int dfaddr;
444*7296Ssam 	register struct ps *psp;
445*7296Ssam 	register struct psdevice *psaddr;
446*7296Ssam {
447*7296Ssam 	int dummy;
448*7296Ssam 
449*7296Ssam 	PSWAIT();
450*7296Ssam 	psaddr->ps_addr = RFASA;
451*7296Ssam 	PSWAIT();
452*7296Ssam 	psaddr->ps_data = dfaddr;
453*7296Ssam 	PSWAIT();
454*7296Ssam 	dummy = psaddr->ps_data;	/* just access to get to status reg */
455*7296Ssam 	PSWAIT();
456*7296Ssam 	psaddr->ps_data = RFSTART;	/* may want to | this value in */
457*7296Ssam 	psp->ps_refresh.mode = RUNNING_RF;
458*7296Ssam }
459*7296Ssam 
460*7296Ssam psrfstop(psaddr, psp)
461*7296Ssam 	register struct psdevice *psaddr;
462*7296Ssam 	register struct ps *psp;
463*7296Ssam {
464*7296Ssam 
465*7296Ssam 	PSWAIT();
466*7296Ssam 	psaddr->ps_addr = RFSR;
467*7296Ssam 	PSWAIT();
468*7296Ssam 	psaddr->ps_data = 0;
469*7296Ssam }
470*7296Ssam 
471*7296Ssam psdbswitch(psp, psaddr)
472*7296Ssam 	register struct ps *psp;
473*7296Ssam 	register struct psdevice *psaddr;
474*7296Ssam {
475*7296Ssam 
476*7296Ssam 	psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
477*7296Ssam 	pssetmapbounds(psp, psaddr);
478*7296Ssam 	psmapnext(psp, psaddr);
479*7296Ssam }
480*7296Ssam 
481*7296Ssam psmapnext(psp, psaddr)
482*7296Ssam 	register struct ps *psp;
483*7296Ssam 	register struct psdevice *psaddr;
484*7296Ssam {
485*7296Ssam 
486*7296Ssam 	if(psp->ps_map.mcntr < psp->ps_map.nmaddrs)
487*7296Ssam 		psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr);
488*7296Ssam 	else
489*7296Ssam 		return(0);
490*7296Ssam 	return(1);
491*7296Ssam }
492*7296Ssam 
493*7296Ssam pssetmapbounds(psp, psaddr)
494*7296Ssam 	register struct ps *psp;
495*7296Ssam 	register struct psdevice *psaddr;
496*7296Ssam {
497*7296Ssam 	unsigned short int start;
498*7296Ssam 
499*7296Ssam 	PSWAIT();
500*7296Ssam 	psaddr->ps_addr = MAOL;
501*7296Ssam 	PSWAIT();
502*7296Ssam 	if(psp->ps_dbuffer.state == ON_DB) {
503*7296Ssam 		psaddr->ps_data = (start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer])
504*7296Ssam 				+psp->ps_dbuffer.dbsize-2;   /* 2 for a refresh halt command */
505*7296Ssam 		PSWAIT();
506*7296Ssam 		psaddr->ps_data = start;
507*7296Ssam 	} else {
508*7296Ssam 		start = psaddr->ps_data;	/* dummy: don't update limit */
509*7296Ssam 		PSWAIT();
510*7296Ssam 		psaddr->ps_data = psp->ps_map.outputstart;
511*7296Ssam 	}
512*7296Ssam }
513*7296Ssam 
514*7296Ssam psmapstart(dfaddr, psp, psaddr)
515*7296Ssam 	int dfaddr;
516*7296Ssam 	register struct ps *psp;
517*7296Ssam 	register struct psdevice *psaddr;
518*7296Ssam {
519*7296Ssam 	int data;
520*7296Ssam 
521*7296Ssam 	PSWAIT();
522*7296Ssam 	psaddr->ps_addr = MAIA;
523*7296Ssam 	PSWAIT();
524*7296Ssam 	psaddr->ps_data = dfaddr;
525*7296Ssam 	PSWAIT();
526*7296Ssam 	psaddr->ps_data = MAO|MAI;	/* may want more here */
527*7296Ssam 	psp->ps_map.mode = RUNNING_MAP;
528*7296Ssam }
529*7296Ssam 
530*7296Ssam psmapstop(psaddr)
531*7296Ssam 	register struct psdevice *psaddr;
532*7296Ssam {
533*7296Ssam 
534*7296Ssam 	PSWAIT();
535*7296Ssam 	psaddr->ps_addr = MASR;
536*7296Ssam 	PSWAIT();
537*7296Ssam 	psaddr->ps_data = 0;	/* zero MAI bit */
538*7296Ssam 	PSWAIT();
539*7296Ssam 	psaddr->ps_addr = MAIA;
540*7296Ssam 	PSWAIT();
541*7296Ssam 	psaddr->ps_data = 0;	/* zero input address register */
542*7296Ssam 	PSWAIT();
543*7296Ssam 	psaddr->ps_addr = SYSREQ;
544*7296Ssam 	PSWAIT();
545*7296Ssam 	psaddr->ps_data = HALT_REQ|MOSTOP_REQ;	/* overkill?? */
546*7296Ssam }
547*7296Ssam 
548*7296Ssam /*ARGSUSED*/
549*7296Ssam psdeviceintr(dev)
550*7296Ssam 	dev_t dev;
551*7296Ssam {
552*7296Ssam 
553*7296Ssam 	printf("ps device intr\n");
554*7296Ssam }
555*7296Ssam 
556*7296Ssam /*ARGSUSED*/
557*7296Ssam psdmaintr(dev)
558*7296Ssam 	dev_t dev;
559*7296Ssam {
560*7296Ssam 
561*7296Ssam 	printf("ps dma intr\n");
562*7296Ssam }
563*7296Ssam 
564*7296Ssam psreset(uban)
565*7296Ssam 	int uban;
566*7296Ssam {
567*7296Ssam }
568*7296Ssam 
569*7296Ssam psextsync(PC, PS) {
570*7296Ssam 	register int n;
571*7296Ssam 	register struct psdevice *psaddr;
572*7296Ssam 	register struct ps *psp;
573*7296Ssam 	register int savepsaddr;
574*7296Ssam 
575*7296Ssam #ifdef EXTERNAL_SYNC
576*7296Ssam 	for(psp = ps, n = 0; n < NPS; psp++, n++) {
577*7296Ssam 		if(!psp->ps_open)
578*7296Ssam 			continue;
579*7296Ssam 		if(psp->ps_refresh.mode == SYNCING_RF) {
580*7296Ssam 			psaddr = (struct psdevice *) psdinfo[n]->ui_addr;
581*7296Ssam 			SAVEPSADDR();
582*7296Ssam 			psrfnext(psp, psaddr);
583*7296Ssam 			RESTORPSADDR();
584*7296Ssam 		} else {
585*7296Ssam 			psp->ps_clock.ticked++;
586*7296Ssam 			psp->ps_clock.missed++;
587*7296Ssam 		}
588*7296Ssam 	}
589*7296Ssam #endif
590*7296Ssam }
591*7296Ssam #endif
592