xref: /csrg-svn/sys/vax/uba/ps.c (revision 23511)
123334Smckusick /*
223334Smckusick  * Copyright (c) 1982 Regents of the University of California.
323334Smckusick  * All rights reserved.  The Berkeley software License Agreement
423334Smckusick  * specifies the terms and conditions for redistribution.
523334Smckusick  *
6*23511Ssam  *	@(#)ps.c	6.4 (Berkeley) 06/16/85
723334Smckusick  */
87296Ssam 
97296Ssam /*
10*23511Ssam  * Evans and Sutherland Picture System 2 driver -- Bill Reeves.
117296Ssam  */
127296Ssam 
137296Ssam /*
147296Ssam  *	Still to be done:
157296Ssam  *		WAIT_HIT
167296Ssam  */
177296Ssam 
187296Ssam #include "ps.h"
197296Ssam #if NPS > 0
207296Ssam 
217296Ssam #define EXTERNAL_SYNC
227296Ssam 
239776Ssam #include "../machine/pte.h"
249776Ssam 
2517075Sbloom #include "param.h"
2617075Sbloom #include "systm.h"
2717075Sbloom #include "ioctl.h"
2817075Sbloom #include "map.h"
2917075Sbloom #include "buf.h"
3017075Sbloom #include "conf.h"
3117075Sbloom #include "dir.h"
3217075Sbloom #include "user.h"
3317075Sbloom #include "uio.h"
347296Ssam 
3517075Sbloom #include "ubareg.h"
3617075Sbloom #include "ubavar.h"
3717075Sbloom #include "psreg.h"
388477Sroot 
397296Ssam int	psprobe(), psattach(), psintr();
407296Ssam struct	uba_device *psdinfo[NPS];
417296Ssam u_short	psstd[] = { 0 };
427296Ssam struct	uba_driver psdriver =
437296Ssam     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
447296Ssam 
457296Ssam #define	PSUNIT(dev)	(minor(dev))
467296Ssam 
477296Ssam #define MAXAUTOREFRESH			(4)
487296Ssam #define MAXAUTOMAP			(4)
497296Ssam #define MAXDBSIZE			(0177777/2)
507296Ssam 
517296Ssam #define PSPRI				(PZERO+1)
527296Ssam 
537296Ssam #define PSWAIT() {register short int i, j; i=20000; while((i-- != 0)\
547296Ssam 	&& (((j=psaddr->ps_iostat)&DIOREADY)==0));}
557296Ssam 
567296Ssam struct ps {
577296Ssam 	char		ps_open;
587296Ssam 	short int 	ps_uid;
597296Ssam 	struct {
6014600Ssam 		enum { SINGLE_STEP_RF, AUTO_RF, TIME_RF } state;
6114600Ssam 		enum { RUNNING_RF, SYNCING_RF, WAITING_MAP, STOPPED_RF } mode;
627296Ssam 		unsigned short int sraddrs[MAXAUTOREFRESH];
637296Ssam 		short int nsraddrs;
647296Ssam 		short int srcntr;
657296Ssam 		char waiting;
667296Ssam 		char stop;
677296Ssam 		int icnt;
6814600Ssam 		int timecnt;
697296Ssam 	} ps_refresh;
707296Ssam 	struct {
717296Ssam 		enum { ON_DB, OFF_DB } state;
727296Ssam 		unsigned short int dbaddrs[2];
737296Ssam 		unsigned short int dbsize;
747296Ssam 		short int rbuffer;
757296Ssam 	} ps_dbuffer;
767296Ssam 	struct {
777296Ssam 		enum { SINGLE_STEP_MAP, AUTO_MAP } state;
787296Ssam 		enum { RUNNING_MAP, WAITING_RF, WAITING_START } mode;
797296Ssam 		unsigned short int maddrs[MAXAUTOMAP];
807296Ssam 		short int nmaddrs;
817296Ssam 		short int mcntr;
827296Ssam 		short int outputstart;
837296Ssam 		char waiting;
847296Ssam 		char stop;
857296Ssam 		int icnt;
867296Ssam 	} ps_map;
877296Ssam 	struct {
887296Ssam 		short int ticked;
897296Ssam 		short int missed;
907296Ssam 		int icnt;
917296Ssam 	} ps_clock;
927296Ssam 	struct {
937296Ssam 		int icnt;
947296Ssam 	} ps_hit;
957296Ssam 	int ps_strayintr;
967296Ssam 	int last_request;
977296Ssam 	int strayrequest;
9814600Ssam 	int ps_icnt;
997296Ssam } ps[NPS];
1007296Ssam 
1017296Ssam psprobe(reg)
1027296Ssam 	caddr_t reg;
1037296Ssam {
1047296Ssam 	register int br, cvec;
1057296Ssam 	register struct psdevice *psaddr = (struct psdevice *) reg;
1067296Ssam 
1077296Ssam 	psaddr->ps_iostat = PSRESET;
1087296Ssam 	DELAY(200);
1097296Ssam 	psaddr->ps_addr = RTCIE;
1107296Ssam 	PSWAIT();
1117296Ssam 	psaddr->ps_data = 01;
1127296Ssam 	psaddr->ps_iostat = PSIE;
1137296Ssam 	psaddr->ps_addr = RTCSR;
1147296Ssam 	PSWAIT();
1157296Ssam 	psaddr->ps_data = (SYNC|RUN);
1167296Ssam 	DELAY(200000);
1177296Ssam 	psaddr->ps_addr = RTCREQ;
1187296Ssam 	PSWAIT();
1197296Ssam 	psaddr->ps_data = 01;
1207296Ssam 	psaddr->ps_iostat = 0;
1217296Ssam 	psaddr->ps_iostat = PSRESET;
1227418Skre 	return (sizeof (struct psdevice));
1237296Ssam }
1247296Ssam 
1257296Ssam /*ARGSUSED*/
1267296Ssam psattach(ui)
1277296Ssam 	register struct uba_device *ui;
1287296Ssam {
1298572Sroot 
1307296Ssam }
1317296Ssam 
1327296Ssam psopen(dev)
1337296Ssam 	dev_t dev;
1347296Ssam {
1357296Ssam 	register struct ps *psp;
1367296Ssam 	register struct uba_device *ui;
1377296Ssam 	register int unit = PSUNIT(dev);
1387296Ssam 
1398572Sroot 	if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
1408572Sroot 	    (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
1418572Sroot 		return (ENXIO);
1427296Ssam 	psp->ps_open = 1;
1437296Ssam 	psp->ps_uid = u.u_uid;
1447296Ssam 	psp->ps_strayintr = 0;
1457296Ssam 	psp->ps_refresh.state = SINGLE_STEP_RF;
1467296Ssam 	psp->ps_refresh.waiting = 0;
1477296Ssam 	psp->ps_refresh.stop = 0;
1487296Ssam 	psp->ps_dbuffer.state = OFF_DB;
1497296Ssam 	psp->ps_map.state = SINGLE_STEP_MAP;
1507296Ssam 	psp->ps_map.waiting = 0;
1517296Ssam 	psp->ps_map.stop = 0;
1527296Ssam 	psp->ps_clock.ticked = 0;
1537296Ssam 	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0;
15414600Ssam 	psp->ps_icnt = 0;
1557296Ssam 	maptouser(ui->ui_addr);
1568572Sroot 	return (0);
1577296Ssam }
1587296Ssam 
1597296Ssam psclose(dev)
1607296Ssam 	dev_t dev;
1617296Ssam {
1627296Ssam 	register struct psdevice *psaddr =
1637296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
1647296Ssam 
1657296Ssam 	ps[PSUNIT(dev)].ps_open = 0;
1667296Ssam 	psaddr->ps_iostat = 0;		/* clear IENABLE */
1677296Ssam 	PSWAIT();
1687296Ssam 	psaddr->ps_addr = RFSR;		/* set in auto refresh mode */
1697296Ssam 	PSWAIT();
1707296Ssam 	psaddr->ps_data = AUTOREF;
1717296Ssam 	unmaptouser(psaddr);
1727296Ssam }
1737296Ssam 
1747296Ssam /*ARGSUSED*/
1757730Sroot psread(dev, uio)
1767296Ssam 	dev_t dev;
1777730Sroot 	struct uio *uio;
1787296Ssam {
1797296Ssam }
1807296Ssam 
1817296Ssam /*ARGSUSED*/
1827730Sroot pswrite(dev, uio)
1837296Ssam 	dev_t dev;
1847730Sroot 	struct uio *uio;
1857296Ssam {
1867296Ssam }
1877296Ssam 
1887296Ssam /*ARGSUSED*/
1897632Ssam psioctl(dev, cmd, data, flag)
1907632Ssam 	register caddr_t data;
1917296Ssam {
1927296Ssam 	register struct uba_device *ui = psdinfo[PSUNIT(dev)];
1937296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
1947632Ssam 	int *waddr = *(int **)data;
1957296Ssam 	int n, arg, i;
1967296Ssam 
1977296Ssam 	switch (cmd) {
1987632Ssam 
1997632Ssam 	case PSIOGETADDR:
2007632Ssam 		*(caddr_t *)data = ui->ui_addr;
2017296Ssam 		break;
2027632Ssam 
2037632Ssam 	case PSIOAUTOREFRESH:
2047296Ssam 		n = fuword(waddr++);
2058572Sroot 		if (n == -1)
2068572Sroot 			return (EFAULT);
2078572Sroot 		if (n < 0 || n > MAXAUTOREFRESH)
2088572Sroot 			return (EINVAL);
2098572Sroot 		for (i = 0; i < n; i++) {
2108572Sroot 			if ((arg = fuword(waddr++)) == -1)
2118572Sroot 				return (EFAULT);
2128572Sroot 			psp->ps_refresh.sraddrs[i] = arg;
2137296Ssam 		}
2148572Sroot 		psp->ps_refresh.state = AUTO_RF;
2158572Sroot 		psp->ps_refresh.nsraddrs = n;
2168572Sroot 		psp->ps_refresh.srcntr = 0;
2178572Sroot 		psp->ps_refresh.mode = WAITING_MAP;
2187296Ssam 		break;
2197632Ssam 
2207632Ssam 	case PSIOAUTOMAP:
2217296Ssam 		n = fuword(waddr++);
2228572Sroot 		if (n == -1)
2238572Sroot 			return (EFAULT);
2248572Sroot 		if (n < 0 || n > MAXAUTOMAP)
2258572Sroot 			return (EINVAL);
2268572Sroot 		for (i = 0; i < n; i++) {
2278572Sroot 			if ((arg = fuword(waddr++)) == -1)
2288572Sroot 				return (EFAULT);
2298572Sroot 			psp->ps_map.maddrs[i] = arg;
2307296Ssam 		}
2318572Sroot 		if ((arg = fuword(waddr++)) == -1)
2328572Sroot 			return (EFAULT);
2338572Sroot 		psp->ps_map.outputstart = arg;
2348572Sroot 		psp->ps_map.state = AUTO_MAP;
2358572Sroot 		psp->ps_map.nmaddrs = n;
2368572Sroot 		psp->ps_map.mcntr = 0;
2378572Sroot 		psp->ps_map.mode = WAITING_START;
2387296Ssam 		break;
2397632Ssam 
2407632Ssam 	case PSIOSINGLEREFRESH:
2417296Ssam 		psp->ps_refresh.state = SINGLE_STEP_RF;
2427296Ssam 		break;
2437632Ssam 
2447632Ssam 	case PSIOSINGLEMAP:
2457296Ssam 		psp->ps_map.state = SINGLE_STEP_MAP;
2467296Ssam 		break;
2477632Ssam 
2487632Ssam 	case PSIODOUBLEBUFFER:
2498572Sroot 		if ((arg = fuword(waddr++)) == -1)
2508572Sroot 			return (EFAULT);
2518572Sroot 		psp->ps_dbuffer.dbaddrs[0] = arg;
2528572Sroot 		if ((arg = fuword(waddr++)) == -1)
2538572Sroot 			return (EFAULT);
2548572Sroot 		if (arg <= 0 || arg > MAXDBSIZE)
2558572Sroot 			return (EINVAL);
2568572Sroot 		psp->ps_dbuffer.dbsize = arg;
2578572Sroot 		psp->ps_dbuffer.dbaddrs[1] =
2588572Sroot 		    psp->ps_dbuffer.dbaddrs[0]+arg;
2598572Sroot 		psp->ps_dbuffer.state = ON_DB;
2608572Sroot 		psp->ps_dbuffer.rbuffer = 0;
2617296Ssam 		break;
2627632Ssam 
2637632Ssam 	case PSIOSINGLEBUFFER:
2647296Ssam 		psp->ps_dbuffer.state = OFF_DB;
2657296Ssam 		break;
2667632Ssam 
26714600Ssam 	case PSIOTIMEREFRESH:
26814600Ssam 		if (psp->ps_refresh.state != SINGLE_STEP_RF)
26914600Ssam 			return(EINVAL);
27014600Ssam 		if ((arg = fuword(waddr++)) == -1)
27114600Ssam 			return(EFAULT);
27214600Ssam 		psp->ps_refresh.state = TIME_RF;
27314600Ssam 		psp->ps_refresh.timecnt = arg;
27414600Ssam 		break;
27514600Ssam 
2767632Ssam 	case PSIOWAITREFRESH:
2778572Sroot 		if (psp->ps_refresh.mode != RUNNING_RF)	/* not running */
2788572Sroot 			return (0);				/* dont wait */
2798572Sroot 		/* fall into ... */
2807632Ssam 
28114600Ssam 	case PSIOSTOPREFRESH:
28214600Ssam 		if (cmd == PSIOSTOPREFRESH) {
28314600Ssam 			if (psp->ps_refresh.mode == STOPPED_RF
28414600Ssam 					&& psp->ps_refresh.state != TIME_RF)
28514600Ssam 				return (0);
2867296Ssam 			psp->ps_refresh.stop = 1;
28714600Ssam 		}
2887296Ssam 		spl5();
2897296Ssam 		psp->ps_refresh.waiting = 1;
2908572Sroot 		while (psp->ps_refresh.waiting)
2917296Ssam 			sleep(&psp->ps_refresh.waiting, PSPRI);
2927296Ssam 		spl0();
29314600Ssam 		if (cmd == PSIOSTOPREFRESH)
29414600Ssam 			psp->ps_refresh.mode = STOPPED_RF;
29514600Ssam 		if (psp->ps_refresh.state == TIME_RF)
29614600Ssam 			psp->ps_refresh.state = SINGLE_STEP_RF;
2977296Ssam 		break;
2987632Ssam 
2997632Ssam 	case PSIOWAITMAP:
3008572Sroot 		if (psp->ps_map.mode != RUNNING_MAP)	/* not running */
3018572Sroot 			return (0);				/* dont wait */
3028572Sroot 		/* fall into ... */
3037632Ssam 
3047632Ssam 	case PSIOSTOPMAP:
30514600Ssam 		if (cmd == PSIOSTOPMAP)
3067296Ssam 			psp->ps_map.stop = 1;
3077296Ssam 		spl5();
3087296Ssam 		psp->ps_map.waiting = 1;
3098572Sroot 		while (psp->ps_map.waiting)
3107296Ssam 			sleep(&psp->ps_map.waiting, PSPRI);
3117296Ssam 		spl0();
3127296Ssam 		break;
3137632Ssam 
3147296Ssam 	default:
3158572Sroot 		return (ENOTTY);
3167296Ssam 		break;
3177296Ssam 	}
3188572Sroot 	return (0);
3197296Ssam }
3207296Ssam 
3217296Ssam #define SAVEPSADDR() {register short int i, x;x=spl6();i=psaddr->ps_addr;\
3227296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
3237296Ssam 		savepsaddr=psaddr->ps_data;splx(x);}
3247296Ssam #define RESTORPSADDR() {register int x,i;x=spl6();\
3257296Ssam 		while(((i=psaddr->ps_iostat)&DIOREADY)==0);\
3267296Ssam 		psaddr->ps_addr=savepsaddr;splx(x);}
3277296Ssam 
3287296Ssam psclockintr(dev)
3297296Ssam 	dev_t dev;
3307296Ssam {
3317296Ssam 	register struct psdevice *psaddr =
3327296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3337296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
3347296Ssam 	int savepsaddr;
3357296Ssam 
3368572Sroot 	if (!psp->ps_open)
3377296Ssam 		return;
3387296Ssam 	psp->ps_clock.icnt++;
3397296Ssam 	SAVEPSADDR();
3407296Ssam #ifndef EXTERNAL_SYNC
3418572Sroot 	if (psp->ps_refresh.state == AUTO_RF) {
34214600Ssam 		if (psp->ps_refresh.mode == SYNCING_RF
34314600Ssam 					&& psp->ps_refresh.state != TIME_RF) {
3447296Ssam 			psrfnext(psp, psaddr);
3457296Ssam 		} else {
3467296Ssam 			psp->ps_clock.ticked++;
3477296Ssam 			psp->ps_clock.missed++;
3487296Ssam 		}
3497296Ssam 	}
3507296Ssam #endif
3517296Ssam 	PSWAIT();
3527296Ssam 	psaddr->ps_addr = RTCREQ;
3537296Ssam 	PSWAIT();
3547296Ssam 	psaddr->ps_data = 01;		/* clear the request bits */
3557296Ssam 	RESTORPSADDR();
3567296Ssam }
3577296Ssam 
3587296Ssam /*ARGSUSED*/
3597296Ssam pssystemintr(dev)
3607296Ssam 	dev_t dev;
3617296Ssam {
3627296Ssam 	register struct psdevice *psaddr =
3637296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3647296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
3657296Ssam 	short int request;
3667296Ssam 	register int savepsaddr, x;
3677296Ssam 
3688572Sroot 	if (!psp->ps_open)
3697296Ssam 		return;
37014600Ssam 	psp->ps_icnt++;
3717296Ssam 	SAVEPSADDR();
3727296Ssam 	PSWAIT();
3737296Ssam 	psaddr->ps_addr = SYSREQ;
3747296Ssam 	PSWAIT();
37514600Ssam 	request = psaddr->ps_data&0377;
3767296Ssam 	psp->last_request = request;
3777296Ssam 	PSWAIT();
3787296Ssam 	psaddr->ps_addr = SYSREQ;
3797296Ssam 	PSWAIT();
3807296Ssam 	psaddr->ps_data = request&(~(HALT_REQ|MOSTOP_REQ));   /* acknowledge */
3817296Ssam 
3828572Sroot 	if (request & (MOSTOP_REQ|HALT_REQ)) {	/* Map stopped */
3837296Ssam 		psp->ps_map.icnt++;
3847296Ssam 		psmapstop(psaddr);		/* kill it dead */
3858572Sroot 		if (psp->ps_map.waiting) {
3867296Ssam 			psp->ps_map.waiting = 0;
3877296Ssam 			wakeup(&psp->ps_map.waiting);
3888572Sroot 			if (psp->ps_map.stop) {
3897296Ssam 				psp->ps_map.stop = 0;
3907296Ssam 				goto tryrf;
3917296Ssam 			}
3927296Ssam 		}
3938572Sroot 		if (psp->ps_map.state == AUTO_MAP)
3948572Sroot 			if (!psmapnext(psp, psaddr)) {
3957296Ssam 				psp->ps_map.mcntr = 0;
3967296Ssam 				/* prepare for next round */
3977296Ssam 				pssetmapbounds(psp, psaddr);
3988572Sroot 				if (psp->ps_refresh.mode == WAITING_MAP) {
3998572Sroot 					if (psp->ps_dbuffer.state == ON_DB)
4007296Ssam 						/* fill other db */
4017296Ssam 						psdbswitch(psp, psaddr);
4027296Ssam 					else
4037296Ssam 						psp->ps_map.mode = WAITING_RF;
4047296Ssam 					psrfnext(psp, psaddr);	/* start rf */
4057296Ssam 				} else
4067296Ssam 					psp->ps_map.mode = WAITING_RF;
4077296Ssam 			}
4087296Ssam 	}
4097296Ssam tryrf:
4108572Sroot 	if (request & RFSTOP_REQ) {		/* Refresh stopped */
4117296Ssam 		psp->ps_refresh.icnt++;
41214600Ssam 		if (psp->ps_refresh.state == TIME_RF)
41314600Ssam 			if(--psp->ps_refresh.timecnt > 0)
41414600Ssam 				goto tryhit;
4157296Ssam 		psrfstop(psaddr, psp);
4168572Sroot 		if (psp->ps_refresh.waiting) {
4177296Ssam 			psp->ps_refresh.waiting = 0;
4187296Ssam 			wakeup(&psp->ps_refresh.waiting);
4198572Sroot 			if (psp->ps_refresh.stop) {
4207296Ssam 				psp->ps_refresh.stop = 0;
4217296Ssam 				goto tryhit;
4227296Ssam 			}
4237296Ssam 		}
4248572Sroot 		if (psp->ps_refresh.state == AUTO_RF)
4258572Sroot 			if (!psrfnext(psp, psaddr)) {	/* at end of refresh cycle */
4268572Sroot 				if (psp->ps_map.state == AUTO_MAP &&
4277296Ssam 						psp->ps_map.mode==WAITING_RF) {
4288572Sroot 					if (psp->ps_dbuffer.state == ON_DB)
4297296Ssam 						psdbswitch(psp, psaddr);
4307296Ssam 					else
4317296Ssam 						psmapnext(psp, psaddr);
4327296Ssam 				}
4337296Ssam 				psp->ps_refresh.srcntr = 0;
4347296Ssam #ifdef EXTERNAL_SYNC
4357296Ssam 				x = spl6();
4367296Ssam #endif
4378572Sroot 				if (!psp->ps_clock.ticked ||
4387296Ssam 						!psrfnext(psp, psaddr)) {
4397296Ssam 					psp->ps_refresh.mode = SYNCING_RF;
4407296Ssam 				}
4417296Ssam 				psp->ps_clock.ticked = 0;
4427296Ssam 				psp->ps_refresh.mode = SYNCING_RF;
4437296Ssam #ifdef EXTERNAL_SYNC
4447296Ssam 				splx(x);
4457296Ssam #endif
4467296Ssam 			}
4477296Ssam 	}
4487296Ssam tryhit:
4498572Sroot 	if (request & HIT_REQ) {		/* Hit request */
4507296Ssam 		psp->ps_hit.icnt++;
4517296Ssam 	}
4528572Sroot 	if (request == 0)
4537296Ssam 		psp->ps_strayintr++;
4547296Ssam 	RESTORPSADDR();
4557296Ssam }
4567296Ssam 
4577296Ssam psrfnext(psp, psaddr)
4587296Ssam 	register struct ps *psp;
4597296Ssam 	register struct psdevice *psaddr;
4607296Ssam {
4617296Ssam 
4628572Sroot 	if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs)
4637296Ssam 		psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
4647296Ssam 						psp, psaddr);
4658572Sroot 	else if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs
4667296Ssam 				&& psp->ps_dbuffer.state == ON_DB) {
4677296Ssam 		psrfstart(psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer],
4687296Ssam 						psp, psaddr);
4697296Ssam 		psp->ps_refresh.srcntr++;	/* flag for after dbuffer */
4707296Ssam 	} else
4717296Ssam 		return(0);
4727296Ssam 	return(1);
4737296Ssam }
4747296Ssam 
4757296Ssam psrfstart(dfaddr, psp, psaddr)
4767296Ssam 	short int dfaddr;
4777296Ssam 	register struct ps *psp;
4787296Ssam 	register struct psdevice *psaddr;
4797296Ssam {
4807296Ssam 	int dummy;
4817296Ssam 
4827296Ssam 	PSWAIT();
4837296Ssam 	psaddr->ps_addr = RFASA;
4847296Ssam 	PSWAIT();
4857296Ssam 	psaddr->ps_data = dfaddr;
4867296Ssam 	PSWAIT();
4877296Ssam 	dummy = psaddr->ps_data;	/* just access to get to status reg */
4887296Ssam 	PSWAIT();
4897296Ssam 	psaddr->ps_data = RFSTART;	/* may want to | this value in */
4907296Ssam 	psp->ps_refresh.mode = RUNNING_RF;
4917296Ssam }
4927296Ssam 
4937296Ssam psrfstop(psaddr, psp)
4947296Ssam 	register struct psdevice *psaddr;
4957296Ssam 	register struct ps *psp;
4967296Ssam {
4977296Ssam 
4987296Ssam 	PSWAIT();
4997296Ssam 	psaddr->ps_addr = RFSR;
5007296Ssam 	PSWAIT();
5017296Ssam 	psaddr->ps_data = 0;
5027296Ssam }
5037296Ssam 
5047296Ssam psdbswitch(psp, psaddr)
5057296Ssam 	register struct ps *psp;
5067296Ssam 	register struct psdevice *psaddr;
5077296Ssam {
5087296Ssam 
5097296Ssam 	psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
5107296Ssam 	pssetmapbounds(psp, psaddr);
5117296Ssam 	psmapnext(psp, psaddr);
5127296Ssam }
5137296Ssam 
5147296Ssam psmapnext(psp, psaddr)
5157296Ssam 	register struct ps *psp;
5167296Ssam 	register struct psdevice *psaddr;
5177296Ssam {
5187296Ssam 
5198572Sroot 	if (psp->ps_map.mcntr < psp->ps_map.nmaddrs)
5207296Ssam 		psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr);
5217296Ssam 	else
5227296Ssam 		return(0);
5237296Ssam 	return(1);
5247296Ssam }
5257296Ssam 
5267296Ssam pssetmapbounds(psp, psaddr)
5277296Ssam 	register struct ps *psp;
5287296Ssam 	register struct psdevice *psaddr;
5297296Ssam {
5307296Ssam 	unsigned short int start;
5317296Ssam 
5327296Ssam 	PSWAIT();
5337296Ssam 	psaddr->ps_addr = MAOL;
5347296Ssam 	PSWAIT();
5358572Sroot 	if (psp->ps_dbuffer.state == ON_DB) {
5367296Ssam 		psaddr->ps_data = (start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer])
5377296Ssam 				+psp->ps_dbuffer.dbsize-2;   /* 2 for a refresh halt command */
5387296Ssam 		PSWAIT();
5397296Ssam 		psaddr->ps_data = start;
5407296Ssam 	} else {
5417296Ssam 		start = psaddr->ps_data;	/* dummy: don't update limit */
5427296Ssam 		PSWAIT();
5437296Ssam 		psaddr->ps_data = psp->ps_map.outputstart;
5447296Ssam 	}
5457296Ssam }
5467296Ssam 
5477296Ssam psmapstart(dfaddr, psp, psaddr)
5487296Ssam 	int dfaddr;
5497296Ssam 	register struct ps *psp;
5507296Ssam 	register struct psdevice *psaddr;
5517296Ssam {
5527296Ssam 	int data;
5537296Ssam 
5547296Ssam 	PSWAIT();
5557296Ssam 	psaddr->ps_addr = MAIA;
5567296Ssam 	PSWAIT();
5577296Ssam 	psaddr->ps_data = dfaddr;
5587296Ssam 	PSWAIT();
5597296Ssam 	psaddr->ps_data = MAO|MAI;	/* may want more here */
5607296Ssam 	psp->ps_map.mode = RUNNING_MAP;
5617296Ssam }
5627296Ssam 
5637296Ssam psmapstop(psaddr)
5647296Ssam 	register struct psdevice *psaddr;
5657296Ssam {
5667296Ssam 
5677296Ssam 	PSWAIT();
5687296Ssam 	psaddr->ps_addr = MASR;
5697296Ssam 	PSWAIT();
5707296Ssam 	psaddr->ps_data = 0;	/* zero MAI bit */
5717296Ssam 	PSWAIT();
5727296Ssam 	psaddr->ps_addr = MAIA;
5737296Ssam 	PSWAIT();
5747296Ssam 	psaddr->ps_data = 0;	/* zero input address register */
5757296Ssam 	PSWAIT();
5767296Ssam 	psaddr->ps_addr = SYSREQ;
5777296Ssam 	PSWAIT();
5787296Ssam 	psaddr->ps_data = HALT_REQ|MOSTOP_REQ;	/* overkill?? */
5797296Ssam }
5807296Ssam 
5817296Ssam /*ARGSUSED*/
5827296Ssam psdeviceintr(dev)
5837296Ssam 	dev_t dev;
5847296Ssam {
5857296Ssam 
5867296Ssam 	printf("ps device intr\n");
5877296Ssam }
5887296Ssam 
5897296Ssam /*ARGSUSED*/
5907296Ssam psdmaintr(dev)
5917296Ssam 	dev_t dev;
5927296Ssam {
5937296Ssam 
5947296Ssam 	printf("ps dma intr\n");
5957296Ssam }
5967296Ssam 
5977296Ssam psreset(uban)
5987296Ssam 	int uban;
5997296Ssam {
6007296Ssam }
6017296Ssam 
6027296Ssam psextsync(PC, PS) {
6037296Ssam 	register int n;
6047296Ssam 	register struct psdevice *psaddr;
6057296Ssam 	register struct ps *psp;
6067296Ssam 	register int savepsaddr;
6077296Ssam 
6087296Ssam #ifdef EXTERNAL_SYNC
6098572Sroot 	for (psp = ps, n = 0; n < NPS; psp++, n++) {
6108572Sroot 		if (!psp->ps_open)
6117296Ssam 			continue;
61214600Ssam 		if(psp->ps_refresh.mode == SYNCING_RF
61314600Ssam 					&& psp->ps_refresh.state != TIME_RF) {
6147296Ssam 			psaddr = (struct psdevice *) psdinfo[n]->ui_addr;
6157296Ssam 			SAVEPSADDR();
6167296Ssam 			psrfnext(psp, psaddr);
6177296Ssam 			RESTORPSADDR();
6187296Ssam 		} else {
6197296Ssam 			psp->ps_clock.ticked++;
6207296Ssam 			psp->ps_clock.missed++;
6217296Ssam 		}
6227296Ssam 	}
6237296Ssam #endif
6247296Ssam }
6257296Ssam #endif
626