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