xref: /csrg-svn/sys/vax/uba/ps.c (revision 7632)
1*7632Ssam /*	ps.c	4.3	82/08/01	*/
27296Ssam 
37296Ssam /*
47296Ssam  * Evans and Sutherland Picture System 2 driver
57296Ssam  */
67296Ssam 
77296Ssam /*
87296Ssam  *	Still to be done:
97296Ssam  *		WAIT_HIT
107296Ssam  */
117296Ssam 
127296Ssam #include "ps.h"
137296Ssam #if NPS > 0
147296Ssam 
157296Ssam #define EXTERNAL_SYNC
167296Ssam 
177296Ssam #include "../h/param.h"
187296Ssam #include "../h/systm.h"
197296Ssam #include "../h/tty.h"
207296Ssam #include "../h/pte.h"
217296Ssam #include "../h/map.h"
227296Ssam #include "../h/buf.h"
237296Ssam #include "../h/ubareg.h"
247296Ssam #include "../h/ubavar.h"
257296Ssam #include "../h/conf.h"
267296Ssam #include "../h/dir.h"
277296Ssam #include "../h/user.h"
287296Ssam #include "../h/psreg.h"
297296Ssam 
307296Ssam int	psprobe(), psattach(), psintr();
317296Ssam struct	uba_device *psdinfo[NPS];
327296Ssam u_short	psstd[] = { 0 };
337296Ssam struct	uba_driver psdriver =
347296Ssam     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
357296Ssam 
367296Ssam #define	PSUNIT(dev)	(minor(dev))
377296Ssam 
387296Ssam #define MAXAUTOREFRESH			(4)
397296Ssam #define MAXAUTOMAP			(4)
407296Ssam #define MAXDBSIZE			(0177777/2)
417296Ssam 
427296Ssam #define PSPRI				(PZERO+1)
437296Ssam 
447296Ssam #define PSWAIT() {register short int i, j; i=20000; while((i-- != 0)\
457296Ssam 	&& (((j=psaddr->ps_iostat)&DIOREADY)==0));}
467296Ssam 
477296Ssam struct ps {
487296Ssam 	char		ps_open;
497296Ssam 	short int 	ps_uid;
507296Ssam 	struct {
517296Ssam 		enum { SINGLE_STEP_RF, AUTO_RF } state;
527296Ssam 		enum { RUNNING_RF, SYNCING_RF, WAITING_MAP } mode;
537296Ssam 		unsigned short int sraddrs[MAXAUTOREFRESH];
547296Ssam 		short int nsraddrs;
557296Ssam 		short int srcntr;
567296Ssam 		char waiting;
577296Ssam 		char stop;
587296Ssam 		int icnt;
597296Ssam 	} ps_refresh;
607296Ssam 	struct {
617296Ssam 		enum { ON_DB, OFF_DB } state;
627296Ssam 		unsigned short int dbaddrs[2];
637296Ssam 		unsigned short int dbsize;
647296Ssam 		short int rbuffer;
657296Ssam 	} ps_dbuffer;
667296Ssam 	struct {
677296Ssam 		enum { SINGLE_STEP_MAP, AUTO_MAP } state;
687296Ssam 		enum { RUNNING_MAP, WAITING_RF, WAITING_START } mode;
697296Ssam 		unsigned short int maddrs[MAXAUTOMAP];
707296Ssam 		short int nmaddrs;
717296Ssam 		short int mcntr;
727296Ssam 		short int outputstart;
737296Ssam 		char waiting;
747296Ssam 		char stop;
757296Ssam 		int icnt;
767296Ssam 	} ps_map;
777296Ssam 	struct {
787296Ssam 		short int ticked;
797296Ssam 		short int missed;
807296Ssam 		int icnt;
817296Ssam 	} ps_clock;
827296Ssam 	struct {
837296Ssam 		int icnt;
847296Ssam 	} ps_hit;
857296Ssam 	int ps_strayintr;
867296Ssam 	int last_request;
877296Ssam 	int strayrequest;
887296Ssam } ps[NPS];
897296Ssam 
907296Ssam psprobe(reg)
917296Ssam 	caddr_t reg;
927296Ssam {
937296Ssam 	register int br, cvec;
947296Ssam 	register struct psdevice *psaddr = (struct psdevice *) reg;
957296Ssam 
967296Ssam 	psaddr->ps_iostat = PSRESET;
977296Ssam 	DELAY(200);
987296Ssam 	psaddr->ps_addr = RTCIE;
997296Ssam 	PSWAIT();
1007296Ssam 	psaddr->ps_data = 01;
1017296Ssam 	psaddr->ps_iostat = PSIE;
1027296Ssam 	psaddr->ps_addr = RTCSR;
1037296Ssam 	PSWAIT();
1047296Ssam 	psaddr->ps_data = (SYNC|RUN);
1057296Ssam 	DELAY(200000);
1067296Ssam 	psaddr->ps_addr = RTCREQ;
1077296Ssam 	PSWAIT();
1087296Ssam 	psaddr->ps_data = 01;
1097296Ssam 	psaddr->ps_iostat = 0;
1107296Ssam 	psaddr->ps_iostat = PSRESET;
1117418Skre 	return (sizeof (struct psdevice));
1127296Ssam }
1137296Ssam 
1147296Ssam /*ARGSUSED*/
1157296Ssam psattach(ui)
1167296Ssam 	register struct uba_device *ui;
1177296Ssam {
1187296Ssam }
1197296Ssam 
1207296Ssam 
1217296Ssam psopen(dev)
1227296Ssam 	dev_t dev;
1237296Ssam {
1247296Ssam 	register struct ps *psp;
1257296Ssam 	register struct uba_device *ui;
1267296Ssam 	register int unit = PSUNIT(dev);
1277296Ssam 
1287296Ssam 	if(unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
1297296Ssam 			(ui = psdinfo[unit]) == 0 || ui->ui_alive == 0) {
1307296Ssam 		u.u_error = ENXIO;
1317296Ssam 		return;
1327296Ssam 	}
1337296Ssam 	psp->ps_open = 1;
1347296Ssam 	psp->ps_uid = u.u_uid;
1357296Ssam 	psp->ps_strayintr = 0;
1367296Ssam 	psp->ps_refresh.state = SINGLE_STEP_RF;
1377296Ssam 	psp->ps_refresh.waiting = 0;
1387296Ssam 	psp->ps_refresh.stop = 0;
1397296Ssam 	psp->ps_dbuffer.state = OFF_DB;
1407296Ssam 	psp->ps_map.state = SINGLE_STEP_MAP;
1417296Ssam 	psp->ps_map.waiting = 0;
1427296Ssam 	psp->ps_map.stop = 0;
1437296Ssam 	psp->ps_clock.ticked = 0;
1447296Ssam 	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0;
1457296Ssam 	maptouser(ui->ui_addr);
1467296Ssam }
1477296Ssam 
1487296Ssam psclose(dev)
1497296Ssam 	dev_t dev;
1507296Ssam {
1517296Ssam 	register struct psdevice *psaddr =
1527296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
1537296Ssam 
1547296Ssam 	ps[PSUNIT(dev)].ps_open = 0;
1557296Ssam 	psaddr->ps_iostat = 0;		/* clear IENABLE */
1567296Ssam 	PSWAIT();
1577296Ssam 	psaddr->ps_addr = RFSR;		/* set in auto refresh mode */
1587296Ssam 	PSWAIT();
1597296Ssam 	psaddr->ps_data = AUTOREF;
1607296Ssam 	unmaptouser(psaddr);
1617296Ssam }
1627296Ssam 
1637296Ssam /*ARGSUSED*/
1647296Ssam psread(dev)
1657296Ssam 	dev_t dev;
1667296Ssam {
1677296Ssam }
1687296Ssam 
1697296Ssam /*ARGSUSED*/
1707296Ssam pswrite(dev)
1717296Ssam 	dev_t dev;
1727296Ssam {
1737296Ssam }
1747296Ssam 
1757296Ssam /*ARGSUSED*/
176*7632Ssam psioctl(dev, cmd, data, flag)
177*7632Ssam 	register caddr_t data;
1787296Ssam {
1797296Ssam 	register struct uba_device *ui = psdinfo[PSUNIT(dev)];
1807296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
181*7632Ssam 	int *waddr = *(int **)data;
1827296Ssam 	int n, arg, i;
1837296Ssam 
1847296Ssam 	switch (cmd) {
185*7632Ssam 
186*7632Ssam 	case PSIOGETADDR:
187*7632Ssam 		*(caddr_t *)data = ui->ui_addr;
1887296Ssam 		break;
189*7632Ssam 
190*7632Ssam 	case PSIOAUTOREFRESH:
1917296Ssam 		n = fuword(waddr++);
1927296Ssam 		if(n == -1)
1937296Ssam 			u.u_error = EFAULT;
1947296Ssam 		else if(n < 0 || n > MAXAUTOREFRESH)
1957296Ssam 			u.u_error = EINVAL;
1967296Ssam 		else {
1977296Ssam 			for(i = 0; i < n; i++)
1987296Ssam 				if((arg = fuword(waddr++)) == -1) {
1997296Ssam 					u.u_error = EFAULT;
2007296Ssam 					break;
2017296Ssam 				}
2027296Ssam 				else
2037296Ssam 					psp->ps_refresh.sraddrs[i] = arg;
2047296Ssam 			if(!u.u_error) {
2057296Ssam 				psp->ps_refresh.state = AUTO_RF;
2067296Ssam 				psp->ps_refresh.nsraddrs = n;
2077296Ssam 				psp->ps_refresh.srcntr = 0;
2087296Ssam 				psp->ps_refresh.mode = WAITING_MAP;
2097296Ssam 			}
2107296Ssam 		}
2117296Ssam 		break;
212*7632Ssam 
213*7632Ssam 	case PSIOAUTOMAP:
2147296Ssam 		n = fuword(waddr++);
2157296Ssam 		if(n == -1)
2167296Ssam 			u.u_error = EFAULT;
2177296Ssam 		else if(n < 0 || n > MAXAUTOMAP)
2187296Ssam 			u.u_error = EINVAL;
2197296Ssam 		else {
2207296Ssam 			for(i = 0; i < n; i++)
2217296Ssam 				if((arg = fuword(waddr++)) == -1) {
2227296Ssam 					u.u_error = EFAULT;
2237296Ssam 					break;
2247296Ssam 				}
2257296Ssam 				else
2267296Ssam 					psp->ps_map.maddrs[i] = arg;
2277296Ssam 			if(!u.u_error)
2287296Ssam 				if((arg = fuword(waddr++)) == -1)
2297296Ssam 					u.u_error = EFAULT;
2307296Ssam 				else
2317296Ssam 					psp->ps_map.outputstart = arg;
2327296Ssam 			if(!u.u_error) {
2337296Ssam 				psp->ps_map.state = AUTO_MAP;
2347296Ssam 				psp->ps_map.nmaddrs = n;
2357296Ssam 				psp->ps_map.mcntr = 0;
2367296Ssam 				psp->ps_map.mode = WAITING_START;
2377296Ssam 			}
2387296Ssam 		}
2397296Ssam 		break;
240*7632Ssam 
241*7632Ssam 	case PSIOSINGLEREFRESH:
2427296Ssam 		psp->ps_refresh.state = SINGLE_STEP_RF;
2437296Ssam 		break;
244*7632Ssam 
245*7632Ssam 	case PSIOSINGLEMAP:
2467296Ssam 		psp->ps_map.state = SINGLE_STEP_MAP;
2477296Ssam 		break;
248*7632Ssam 
249*7632Ssam 	case PSIODOUBLEBUFFER:
2507296Ssam 		if((arg = fuword(waddr++)) == -1)
2517296Ssam 			u.u_error = EFAULT;
2527296Ssam 		else {
2537296Ssam 			psp->ps_dbuffer.dbaddrs[0] = arg;
2547296Ssam 			if((arg = fuword(waddr++)) == -1)
2557296Ssam 				u.u_error = EFAULT;
2567296Ssam 			else if(arg <= 0 || arg > MAXDBSIZE)
2577296Ssam 				u.u_error = EINVAL;
2587296Ssam 			else {
2597296Ssam 				psp->ps_dbuffer.dbsize = arg;
2607296Ssam 				psp->ps_dbuffer.dbaddrs[1] =
2617296Ssam 						psp->ps_dbuffer.dbaddrs[0]+arg;
2627296Ssam 				psp->ps_dbuffer.state = ON_DB;
2637296Ssam 				psp->ps_dbuffer.rbuffer = 0;
2647296Ssam 			}
2657296Ssam 		}
2667296Ssam 		break;
267*7632Ssam 
268*7632Ssam 	case PSIOSINGLEBUFFER:
2697296Ssam 		psp->ps_dbuffer.state = OFF_DB;
2707296Ssam 		break;
271*7632Ssam 
272*7632Ssam 	case PSIOWAITREFRESH:
2737296Ssam 		if(psp->ps_refresh.mode != RUNNING_RF)	/* not running */
2747296Ssam 			return;				/* dont wait */
275*7632Ssam 
276*7632Ssam 	case PSSIOTOPREFRESH:
2777296Ssam 		if(cmd == PSSTOPREFRESH)
2787296Ssam 			psp->ps_refresh.stop = 1;
2797296Ssam 		spl5();
2807296Ssam 		psp->ps_refresh.waiting = 1;
2817296Ssam 		while(psp->ps_refresh.waiting)
2827296Ssam 			sleep(&psp->ps_refresh.waiting, PSPRI);
2837296Ssam 		spl0();
2847296Ssam 		break;
285*7632Ssam 
286*7632Ssam 	case PSIOWAITMAP:
2877296Ssam 		if(psp->ps_map.mode != RUNNING_MAP)	/* not running */
2887296Ssam 			return;				/* dont wait */
289*7632Ssam 
290*7632Ssam 	case PSIOSTOPMAP:
2917296Ssam 		if(cmd == PSSTOPMAP)
2927296Ssam 			psp->ps_map.stop = 1;
2937296Ssam 		spl5();
2947296Ssam 		psp->ps_map.waiting = 1;
2957296Ssam 		while(psp->ps_map.waiting)
2967296Ssam 			sleep(&psp->ps_map.waiting, PSPRI);
2977296Ssam 		spl0();
2987296Ssam 		break;
299*7632Ssam 
3007296Ssam 	default:
3017296Ssam 		u.u_error = ENOTTY;	/* Not a legal ioctl cmd. */
3027296Ssam 		break;
3037296Ssam 	}
3047296Ssam }
3057296Ssam 
3067296Ssam #define SAVEPSADDR() {register short int i, x;x=spl6();i=psaddr->ps_addr;\
3077296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
3087296Ssam 		savepsaddr=psaddr->ps_data;splx(x);}
3097296Ssam #define RESTORPSADDR() {register int x,i;x=spl6();\
3107296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
3117296Ssam 		psaddr->ps_addr=savepsaddr;splx(x);}
3127296Ssam 
3137296Ssam psclockintr(dev)
3147296Ssam 	dev_t dev;
3157296Ssam {
3167296Ssam 	register struct psdevice *psaddr =
3177296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3187296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
3197296Ssam 	int savepsaddr;
3207296Ssam 
3217296Ssam 	if(!psp->ps_open)
3227296Ssam 		return;
3237296Ssam 	psp->ps_clock.icnt++;
3247296Ssam 	SAVEPSADDR();
3257296Ssam #ifndef EXTERNAL_SYNC
3267296Ssam 	if(psp->ps_refresh.state == AUTO_RF) {
3277296Ssam 		if(psp->ps_refresh.mode == SYNCING_RF) {
3287296Ssam 			psrfnext(psp, psaddr);
3297296Ssam 		} else {
3307296Ssam 			psp->ps_clock.ticked++;
3317296Ssam 			psp->ps_clock.missed++;
3327296Ssam 		}
3337296Ssam 	}
3347296Ssam #endif
3357296Ssam 	PSWAIT();
3367296Ssam 	psaddr->ps_addr = RTCREQ;
3377296Ssam 	PSWAIT();
3387296Ssam 	psaddr->ps_data = 01;		/* clear the request bits */
3397296Ssam 	RESTORPSADDR();
3407296Ssam }
3417296Ssam 
3427296Ssam /*ARGSUSED*/
3437296Ssam pssystemintr(dev)
3447296Ssam 	dev_t dev;
3457296Ssam {
3467296Ssam 	register struct psdevice *psaddr =
3477296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3487296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
3497296Ssam 	short int request;
3507296Ssam 	register int savepsaddr, x;
3517296Ssam 
3527296Ssam 	if(!psp->ps_open)
3537296Ssam 		return;
3547296Ssam 	SAVEPSADDR();
3557296Ssam 	PSWAIT();
3567296Ssam 	psaddr->ps_addr = SYSREQ;
3577296Ssam 	PSWAIT();
3587296Ssam 	request = psaddr->ps_data;
3597296Ssam 	psp->last_request = request;
3607296Ssam 	PSWAIT();
3617296Ssam 	psaddr->ps_addr = SYSREQ;
3627296Ssam 	PSWAIT();
3637296Ssam 	psaddr->ps_data = request&(~(HALT_REQ|MOSTOP_REQ));   /* acknowledge */
3647296Ssam 
3657296Ssam 	if(request & (MOSTOP_REQ|HALT_REQ)) {	/* Map stopped */
3667296Ssam 		psp->ps_map.icnt++;
3677296Ssam 		psmapstop(psaddr);		/* kill it dead */
3687296Ssam 		if(psp->ps_map.waiting) {
3697296Ssam 			psp->ps_map.waiting = 0;
3707296Ssam 			wakeup(&psp->ps_map.waiting);
3717296Ssam 			if(psp->ps_map.stop) {
3727296Ssam 				psp->ps_map.stop = 0;
3737296Ssam 				goto tryrf;
3747296Ssam 			}
3757296Ssam 		}
3767296Ssam 		if(psp->ps_map.state == AUTO_MAP)
3777296Ssam 			if(!psmapnext(psp, psaddr)) {
3787296Ssam 				psp->ps_map.mcntr = 0;
3797296Ssam 				/* prepare for next round */
3807296Ssam 				pssetmapbounds(psp, psaddr);
3817296Ssam 				if(psp->ps_refresh.mode == WAITING_MAP) {
3827296Ssam 					if(psp->ps_dbuffer.state == ON_DB)
3837296Ssam 						/* fill other db */
3847296Ssam 						psdbswitch(psp, psaddr);
3857296Ssam 					else
3867296Ssam 						psp->ps_map.mode = WAITING_RF;
3877296Ssam 					psrfnext(psp, psaddr);	/* start rf */
3887296Ssam 				} else
3897296Ssam 					psp->ps_map.mode = WAITING_RF;
3907296Ssam 			}
3917296Ssam 	}
3927296Ssam tryrf:
3937296Ssam 	if(request & RFSTOP_REQ) {		/* Refresh stopped */
3947296Ssam 		psp->ps_refresh.icnt++;
3957296Ssam 		psrfstop(psaddr, psp);
3967296Ssam 		if(psp->ps_refresh.waiting) {
3977296Ssam 			psp->ps_refresh.waiting = 0;
3987296Ssam 			wakeup(&psp->ps_refresh.waiting);
3997296Ssam 			if(psp->ps_refresh.stop) {
4007296Ssam 				psp->ps_refresh.stop = 0;
4017296Ssam 				goto tryhit;
4027296Ssam 			}
4037296Ssam 		}
4047296Ssam 		if(psp->ps_refresh.state == AUTO_RF)
4057296Ssam 			if(!psrfnext(psp, psaddr)) {	/* at end of refresh cycle */
4067296Ssam 				if(psp->ps_map.state == AUTO_MAP &&
4077296Ssam 						psp->ps_map.mode==WAITING_RF) {
4087296Ssam 					if(psp->ps_dbuffer.state == ON_DB)
4097296Ssam 						psdbswitch(psp, psaddr);
4107296Ssam 					else
4117296Ssam 						psmapnext(psp, psaddr);
4127296Ssam 				}
4137296Ssam 				psp->ps_refresh.srcntr = 0;
4147296Ssam #ifdef EXTERNAL_SYNC
4157296Ssam 				x = spl6();
4167296Ssam #endif
4177296Ssam 				if(!psp->ps_clock.ticked ||
4187296Ssam 						!psrfnext(psp, psaddr)) {
4197296Ssam 					psp->ps_refresh.mode = SYNCING_RF;
4207296Ssam 				}
4217296Ssam 				psp->ps_clock.ticked = 0;
4227296Ssam 				psp->ps_refresh.mode = SYNCING_RF;
4237296Ssam #ifdef EXTERNAL_SYNC
4247296Ssam 				splx(x);
4257296Ssam #endif
4267296Ssam 			}
4277296Ssam 	}
4287296Ssam tryhit:
4297296Ssam 	if(request & HIT_REQ) {		/* Hit request */
4307296Ssam 		psp->ps_hit.icnt++;
4317296Ssam 	}
4327296Ssam 	if(request == 0)
4337296Ssam 		psp->ps_strayintr++;
4347296Ssam 	RESTORPSADDR();
4357296Ssam }
4367296Ssam 
4377296Ssam psrfnext(psp, psaddr)
4387296Ssam 	register struct ps *psp;
4397296Ssam 	register struct psdevice *psaddr;
4407296Ssam {
4417296Ssam 
4427296Ssam 	if(psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs)
4437296Ssam 		psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
4447296Ssam 						psp, psaddr);
4457296Ssam 	else if(psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs
4467296Ssam 				&& psp->ps_dbuffer.state == ON_DB) {
4477296Ssam 		psrfstart(psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer],
4487296Ssam 						psp, psaddr);
4497296Ssam 		psp->ps_refresh.srcntr++;	/* flag for after dbuffer */
4507296Ssam 	} else
4517296Ssam 		return(0);
4527296Ssam 	return(1);
4537296Ssam }
4547296Ssam 
4557296Ssam psrfstart(dfaddr, psp, psaddr)
4567296Ssam 	short int dfaddr;
4577296Ssam 	register struct ps *psp;
4587296Ssam 	register struct psdevice *psaddr;
4597296Ssam {
4607296Ssam 	int dummy;
4617296Ssam 
4627296Ssam 	PSWAIT();
4637296Ssam 	psaddr->ps_addr = RFASA;
4647296Ssam 	PSWAIT();
4657296Ssam 	psaddr->ps_data = dfaddr;
4667296Ssam 	PSWAIT();
4677296Ssam 	dummy = psaddr->ps_data;	/* just access to get to status reg */
4687296Ssam 	PSWAIT();
4697296Ssam 	psaddr->ps_data = RFSTART;	/* may want to | this value in */
4707296Ssam 	psp->ps_refresh.mode = RUNNING_RF;
4717296Ssam }
4727296Ssam 
4737296Ssam psrfstop(psaddr, psp)
4747296Ssam 	register struct psdevice *psaddr;
4757296Ssam 	register struct ps *psp;
4767296Ssam {
4777296Ssam 
4787296Ssam 	PSWAIT();
4797296Ssam 	psaddr->ps_addr = RFSR;
4807296Ssam 	PSWAIT();
4817296Ssam 	psaddr->ps_data = 0;
4827296Ssam }
4837296Ssam 
4847296Ssam psdbswitch(psp, psaddr)
4857296Ssam 	register struct ps *psp;
4867296Ssam 	register struct psdevice *psaddr;
4877296Ssam {
4887296Ssam 
4897296Ssam 	psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
4907296Ssam 	pssetmapbounds(psp, psaddr);
4917296Ssam 	psmapnext(psp, psaddr);
4927296Ssam }
4937296Ssam 
4947296Ssam psmapnext(psp, psaddr)
4957296Ssam 	register struct ps *psp;
4967296Ssam 	register struct psdevice *psaddr;
4977296Ssam {
4987296Ssam 
4997296Ssam 	if(psp->ps_map.mcntr < psp->ps_map.nmaddrs)
5007296Ssam 		psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr);
5017296Ssam 	else
5027296Ssam 		return(0);
5037296Ssam 	return(1);
5047296Ssam }
5057296Ssam 
5067296Ssam pssetmapbounds(psp, psaddr)
5077296Ssam 	register struct ps *psp;
5087296Ssam 	register struct psdevice *psaddr;
5097296Ssam {
5107296Ssam 	unsigned short int start;
5117296Ssam 
5127296Ssam 	PSWAIT();
5137296Ssam 	psaddr->ps_addr = MAOL;
5147296Ssam 	PSWAIT();
5157296Ssam 	if(psp->ps_dbuffer.state == ON_DB) {
5167296Ssam 		psaddr->ps_data = (start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer])
5177296Ssam 				+psp->ps_dbuffer.dbsize-2;   /* 2 for a refresh halt command */
5187296Ssam 		PSWAIT();
5197296Ssam 		psaddr->ps_data = start;
5207296Ssam 	} else {
5217296Ssam 		start = psaddr->ps_data;	/* dummy: don't update limit */
5227296Ssam 		PSWAIT();
5237296Ssam 		psaddr->ps_data = psp->ps_map.outputstart;
5247296Ssam 	}
5257296Ssam }
5267296Ssam 
5277296Ssam psmapstart(dfaddr, psp, psaddr)
5287296Ssam 	int dfaddr;
5297296Ssam 	register struct ps *psp;
5307296Ssam 	register struct psdevice *psaddr;
5317296Ssam {
5327296Ssam 	int data;
5337296Ssam 
5347296Ssam 	PSWAIT();
5357296Ssam 	psaddr->ps_addr = MAIA;
5367296Ssam 	PSWAIT();
5377296Ssam 	psaddr->ps_data = dfaddr;
5387296Ssam 	PSWAIT();
5397296Ssam 	psaddr->ps_data = MAO|MAI;	/* may want more here */
5407296Ssam 	psp->ps_map.mode = RUNNING_MAP;
5417296Ssam }
5427296Ssam 
5437296Ssam psmapstop(psaddr)
5447296Ssam 	register struct psdevice *psaddr;
5457296Ssam {
5467296Ssam 
5477296Ssam 	PSWAIT();
5487296Ssam 	psaddr->ps_addr = MASR;
5497296Ssam 	PSWAIT();
5507296Ssam 	psaddr->ps_data = 0;	/* zero MAI bit */
5517296Ssam 	PSWAIT();
5527296Ssam 	psaddr->ps_addr = MAIA;
5537296Ssam 	PSWAIT();
5547296Ssam 	psaddr->ps_data = 0;	/* zero input address register */
5557296Ssam 	PSWAIT();
5567296Ssam 	psaddr->ps_addr = SYSREQ;
5577296Ssam 	PSWAIT();
5587296Ssam 	psaddr->ps_data = HALT_REQ|MOSTOP_REQ;	/* overkill?? */
5597296Ssam }
5607296Ssam 
5617296Ssam /*ARGSUSED*/
5627296Ssam psdeviceintr(dev)
5637296Ssam 	dev_t dev;
5647296Ssam {
5657296Ssam 
5667296Ssam 	printf("ps device intr\n");
5677296Ssam }
5687296Ssam 
5697296Ssam /*ARGSUSED*/
5707296Ssam psdmaintr(dev)
5717296Ssam 	dev_t dev;
5727296Ssam {
5737296Ssam 
5747296Ssam 	printf("ps dma intr\n");
5757296Ssam }
5767296Ssam 
5777296Ssam psreset(uban)
5787296Ssam 	int uban;
5797296Ssam {
5807296Ssam }
5817296Ssam 
5827296Ssam psextsync(PC, PS) {
5837296Ssam 	register int n;
5847296Ssam 	register struct psdevice *psaddr;
5857296Ssam 	register struct ps *psp;
5867296Ssam 	register int savepsaddr;
5877296Ssam 
5887296Ssam #ifdef EXTERNAL_SYNC
5897296Ssam 	for(psp = ps, n = 0; n < NPS; psp++, n++) {
5907296Ssam 		if(!psp->ps_open)
5917296Ssam 			continue;
5927296Ssam 		if(psp->ps_refresh.mode == SYNCING_RF) {
5937296Ssam 			psaddr = (struct psdevice *) psdinfo[n]->ui_addr;
5947296Ssam 			SAVEPSADDR();
5957296Ssam 			psrfnext(psp, psaddr);
5967296Ssam 			RESTORPSADDR();
5977296Ssam 		} else {
5987296Ssam 			psp->ps_clock.ticked++;
5997296Ssam 			psp->ps_clock.missed++;
6007296Ssam 		}
6017296Ssam 	}
6027296Ssam #endif
6037296Ssam }
6047296Ssam #endif
605