xref: /csrg-svn/sys/vax/uba/ps.c (revision 25472)
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*25472Ssam  *	@(#)ps.c	6.5 (Berkeley) 11/12/85
723334Smckusick  */
87296Ssam 
97296Ssam /*
1023511Ssam  * 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 
39*25472Ssam int	psprobe(), psattach(), psextsync();
40*25472Ssam int	psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();
417296Ssam struct	uba_device *psdinfo[NPS];
427296Ssam u_short	psstd[] = { 0 };
437296Ssam struct	uba_driver psdriver =
447296Ssam     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };
457296Ssam 
467296Ssam #define	PSUNIT(dev)	(minor(dev))
477296Ssam 
487296Ssam #define MAXAUTOREFRESH			(4)
497296Ssam #define MAXAUTOMAP			(4)
507296Ssam #define MAXDBSIZE			(0177777/2)
517296Ssam 
527296Ssam #define PSPRI				(PZERO+1)
537296Ssam 
54*25472Ssam #define PSWAIT() {register short i, j; i=20000; while((i-- != 0)\
557296Ssam 	&& (((j=psaddr->ps_iostat)&DIOREADY)==0));}
567296Ssam 
577296Ssam struct ps {
587296Ssam 	char		ps_open;
597296Ssam 	short int 	ps_uid;
607296Ssam 	struct {
6114600Ssam 		enum { SINGLE_STEP_RF, AUTO_RF, TIME_RF } state;
6214600Ssam 		enum { RUNNING_RF, SYNCING_RF, WAITING_MAP, STOPPED_RF } mode;
637296Ssam 		unsigned short int sraddrs[MAXAUTOREFRESH];
647296Ssam 		short int nsraddrs;
657296Ssam 		short int srcntr;
667296Ssam 		char waiting;
677296Ssam 		char stop;
687296Ssam 		int icnt;
6914600Ssam 		int timecnt;
707296Ssam 	} ps_refresh;
717296Ssam 	struct {
727296Ssam 		enum { ON_DB, OFF_DB } state;
737296Ssam 		unsigned short int dbaddrs[2];
747296Ssam 		unsigned short int dbsize;
757296Ssam 		short int rbuffer;
767296Ssam 	} ps_dbuffer;
777296Ssam 	struct {
787296Ssam 		enum { SINGLE_STEP_MAP, AUTO_MAP } state;
79*25472Ssam 		enum { RUNNING_MAP, WAITING_RF, WAITING_START, STOPPED_MAP } mode;
807296Ssam 		unsigned short int maddrs[MAXAUTOMAP];
817296Ssam 		short int nmaddrs;
827296Ssam 		short int mcntr;
837296Ssam 		short int outputstart;
847296Ssam 		char waiting;
857296Ssam 		char stop;
867296Ssam 		int icnt;
877296Ssam 	} ps_map;
887296Ssam 	struct {
897296Ssam 		short int ticked;
907296Ssam 		short int missed;
917296Ssam 		int icnt;
927296Ssam 	} ps_clock;
937296Ssam 	struct {
947296Ssam 		int icnt;
957296Ssam 	} ps_hit;
967296Ssam 	int ps_strayintr;
977296Ssam 	int last_request;
987296Ssam 	int strayrequest;
9914600Ssam 	int ps_icnt;
100*25472Ssam 	int last_request2;
101*25472Ssam 	int last_funnyrequest;
102*25472Ssam 	int funny_cnt;
1037296Ssam } ps[NPS];
1047296Ssam 
1057296Ssam psprobe(reg)
1067296Ssam 	caddr_t reg;
1077296Ssam {
1087296Ssam 	register int br, cvec;
1097296Ssam 	register struct psdevice *psaddr = (struct psdevice *) reg;
1107296Ssam 
111*25472Ssam #ifdef lint
112*25472Ssam 	br = 0; cvec = br; br = cvec;
113*25472Ssam 	psclockintr((dev_t)0); pssystemintr((dev_t)0);
114*25472Ssam 	psdeviceintr((dev_t)0); psdmaintr((dev_t)0);
115*25472Ssam 	psextsync(0, 0);
116*25472Ssam #endif
1177296Ssam 	psaddr->ps_iostat = PSRESET;
1187296Ssam 	DELAY(200);
1197296Ssam 	psaddr->ps_addr = RTCIE;
1207296Ssam 	PSWAIT();
1217296Ssam 	psaddr->ps_data = 01;
1227296Ssam 	psaddr->ps_iostat = PSIE;
1237296Ssam 	psaddr->ps_addr = RTCSR;
1247296Ssam 	PSWAIT();
1257296Ssam 	psaddr->ps_data = (SYNC|RUN);
1267296Ssam 	DELAY(200000);
1277296Ssam 	psaddr->ps_addr = RTCREQ;
1287296Ssam 	PSWAIT();
1297296Ssam 	psaddr->ps_data = 01;
1307296Ssam 	psaddr->ps_iostat = 0;
1317296Ssam 	psaddr->ps_iostat = PSRESET;
1327418Skre 	return (sizeof (struct psdevice));
1337296Ssam }
1347296Ssam 
1357296Ssam /*ARGSUSED*/
1367296Ssam psattach(ui)
137*25472Ssam 	struct uba_device *ui;
1387296Ssam {
1398572Sroot 
1407296Ssam }
1417296Ssam 
1427296Ssam psopen(dev)
1437296Ssam 	dev_t dev;
1447296Ssam {
1457296Ssam 	register struct ps *psp;
1467296Ssam 	register struct uba_device *ui;
1477296Ssam 	register int unit = PSUNIT(dev);
1487296Ssam 
1498572Sroot 	if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||
1508572Sroot 	    (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)
1518572Sroot 		return (ENXIO);
1527296Ssam 	psp->ps_open = 1;
1537296Ssam 	psp->ps_uid = u.u_uid;
1547296Ssam 	psp->ps_strayintr = 0;
1557296Ssam 	psp->ps_refresh.state = SINGLE_STEP_RF;
156*25472Ssam 	psp->ps_refresh.mode = STOPPED_RF;
1577296Ssam 	psp->ps_refresh.waiting = 0;
1587296Ssam 	psp->ps_refresh.stop = 0;
1597296Ssam 	psp->ps_dbuffer.state = OFF_DB;
1607296Ssam 	psp->ps_map.state = SINGLE_STEP_MAP;
161*25472Ssam 	psp->ps_map.mode = STOPPED_MAP;
1627296Ssam 	psp->ps_map.waiting = 0;
1637296Ssam 	psp->ps_map.stop = 0;
1647296Ssam 	psp->ps_clock.ticked = 0;
165*25472Ssam 	psp->ps_clock.missed = 0;
1667296Ssam 	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clock.icnt = 0;
167*25472Ssam 	psp->ps_hit.icnt = 0;
16814600Ssam 	psp->ps_icnt = 0;
1697296Ssam 	maptouser(ui->ui_addr);
1708572Sroot 	return (0);
1717296Ssam }
1727296Ssam 
1737296Ssam psclose(dev)
1747296Ssam 	dev_t dev;
1757296Ssam {
1767296Ssam 	register struct psdevice *psaddr =
1777296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
1787296Ssam 
1797296Ssam 	ps[PSUNIT(dev)].ps_open = 0;
1807296Ssam 	psaddr->ps_iostat = 0;		/* clear IENABLE */
1817296Ssam 	PSWAIT();
1827296Ssam 	psaddr->ps_addr = RFSR;		/* set in auto refresh mode */
1837296Ssam 	PSWAIT();
1847296Ssam 	psaddr->ps_data = AUTOREF;
185*25472Ssam 	unmaptouser((caddr_t)psaddr);
1867296Ssam }
1877296Ssam 
1887296Ssam /*ARGSUSED*/
1897730Sroot psread(dev, uio)
1907296Ssam 	dev_t dev;
1917730Sroot 	struct uio *uio;
1927296Ssam {
1937296Ssam }
1947296Ssam 
1957296Ssam /*ARGSUSED*/
1967730Sroot pswrite(dev, uio)
1977296Ssam 	dev_t dev;
1987730Sroot 	struct uio *uio;
1997296Ssam {
2007296Ssam }
2017296Ssam 
2027296Ssam /*ARGSUSED*/
2037632Ssam psioctl(dev, cmd, data, flag)
2047632Ssam 	register caddr_t data;
2057296Ssam {
2067296Ssam 	register struct uba_device *ui = psdinfo[PSUNIT(dev)];
2077296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
2087632Ssam 	int *waddr = *(int **)data;
2097296Ssam 	int n, arg, i;
2107296Ssam 
2117296Ssam 	switch (cmd) {
2127632Ssam 
2137632Ssam 	case PSIOGETADDR:
2147632Ssam 		*(caddr_t *)data = ui->ui_addr;
2157296Ssam 		break;
2167632Ssam 
2177632Ssam 	case PSIOAUTOREFRESH:
218*25472Ssam 		n = fuword((caddr_t)waddr++);
2198572Sroot 		if (n == -1)
2208572Sroot 			return (EFAULT);
2218572Sroot 		if (n < 0 || n > MAXAUTOREFRESH)
2228572Sroot 			return (EINVAL);
2238572Sroot 		for (i = 0; i < n; i++) {
224*25472Ssam 			if ((arg = fuword((caddr_t)waddr++)) == -1)
2258572Sroot 				return (EFAULT);
2268572Sroot 			psp->ps_refresh.sraddrs[i] = arg;
2277296Ssam 		}
2288572Sroot 		psp->ps_refresh.state = AUTO_RF;
2298572Sroot 		psp->ps_refresh.nsraddrs = n;
2308572Sroot 		psp->ps_refresh.srcntr = 0;
2318572Sroot 		psp->ps_refresh.mode = WAITING_MAP;
2327296Ssam 		break;
2337632Ssam 
2347632Ssam 	case PSIOAUTOMAP:
235*25472Ssam 		n = fuword((caddr_t)waddr++);
2368572Sroot 		if (n == -1)
2378572Sroot 			return (EFAULT);
2388572Sroot 		if (n < 0 || n > MAXAUTOMAP)
2398572Sroot 			return (EINVAL);
2408572Sroot 		for (i = 0; i < n; i++) {
241*25472Ssam 			if ((arg = fuword((caddr_t)waddr++)) == -1)
2428572Sroot 				return (EFAULT);
2438572Sroot 			psp->ps_map.maddrs[i] = arg;
2447296Ssam 		}
245*25472Ssam 		if ((arg = fuword((caddr_t)waddr++)) == -1)
2468572Sroot 			return (EFAULT);
2478572Sroot 		psp->ps_map.outputstart = arg;
2488572Sroot 		psp->ps_map.state = AUTO_MAP;
2498572Sroot 		psp->ps_map.nmaddrs = n;
2508572Sroot 		psp->ps_map.mcntr = 0;
2518572Sroot 		psp->ps_map.mode = WAITING_START;
2527296Ssam 		break;
2537632Ssam 
2547632Ssam 	case PSIOSINGLEREFRESH:
2557296Ssam 		psp->ps_refresh.state = SINGLE_STEP_RF;
2567296Ssam 		break;
2577632Ssam 
2587632Ssam 	case PSIOSINGLEMAP:
2597296Ssam 		psp->ps_map.state = SINGLE_STEP_MAP;
2607296Ssam 		break;
2617632Ssam 
2627632Ssam 	case PSIODOUBLEBUFFER:
263*25472Ssam 		if ((arg = fuword((caddr_t)waddr++)) == -1)
2648572Sroot 			return (EFAULT);
2658572Sroot 		psp->ps_dbuffer.dbaddrs[0] = arg;
266*25472Ssam 		if ((arg = fuword((caddr_t)waddr++)) == -1)
2678572Sroot 			return (EFAULT);
2688572Sroot 		if (arg <= 0 || arg > MAXDBSIZE)
2698572Sroot 			return (EINVAL);
2708572Sroot 		psp->ps_dbuffer.dbsize = arg;
2718572Sroot 		psp->ps_dbuffer.dbaddrs[1] =
2728572Sroot 		    psp->ps_dbuffer.dbaddrs[0]+arg;
2738572Sroot 		psp->ps_dbuffer.state = ON_DB;
2748572Sroot 		psp->ps_dbuffer.rbuffer = 0;
2757296Ssam 		break;
2767632Ssam 
2777632Ssam 	case PSIOSINGLEBUFFER:
2787296Ssam 		psp->ps_dbuffer.state = OFF_DB;
2797296Ssam 		break;
2807632Ssam 
28114600Ssam 	case PSIOTIMEREFRESH:
28214600Ssam 		if (psp->ps_refresh.state != SINGLE_STEP_RF)
28314600Ssam 			return(EINVAL);
284*25472Ssam 		if ((arg = fuword((caddr_t)waddr++)) == -1)
28514600Ssam 			return(EFAULT);
28614600Ssam 		psp->ps_refresh.state = TIME_RF;
28714600Ssam 		psp->ps_refresh.timecnt = arg;
28814600Ssam 		break;
28914600Ssam 
2907632Ssam 	case PSIOWAITREFRESH:
2918572Sroot 		if (psp->ps_refresh.mode != RUNNING_RF)	/* not running */
2928572Sroot 			return (0);				/* dont wait */
2938572Sroot 		/* fall into ... */
2947632Ssam 
29514600Ssam 	case PSIOSTOPREFRESH:
29614600Ssam 		if (cmd == PSIOSTOPREFRESH) {
29714600Ssam 			if (psp->ps_refresh.mode == STOPPED_RF
29814600Ssam 					&& psp->ps_refresh.state != TIME_RF)
29914600Ssam 				return (0);
3007296Ssam 			psp->ps_refresh.stop = 1;
30114600Ssam 		}
3027296Ssam 		spl5();
3037296Ssam 		psp->ps_refresh.waiting = 1;
3048572Sroot 		while (psp->ps_refresh.waiting)
3057296Ssam 			sleep(&psp->ps_refresh.waiting, PSPRI);
3067296Ssam 		spl0();
30714600Ssam 		if (cmd == PSIOSTOPREFRESH)
30814600Ssam 			psp->ps_refresh.mode = STOPPED_RF;
30914600Ssam 		if (psp->ps_refresh.state == TIME_RF)
31014600Ssam 			psp->ps_refresh.state = SINGLE_STEP_RF;
3117296Ssam 		break;
3127632Ssam 
3137632Ssam 	case PSIOWAITMAP:
3148572Sroot 		if (psp->ps_map.mode != RUNNING_MAP)	/* not running */
3158572Sroot 			return (0);				/* dont wait */
3168572Sroot 		/* fall into ... */
3177632Ssam 
3187632Ssam 	case PSIOSTOPMAP:
31914600Ssam 		if (cmd == PSIOSTOPMAP)
3207296Ssam 			psp->ps_map.stop = 1;
3217296Ssam 		spl5();
3227296Ssam 		psp->ps_map.waiting = 1;
3238572Sroot 		while (psp->ps_map.waiting)
3247296Ssam 			sleep(&psp->ps_map.waiting, PSPRI);
3257296Ssam 		spl0();
3267296Ssam 		break;
3277632Ssam 
3287296Ssam 	default:
3298572Sroot 		return (ENOTTY);
3307296Ssam 		break;
3317296Ssam 	}
3328572Sroot 	return (0);
3337296Ssam }
3347296Ssam 
335*25472Ssam #define SAVEPSADDR() {register short i,xx1;xx1=spl6();i=psaddr->ps_addr;\
336*25472Ssam 		while(((psaddr->ps_iostat)&DIOREADY)==0);\
337*25472Ssam 		savepsaddr=psaddr->ps_data;splx(xx1);}
338*25472Ssam #define RESTORPSADDR() {register short xx2;xx2=spl6();\
339*25472Ssam 		while(((psaddr->ps_iostat)&DIOREADY)==0);\
340*25472Ssam 		psaddr->ps_addr=savepsaddr;splx(xx2);}
3417296Ssam 
3427296Ssam psclockintr(dev)
3437296Ssam 	dev_t dev;
3447296Ssam {
3457296Ssam 	register struct psdevice *psaddr =
3467296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3477296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
3487296Ssam 	int savepsaddr;
3497296Ssam 
3508572Sroot 	if (!psp->ps_open)
3517296Ssam 		return;
3527296Ssam 	psp->ps_clock.icnt++;
3537296Ssam 	SAVEPSADDR();
3547296Ssam #ifndef EXTERNAL_SYNC
3558572Sroot 	if (psp->ps_refresh.state == AUTO_RF) {
35614600Ssam 		if (psp->ps_refresh.mode == SYNCING_RF
35714600Ssam 					&& psp->ps_refresh.state != TIME_RF) {
358*25472Ssam 			(void) psrfnext(psp, psaddr);
3597296Ssam 		} else {
3607296Ssam 			psp->ps_clock.ticked++;
3617296Ssam 			psp->ps_clock.missed++;
3627296Ssam 		}
3637296Ssam 	}
3647296Ssam #endif
3657296Ssam 	PSWAIT();
3667296Ssam 	psaddr->ps_addr = RTCREQ;
3677296Ssam 	PSWAIT();
3687296Ssam 	psaddr->ps_data = 01;		/* clear the request bits */
3697296Ssam 	RESTORPSADDR();
3707296Ssam }
3717296Ssam 
3727296Ssam /*ARGSUSED*/
3737296Ssam pssystemintr(dev)
3747296Ssam 	dev_t dev;
3757296Ssam {
3767296Ssam 	register struct psdevice *psaddr =
3777296Ssam 			(struct psdevice *) psdinfo[PSUNIT(dev)]->ui_addr;
3787296Ssam 	register struct ps *psp = &ps[PSUNIT(dev)];
379*25472Ssam 	short int request, tmp;
3807296Ssam 	register int savepsaddr, x;
3817296Ssam 
3828572Sroot 	if (!psp->ps_open)
3837296Ssam 		return;
38414600Ssam 	psp->ps_icnt++;
3857296Ssam 	SAVEPSADDR();
3867296Ssam 	PSWAIT();
3877296Ssam 	psaddr->ps_addr = SYSREQ;
3887296Ssam 	PSWAIT();
389*25472Ssam 	request = psaddr->ps_data;
390*25472Ssam 	request = request&0377;
391*25472Ssam 	psp->last_request2 = psp->last_request;
3927296Ssam 	psp->last_request = request;
393*25472Ssam 	if(request&(~(HALT_REQ|RFSTOP_REQ|HIT_REQ))) {
394*25472Ssam 		psp->last_funnyrequest = request;
395*25472Ssam 		psp->funny_cnt++;
396*25472Ssam 	}
3977296Ssam 	PSWAIT();
3987296Ssam 	psaddr->ps_addr = SYSREQ;
399*25472Ssam 	tmp = request&(~(HALT_REQ|MOSTOP_REQ));   /* acknowledge */
4007296Ssam 	PSWAIT();
401*25472Ssam 	psaddr->ps_data = tmp;
4027296Ssam 
4038572Sroot 	if (request & (MOSTOP_REQ|HALT_REQ)) {	/* Map stopped */
4047296Ssam 		psp->ps_map.icnt++;
405*25472Ssam 		psmapstop(psaddr, psp, request);	/* kill it dead */
4068572Sroot 		if (psp->ps_map.waiting) {
4077296Ssam 			psp->ps_map.waiting = 0;
4087296Ssam 			wakeup(&psp->ps_map.waiting);
4098572Sroot 			if (psp->ps_map.stop) {
4107296Ssam 				psp->ps_map.stop = 0;
4117296Ssam 				goto tryrf;
4127296Ssam 			}
4137296Ssam 		}
414*25472Ssam 		if((psp->ps_map.state==AUTO_MAP) && (!psmapnext(psp, psaddr))){
415*25472Ssam 			psp->ps_map.mcntr = 0;
416*25472Ssam 			/* prepare for next round */
417*25472Ssam 			pssetmapbounds(psp, psaddr);
418*25472Ssam 			if (psp->ps_refresh.state == AUTO_RF) {
419*25472Ssam 				if(psp->ps_refresh.mode == WAITING_MAP){
4208572Sroot 					if (psp->ps_dbuffer.state == ON_DB)
4217296Ssam 						/* fill other db */
4227296Ssam 						psdbswitch(psp, psaddr);
4237296Ssam 					else
4247296Ssam 						psp->ps_map.mode = WAITING_RF;
425*25472Ssam #ifdef EXTERNAL_SYNC
426*25472Ssam 					x = spl6();
427*25472Ssam #endif
428*25472Ssam 					(void) psrfnext(psp, psaddr);
429*25472Ssam #ifdef EXTERNAL_SYNC
430*25472Ssam 					splx(x);
431*25472Ssam #endif
4327296Ssam 				} else
4337296Ssam 					psp->ps_map.mode = WAITING_RF;
434*25472Ssam 			} else {	/* no auto refresh */
435*25472Ssam 				if (psp->ps_dbuffer.state == ON_DB)
436*25472Ssam 					/* fill other db */
437*25472Ssam 					psdbswitch(psp, psaddr);
438*25472Ssam 				else
439*25472Ssam 					(void) psmapnext(psp, psaddr);
4407296Ssam 			}
441*25472Ssam 		}
4427296Ssam 	}
4437296Ssam tryrf:
4448572Sroot 	if (request & RFSTOP_REQ) {		/* Refresh stopped */
4457296Ssam 		psp->ps_refresh.icnt++;
44614600Ssam 		if (psp->ps_refresh.state == TIME_RF)
44714600Ssam 			if(--psp->ps_refresh.timecnt > 0)
44814600Ssam 				goto tryhit;
4497296Ssam 		psrfstop(psaddr, psp);
4508572Sroot 		if (psp->ps_refresh.waiting) {
4517296Ssam 			psp->ps_refresh.waiting = 0;
4527296Ssam 			wakeup(&psp->ps_refresh.waiting);
4538572Sroot 			if (psp->ps_refresh.stop) {
4547296Ssam 				psp->ps_refresh.stop = 0;
4557296Ssam 				goto tryhit;
4567296Ssam 			}
4577296Ssam 		}
4588572Sroot 		if (psp->ps_refresh.state == AUTO_RF)
4598572Sroot 			if (!psrfnext(psp, psaddr)) {	/* at end of refresh cycle */
4608572Sroot 				if (psp->ps_map.state == AUTO_MAP &&
4617296Ssam 						psp->ps_map.mode==WAITING_RF) {
4628572Sroot 					if (psp->ps_dbuffer.state == ON_DB)
4637296Ssam 						psdbswitch(psp, psaddr);
4647296Ssam 					else
465*25472Ssam 						(void) psmapnext(psp, psaddr);
4667296Ssam 				}
4677296Ssam 				psp->ps_refresh.srcntr = 0;
4687296Ssam #ifdef EXTERNAL_SYNC
4697296Ssam 				x = spl6();
4707296Ssam #endif
471*25472Ssam 				psp->ps_refresh.mode = SYNCING_RF;
472*25472Ssam 				if (psp->ps_clock.ticked)
473*25472Ssam 					(void) psrfnext(psp, psaddr);
4747296Ssam 				psp->ps_clock.ticked = 0;
4757296Ssam #ifdef EXTERNAL_SYNC
4767296Ssam 				splx(x);
4777296Ssam #endif
4787296Ssam 			}
4797296Ssam 	}
4807296Ssam tryhit:
4818572Sroot 	if (request & HIT_REQ) {		/* Hit request */
4827296Ssam 		psp->ps_hit.icnt++;
4837296Ssam 	}
4848572Sroot 	if (request == 0)
4857296Ssam 		psp->ps_strayintr++;
4867296Ssam 	RESTORPSADDR();
4877296Ssam }
4887296Ssam 
4897296Ssam psrfnext(psp, psaddr)
4907296Ssam 	register struct ps *psp;
4917296Ssam 	register struct psdevice *psaddr;
4927296Ssam {
493*25472Ssam 	unsigned short int start, last;
4947296Ssam 
4958572Sroot 	if (psp->ps_refresh.srcntr < psp->ps_refresh.nsraddrs)
4967296Ssam 		psrfstart(psp->ps_refresh.sraddrs[psp->ps_refresh.srcntr++],
497*25472Ssam 						0, psp, psaddr);
4988572Sroot 	else if (psp->ps_refresh.srcntr == psp->ps_refresh.nsraddrs
4997296Ssam 				&& psp->ps_dbuffer.state == ON_DB) {
500*25472Ssam 		start = psp->ps_dbuffer.dbaddrs[psp->ps_dbuffer.rbuffer];
501*25472Ssam 		last = start+psp->ps_dbuffer.dbsize;
502*25472Ssam 		psrfstart(start, last, psp, psaddr);
5037296Ssam 		psp->ps_refresh.srcntr++;	/* flag for after dbuffer */
5047296Ssam 	} else
5057296Ssam 		return(0);
5067296Ssam 	return(1);
5077296Ssam }
5087296Ssam 
509*25472Ssam psrfstart(dfaddr, last, psp, psaddr)
510*25472Ssam 	unsigned short int dfaddr, last;
5117296Ssam 	register struct ps *psp;
5127296Ssam 	register struct psdevice *psaddr;
5137296Ssam {
514*25472Ssam 	short int dummy;
5157296Ssam 
5167296Ssam 	PSWAIT();
5177296Ssam 	psaddr->ps_addr = RFASA;
5187296Ssam 	PSWAIT();
5197296Ssam 	psaddr->ps_data = dfaddr;
5207296Ssam 	PSWAIT();
521*25472Ssam 	if(last != 0)
522*25472Ssam 		psaddr->ps_data = last;
523*25472Ssam 	else
524*25472Ssam 		dummy = psaddr->ps_data;/* just access to get to status reg */
5257296Ssam 	PSWAIT();
5267296Ssam 	psaddr->ps_data = RFSTART;	/* may want to | this value in */
5277296Ssam 	psp->ps_refresh.mode = RUNNING_RF;
5287296Ssam }
5297296Ssam 
530*25472Ssam /*ARGSUSED*/
5317296Ssam psrfstop(psaddr, psp)
5327296Ssam 	register struct psdevice *psaddr;
5337296Ssam 	register struct ps *psp;
5347296Ssam {
5357296Ssam 
5367296Ssam 	PSWAIT();
5377296Ssam 	psaddr->ps_addr = RFSR;
5387296Ssam 	PSWAIT();
5397296Ssam 	psaddr->ps_data = 0;
5407296Ssam }
5417296Ssam 
5427296Ssam psdbswitch(psp, psaddr)
5437296Ssam 	register struct ps *psp;
5447296Ssam 	register struct psdevice *psaddr;
5457296Ssam {
5467296Ssam 
5477296Ssam 	psp->ps_dbuffer.rbuffer = !psp->ps_dbuffer.rbuffer;
5487296Ssam 	pssetmapbounds(psp, psaddr);
549*25472Ssam 	(void) psmapnext(psp, psaddr);
5507296Ssam }
5517296Ssam 
5527296Ssam psmapnext(psp, psaddr)
5537296Ssam 	register struct ps *psp;
5547296Ssam 	register struct psdevice *psaddr;
5557296Ssam {
5567296Ssam 
5578572Sroot 	if (psp->ps_map.mcntr < psp->ps_map.nmaddrs)
5587296Ssam 		psmapstart(psp->ps_map.maddrs[psp->ps_map.mcntr++], psp, psaddr);
5597296Ssam 	else
5607296Ssam 		return(0);
5617296Ssam 	return(1);
5627296Ssam }
5637296Ssam 
5647296Ssam pssetmapbounds(psp, psaddr)
5657296Ssam 	register struct ps *psp;
5667296Ssam 	register struct psdevice *psaddr;
5677296Ssam {
568*25472Ssam 	unsigned short int start, last;
5697296Ssam 
5707296Ssam 	PSWAIT();
5717296Ssam 	psaddr->ps_addr = MAOL;
5727296Ssam 	PSWAIT();
5738572Sroot 	if (psp->ps_dbuffer.state == ON_DB) {
574*25472Ssam 		start = psp->ps_dbuffer.dbaddrs[!psp->ps_dbuffer.rbuffer];
575*25472Ssam 		last = start+psp->ps_dbuffer.dbsize-2;   /* 2 for halt cmd */
576*25472Ssam 		psaddr->ps_data = last;
5777296Ssam 		PSWAIT();
5787296Ssam 		psaddr->ps_data = start;
5797296Ssam 	} else {
5807296Ssam 		start = psaddr->ps_data;	/* dummy: don't update limit */
5817296Ssam 		PSWAIT();
5827296Ssam 		psaddr->ps_data = psp->ps_map.outputstart;
5837296Ssam 	}
5847296Ssam }
5857296Ssam 
5867296Ssam psmapstart(dfaddr, psp, psaddr)
587*25472Ssam 	unsigned short int dfaddr;
5887296Ssam 	register struct ps *psp;
5897296Ssam 	register struct psdevice *psaddr;
5907296Ssam {
5917296Ssam 
5927296Ssam 	PSWAIT();
5937296Ssam 	psaddr->ps_addr = MAIA;
5947296Ssam 	PSWAIT();
5957296Ssam 	psaddr->ps_data = dfaddr;
5967296Ssam 	PSWAIT();
5977296Ssam 	psaddr->ps_data = MAO|MAI;	/* may want more here */
5987296Ssam 	psp->ps_map.mode = RUNNING_MAP;
5997296Ssam }
6007296Ssam 
601*25472Ssam int pskillcnt = 1;
602*25472Ssam 
603*25472Ssam psmapstop(psaddr, psp, request)
6047296Ssam 	register struct psdevice *psaddr;
605*25472Ssam 	register struct ps *psp;
606*25472Ssam 	short int request;
6077296Ssam {
608*25472Ssam 	register int i;
6097296Ssam 
610*25472Ssam 	request = request&(HALT_REQ|MOSTOP_REQ); 	/* overkill?? */
611*25472Ssam 	for(i = 0; i < pskillcnt; i++) {
612*25472Ssam 		PSWAIT();
613*25472Ssam 		psaddr->ps_addr = MASR;
614*25472Ssam 		PSWAIT();
615*25472Ssam 		psaddr->ps_data = IOUT;		/* zero MAI & MAO bits */
616*25472Ssam 		PSWAIT();
617*25472Ssam 		psaddr->ps_addr = MAIA;
618*25472Ssam 		PSWAIT();
619*25472Ssam 		psaddr->ps_data = 0;		/* 0 input address register */
620*25472Ssam 		PSWAIT();
621*25472Ssam 		psaddr->ps_addr = MAOA;
622*25472Ssam 		PSWAIT();
623*25472Ssam 		psaddr->ps_data = 0;		/* 0 output address register */
624*25472Ssam 		PSWAIT();
625*25472Ssam 		psaddr->ps_addr = SYSREQ;
626*25472Ssam 		PSWAIT();
627*25472Ssam 		psaddr->ps_data = request;
628*25472Ssam 	}
629*25472Ssam 	psp->ps_map.mode = STOPPED_MAP;
6307296Ssam }
6317296Ssam 
6327296Ssam /*ARGSUSED*/
6337296Ssam psdeviceintr(dev)
6347296Ssam 	dev_t dev;
6357296Ssam {
6367296Ssam 
6377296Ssam 	printf("ps device intr\n");
6387296Ssam }
6397296Ssam 
6407296Ssam /*ARGSUSED*/
6417296Ssam psdmaintr(dev)
6427296Ssam 	dev_t dev;
6437296Ssam {
6447296Ssam 
6457296Ssam 	printf("ps dma intr\n");
6467296Ssam }
6477296Ssam 
648*25472Ssam /*ARGSUSED*/
6497296Ssam psreset(uban)
6507296Ssam 	int uban;
6517296Ssam {
6527296Ssam }
6537296Ssam 
654*25472Ssam /*ARGSUSED*/
6557296Ssam psextsync(PC, PS) {
6567296Ssam 	register int n;
6577296Ssam 	register struct psdevice *psaddr;
6587296Ssam 	register struct ps *psp;
6597296Ssam 	register int savepsaddr;
6607296Ssam 
6617296Ssam #ifdef EXTERNAL_SYNC
6628572Sroot 	for (psp = ps, n = 0; n < NPS; psp++, n++) {
6638572Sroot 		if (!psp->ps_open)
6647296Ssam 			continue;
66514600Ssam 		if(psp->ps_refresh.mode == SYNCING_RF
66614600Ssam 					&& psp->ps_refresh.state != TIME_RF) {
6677296Ssam 			psaddr = (struct psdevice *) psdinfo[n]->ui_addr;
6687296Ssam 			SAVEPSADDR();
669*25472Ssam 			(void) psrfnext(psp, psaddr);
6707296Ssam 			RESTORPSADDR();
6717296Ssam 		} else {
6727296Ssam 			psp->ps_clock.ticked++;
6737296Ssam 			psp->ps_clock.missed++;
6747296Ssam 		}
6757296Ssam 	}
6767296Ssam #endif
6777296Ssam }
6787296Ssam #endif
679