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