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

📄 dh.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
/* *	DH-11 driver *	This driver calls on the DHDM driver. *	If the DH has no DM11-BB, then the latter will *	be fake. To insure loading of the correct DM code, *	lib2 should have dhdm.o, dh.o and dhfdm.o in that order. */#include "../h/param.h"#include "../h/conf.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/tty.h"#define	q3	tp->t_outq#define	DHADDR	((struct device *)0160020)#define	NDH11	16	/* number of lines */struct	tty dh11[NDH11];char	dhcc[NDH11];int	dhchars[(NDH11+15)/16];int	ndh11	= NDH11;int	dhstart();int	ttrstrt();/* * Hardware control bits */#define	BITS6	01#define	BITS7	02#define	BITS8	03#define	TWOSB	04#define	PENABLE	020/* DEC manuals incorrectly say this bit causes generation of even parity. */#define	OPAR	040#define	HDUPLX	040000#define	IENAB	030100#define	PERROR	010000#define	FRERROR	020000#define	OVERRUN	040000#define	XINT	0100000#define	SSPEED	7	/* standard speed: 300 baud */#define	NSILO	16#define	DHTIME	6extern int dhtimer();/* * DM control bits */#define	TURNON	03	/* CD lead + line enable */#define	TURNOFF	01	/* line enable */#define	RQS	04	/* request to send *//* * Software copy of last dhbar */int	dhsar[(NDH11+15)/16];struct device{	union {		int	dhcsr;		char	dhcsrl;	} un;	int	dhnxch;	int	dhlpr;	char	*dhcar;	int	dhbcr;	int	dhbar;	int	dhbreak;	int	dhsilo;};/* * Open a DH11 line. */dhopen(dev, flag){	register struct tty *tp;	register d;	register struct device *addr;	static	timer_on;	int s;	d = minor(dev);	if (d >= NDH11) {		u.u_error = ENXIO;		return;	}	tp = &dh11[d];	addr = DHADDR;	addr += d>>4;	tp->t_addr = (caddr_t)addr;	tp->t_oproc = dhstart;	tp->t_iproc = NULL;	tp->t_state |= WOPEN;	s = spl6();	if (!timer_on) {		timer_on++;		timeout(dhtimer, (caddr_t)0, DHTIME);	}	splx(s);	addr->un.dhcsr |= IENAB;	if ((tp->t_state&ISOPEN) == 0) {		ttychars(tp);		tp->t_ispeed = SSPEED;		tp->t_ospeed = SSPEED;		tp->t_flags = ODDP|EVENP|ECHO;		dhparam(d);	}	if (tp->t_state&XCLUDE && u.u_uid!=0) {		u.u_error = EBUSY;		return;	}	dmopen(d);	(*linesw[tp->t_line].l_open)(dev,tp);}/* * Close a DH11 line. */dhclose(dev, flag)dev_t dev;int  flag;{	register struct tty *tp;	register d;	d = minor(dev);	tp = &dh11[d];	(*linesw[tp->t_line].l_close)(tp);	if (tp->t_state&HUPCLS)		dmctl(d, TURNOFF);	ttyclose(tp);}/* * Read from a DH11 line. */dhread(dev){register struct tty *tp;	tp = &dh11[minor(dev)];	(*linesw[tp->t_line].l_read)(tp);}/* * write on a DH11 line */dhwrite(dev){register struct tty *tp;	tp = &dh11[minor(dev)];	(*linesw[tp->t_line].l_write)(tp);}/* * DH11 receiver interrupt. */dhrint(dev){	register struct tty *tp;	register int c;	register struct device *addr;	addr = DHADDR;	addr += minor(dev);	while ((c = addr->dhnxch) < 0) {	/* char. present */		tp = &dh11[(minor(dev)<<4) + ((c>>8)&017)];		dhchars[minor(dev)]++;		if (tp >= &dh11[NDH11])			continue;		if((tp->t_state&ISOPEN)==0) {			wakeup((caddr_t)tp);			continue;		}		if (c&PERROR)			if ((tp->t_flags&(EVENP|ODDP))==EVENP			 || (tp->t_flags&(EVENP|ODDP))==ODDP )				continue;		if (c&FRERROR)		/* break */			if (tp->t_flags&RAW)				c = 0;	/* null (for getty) */			else				c = 0177;	/* DEL (intr) */		(*linesw[tp->t_line].l_rint)(c,tp);	}}/* * stty/gtty for DH11 */dhioctl(dev, cmd, addr, flag)caddr_t addr;{	register struct tty *tp;	tp = &dh11[minor(dev)];	if (ttioccomm(cmd, tp, addr, dev)) {		if (cmd==TIOCSETP||cmd==TIOCSETN)			dhparam(dev);	} else		u.u_error = ENOTTY;}/* * Set parameters from open or stty into the DH hardware * registers. */dhparam(dev){	register struct tty *tp;	register struct device *addr;	register d;	d = minor(dev);	tp = &dh11[d];	addr = (struct device *)tp->t_addr;	spl5();	addr->un.dhcsrl = (d&017) | IENAB;	/*	 * Hang up line?	 */	if ((tp->t_ispeed)==0) {		tp->t_state |= HUPCLS;		dmctl(d, TURNOFF);		return;	}	d = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);	if ((tp->t_ispeed) == 4)		/* 134.5 baud */		d |= BITS6|PENABLE|HDUPLX;	else if (tp->t_flags&RAW)		d |= BITS8;	else		d |= BITS7|PENABLE;	if ((tp->t_flags&EVENP) == 0)		d |= OPAR;	if ((tp->t_ospeed) == 3)	/* 110 baud */		d |= TWOSB;	addr->dhlpr = d;	spl0();}/* * DH11 transmitter interrupt. * Restart each line which used to be active but has * terminated transmission since the last interrupt. */dhxint(dev){	register struct tty *tp;	register struct device *addr;	register d;	int ttybit, bar, *sbar;	d = minor(dev);	addr = DHADDR + d;	addr->un.dhcsr &= ~XINT;	sbar = &dhsar[d];	bar = *sbar & ~addr->dhbar;	d <<= 4; ttybit = 1;	for(; bar; d++, ttybit <<= 1) {		if(bar&ttybit) {			*sbar &= ~ttybit;			bar &= ~ttybit;			tp = &dh11[d];			if (tp->t_line) {				(*linesw[tp->t_line].l_start)(tp);			} else {				addr->un.dhcsrl = (d&017)|IENAB;				if (tp->t_state&FLUSH)					tp->t_state &= ~FLUSH;				else {					ndflush(&q3, addr->dhcar-q3.c_cf);				}				tp->t_state &= ~BUSY;				dhstart(tp);			}		}	}}/* * Start (restart) transmission on the given DH11 line. */dhstart(tp)register struct tty *tp;{	register struct device *addr;	register nch;	int s, d;	/*	 * If it's currently active, or delaying,	 * no need to do anything.	 */	s = spl5();	d = tp-dh11;	addr = (struct device *)tp->t_addr;	if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))		goto out;	/*	 * If the writer was sleeping on output overflow,	 * wake him when low tide is reached.	 */	if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT) {		tp->t_state &= ~ASLEEP;		if (tp->t_chan)			mcstart(tp->t_chan, (caddr_t)&tp->t_outq); else			wakeup((caddr_t)&tp->t_outq);	}	if (tp->t_outq.c_cc == 0)		goto out;	/*	 * Find number of characters to transfer.	 */	if (tp->t_flags & RAW) {		nch = ndqb(&tp->t_outq, 0);	} else {		nch = ndqb(&tp->t_outq, 0200);		if (nch == 0) {			nch = getc(&tp->t_outq);			timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);			tp->t_state |= TIMEOUT;			goto out;		}	}	/*	 * If any characters were set up, start transmission;	 */	if (nch) {		addr->un.dhcsrl = (d&017)|IENAB;		addr->dhcar = tp->t_outq.c_cf;		addr->dhbcr = -nch;		dhcc[d] = nch;		nch = 1<<(d&017);		addr->dhbar |= nch;		dhsar[d>>4] |= nch;		tp->t_state |= BUSY;	}    out:	splx(s);}/* * Stop output on a line. */dhstop(tp, flag)register struct tty *tp;{	register struct device *addr;	register d, s;	addr = (struct device *)tp->t_addr;	s = spl6();	if (tp->t_state & BUSY) {		d = minor(tp->t_dev);		addr->un.dhcsrl = (d&017) | IENAB;		if ((tp->t_state&TTSTOP)==0) {			tp->t_state |= FLUSH;		}		addr->dhbcr = -1;	}	splx(s);}dhtimer(dev){register d,cc;register struct device *addr;	addr = DHADDR; d = 0;	do {		cc = dhchars[d];		dhchars[d] = 0;		if (cc > 50)			cc = 32; else			if (cc > 16)				cc = 16; else				cc = 0;		addr->dhsilo = cc;		addr += 1;		dhrint(d++);	} while (d < (NDH11+15)/16);	timeout(dhtimer, (caddr_t)0, DHTIME);}

⌨️ 快捷键说明

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