⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1982, 1986 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)ps.c	7.7 (Berkeley) 5/9/91 *//* * Evans and Sutherland Picture System 2 driver -- Bill Reeves. *//* *	Still to be done: *		WAIT_HIT */#include "ps.h"#if NPS > 0#define EXTERNAL_SYNC#include "../include/pte.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/ioctl.h"#include "sys/map.h"#include "sys/buf.h"#include "sys/conf.h"#include "sys/user.h"#include "sys/uio.h"#include "ubareg.h"#include "ubavar.h"#include "psreg.h"int	psprobe(), psattach(), psextsync();int	psclockintr(), pssystemintr(), psdeviceintr(), psdmaintr();struct	uba_device *psdinfo[NPS];u_short	psstd[] = { 0 };struct	uba_driver psdriver =     { psprobe, 0, psattach, 0, psstd, "ps", psdinfo };#define	PSUNIT(dev)	(minor(dev))#define MAXAUTOREFRESH	4#define MAXAUTOMAP	4#define MAXDBSIZE	(0177777/2)#define PSPRI		(PZERO+1)#define PSWAIT(psaddr) { \	register short i = 20000, j; \	while (i-- != 0 && ((j = psaddr->ps_iostat) & DIOREADY) == 0) \		;\}struct psrefresh {	enum {		SINGLE_STEP_RF,		AUTO_RF,		TIME_RF	} state;	enum {		RUNNING_RF,		SYNCING_RF,		WAITING_MAP,		STOPPED_RF	} mode;	u_short	sraddrs[MAXAUTOREFRESH];	short	nsraddrs;	short	srcntr;	char	waiting;	char	stop;	int	icnt;	int	timecnt;};struct psdbuffer {	enum {		ON_DB,		OFF_DB	} state;	u_short	dbaddrs[2];	u_short	dbsize;	short	rbuffer;};struct psmap {	enum {		SINGLE_STEP_MAP,		AUTO_MAP	} state;	enum {		RUNNING_MAP,		WAITING_RF,		WAITING_START,		STOPPED_MAP	} mode;	u_short	maddrs[MAXAUTOMAP];	short	nmaddrs;	short	mcntr;	short	outputstart;	char	waiting;	char	stop;	int	icnt;};/* * PS2 software state. */struct ps {	char	ps_open;		/* device is open */	uid_t 	ps_uid;			/* uid of device owner */	struct	psrefresh ps_refresh;	/* refresh state */	struct	psdbuffer ps_dbuffer;	/* double buffering state */	struct	psmap ps_map;		/* segment map state */	int	ps_clockticks;		/* clock ints between refresh */	int	ps_clockmiss;		/* clock ints w/o refresh */	int	ps_clockcnt;		/* count of clock interrupts */	int	ps_hitcnt;		/* count of hit interrupts */	int	ps_strayintr;		/* count of stray interrupts */	int	ps_icnt;		/* count of system interrupts *//* BEGIN GROT */	int	ps_lastrequest;	int	ps_lastrequest2;	int	ps_lastfunnyrequest;	int	ps_funnycnt;/* END GROT */} ps[NPS];psprobe(reg)	caddr_t reg;{	register int br, cvec;	register struct psdevice *psaddr = (struct psdevice *)reg;#ifdef lint	br = 0; cvec = br; br = cvec;	psclockintr((dev_t)0); pssystemintr((dev_t)0);	psdeviceintr((dev_t)0); psdmaintr((dev_t)0);	psextsync(0, 0);#endif	psaddr->ps_iostat = PSRESET;	DELAY(200);	psaddr->ps_addr = RTCIE;	PSWAIT(psaddr); psaddr->ps_data = 01;	psaddr->ps_iostat = PSIE;	psaddr->ps_addr = RTCSR;	PSWAIT(psaddr); psaddr->ps_data = SYNC|RUN;	DELAY(200000);	psaddr->ps_addr = RTCREQ;	PSWAIT(psaddr); psaddr->ps_data = 01;	psaddr->ps_iostat = 0;	psaddr->ps_iostat = PSRESET;	return (sizeof (struct psdevice));}/*ARGSUSED*/psattach(ui)	struct uba_device *ui;{}psopen(dev)	dev_t dev;{	register struct ps *psp;	register struct uba_device *ui;	register int unit = PSUNIT(dev);	if (unit >= NPS || (psp = &ps[minor(dev)])->ps_open ||	    (ui = psdinfo[unit]) == 0 || ui->ui_alive == 0)		return (ENXIO);	psp->ps_open = 1;	psp->ps_uid = u.u_uid;	psp->ps_strayintr = 0;	psp->ps_refresh.state = SINGLE_STEP_RF;	psp->ps_refresh.mode = STOPPED_RF;	psp->ps_refresh.waiting = 0;	psp->ps_refresh.stop = 0;	psp->ps_dbuffer.state = OFF_DB;	psp->ps_map.state = SINGLE_STEP_MAP;	psp->ps_map.mode = STOPPED_MAP;	psp->ps_map.waiting = 0;	psp->ps_map.stop = 0;	psp->ps_clockticks = 0;	psp->ps_clockmiss = 0;	psp->ps_refresh.icnt = psp->ps_map.icnt = psp->ps_clockcnt = 0;	psp->ps_hitcnt = 0;	psp->ps_icnt = 0;	maptouser(ui->ui_addr);	return (0);}psclose(dev)	dev_t dev;{	register struct psdevice *psaddr = 	    (struct psdevice *)psdinfo[PSUNIT(dev)]->ui_addr;	ps[PSUNIT(dev)].ps_open = 0;	psaddr->ps_iostat = 0;			 /* clear IENABLE */	PSWAIT(psaddr); psaddr->ps_addr = RFSR;	 /* set in auto refresh mode */	PSWAIT(psaddr); psaddr->ps_data = AUTOREF;	unmaptouser((caddr_t)psaddr);	return (0);}/*ARGSUSED*/psread(dev, uio)	dev_t dev;	struct uio *uio;{}/*ARGSUSED*/pswrite(dev, uio)	dev_t dev;	struct uio *uio;{}/*ARGSUSED*/psioctl(dev, cmd, data, flag)	register caddr_t data;{	register struct uba_device *ui = psdinfo[PSUNIT(dev)];	register struct ps *psp = &ps[PSUNIT(dev)];	int *waddr = *(int **)data;	int n, arg, i, error = 0;	switch (cmd) {	case PSIOGETADDR:		*(caddr_t *)data = ui->ui_addr;		break;	case PSIOAUTOREFRESH:		n = fuword((caddr_t)waddr++);		if (n == -1)			return (EFAULT);		if (n < 0 || n > MAXAUTOREFRESH)			return (EINVAL);		for (i = 0; i < n; i++) {			if ((arg = fuword((caddr_t)waddr++)) == -1)				return (EFAULT);			psp->ps_refresh.sraddrs[i] = arg;		}		psp->ps_refresh.state = AUTO_RF;		psp->ps_refresh.nsraddrs = n;		psp->ps_refresh.srcntr = 0;		psp->ps_refresh.mode = WAITING_MAP;		break;	case PSIOAUTOMAP:		n = fuword((caddr_t)waddr++);		if (n == -1)			return (EFAULT);		if (n < 0 || n > MAXAUTOMAP)			return (EINVAL);		for (i = 0; i < n; i++) {			if ((arg = fuword((caddr_t)waddr++)) == -1)				return (EFAULT);			psp->ps_map.maddrs[i] = arg;		}		if ((arg = fuword((caddr_t)waddr++)) == -1)			return (EFAULT);		psp->ps_map.outputstart = arg;		psp->ps_map.state = AUTO_MAP;		psp->ps_map.nmaddrs = n;		psp->ps_map.mcntr = 0;		psp->ps_map.mode = WAITING_START;		break;	case PSIOSINGLEREFRESH:		psp->ps_refresh.state = SINGLE_STEP_RF;		break;	case PSIOSINGLEMAP:		psp->ps_map.state = SINGLE_STEP_MAP;		break;	case PSIODOUBLEBUFFER:		if ((arg = fuword((caddr_t)waddr++)) == -1)			return (EFAULT);		psp->ps_dbuffer.dbaddrs[0] = arg;		if ((arg = fuword((caddr_t)waddr++)) == -1)			return (EFAULT);		if (arg <= 0 || arg > MAXDBSIZE)			return (EINVAL);		psp->ps_dbuffer.dbsize = arg;		psp->ps_dbuffer.dbaddrs[1] = psp->ps_dbuffer.dbaddrs[0]+arg;		psp->ps_dbuffer.state = ON_DB;		psp->ps_dbuffer.rbuffer = 0;		break;	case PSIOSINGLEBUFFER:		psp->ps_dbuffer.state = OFF_DB;		break;	case PSIOTIMEREFRESH:		if (psp->ps_refresh.state != SINGLE_STEP_RF)			return (EINVAL);		if ((arg = fuword((caddr_t)waddr++)) == -1)			return (EFAULT);		psp->ps_refresh.state = TIME_RF;		psp->ps_refresh.timecnt = arg;		break;	case PSIOWAITREFRESH:		if (psp->ps_refresh.mode != RUNNING_RF)	/* not running */			return (0);			/* dont wait */		/* fall into ... */	case PSIOSTOPREFRESH:		if (cmd == PSIOSTOPREFRESH) {			if (psp->ps_refresh.mode == STOPPED_RF &&			    psp->ps_refresh.state != TIME_RF)				return (0);			psp->ps_refresh.stop = 1;		}		(void) spl5();		psp->ps_refresh.waiting = 1;		while (psp->ps_refresh.waiting)			if (error = tsleep(&psp->ps_refresh.waiting,			    PSPRI | PCATCH, devwait, 0))				break;		(void) spl0();		if (error)			return (error);		if (cmd == PSIOSTOPREFRESH)			psp->ps_refresh.mode = STOPPED_RF;		if (psp->ps_refresh.state == TIME_RF)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -