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

📄 dh.c

📁 UNIX v6 源代码
💻 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 "../param.h"#include "../conf.h"#include "../user.h"#include "../tty.h"#include "../proc.h"#define	DHADDR	0160020#define	NDH11	16	/* number of lines */#define	DHNCH	8	/* max number of DMA chars */struct	tty dh11[NDH11];/* * Place from which to do DMA on output */char	dh_clist[NDH11][DHNCH];/* * Used to communicate the number of lines to the DM */int	ndh11	NDH11;/* * 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	IENABLE	030100#define	PERROR	010000#define	FRERROR	020000#define	XINT	0100000#define	SSPEED	7	/* standard speed: 300 baud *//* * Software copy of last dhbar */int	dhsar;struct dhregs {	int dhcsr;	int dhnxch;	int dhlpr;	int dhcar;	int dhbcr;	int dhbar;	int dhbreak;	int dhsilo;};/* * Open a DH11 line. */dhopen(dev, flag){	register struct tty *tp;	extern dhstart();	if (dev.d_minor >= NDH11) {		u.u_error = ENXIO;		return;	}	tp = &dh11[dev.d_minor];	tp->t_addr = dhstart;	tp->t_dev = dev;	DHADDR->dhcsr =| IENABLE;	tp->t_state =| WOPEN|SSTART;	if ((tp->t_state&ISOPEN) == 0) {		tp->t_erase = CERASE;		tp->t_kill = CKILL;		tp->t_speeds = SSPEED | (SSPEED<<8);		tp->t_flags = ODDP|EVENP|ECHO;		dhparam(tp);	}	dmopen(dev);	tp->t_state =& ~WOPEN;	tp->t_state =| ISOPEN;	if (u.u_procp->p_ttyp == 0)		u.u_procp->p_ttyp = tp;}/* * Close a DH11 line. */dhclose(dev){	register struct tty *tp;	tp = &dh11[dev.d_minor];	dmclose(dev);	tp->t_state =& (CARR_ON|SSTART);	wflushtty(tp);}/* * Read from a DH11 line. */dhread(dev){	ttread(&dh11[dev.d_minor]);}/* * write on a DH11 line */dhwrite(dev){	ttwrite(&dh11[dev.d_minor]);}/* * DH11 receiver interrupt. */dhrint(){	register struct tty *tp;	register int c;	while ((c = DHADDR->dhnxch) < 0) {	/* char. present */		tp = &dh11[(c>>8)&017];		if (tp >= &dh11[NDH11])			continue;		if((tp->t_state&ISOPEN)==0 || (c&PERROR)) {			wakeup(tp);			continue;		}		if (c&FRERROR)		/* break */			if (tp->t_flags&RAW)				c = 0;		/* null (for getty) */			else				c = 0177;	/* DEL (intr) */		ttyinput(c, tp);	}}/* * stty/gtty for DH11 */dhsgtty(dev, av)int *av;{	register struct tty *tp;	register r;	tp = &dh11[dev.d_minor];	if (ttystty(tp, av))		return;	dhparam(tp);}/* * Set parameters from open or stty into the DH hardware * registers. */dhparam(atp)struct tty *atp;{	register struct tty *tp;	register int lpr;	tp = atp;	spl5();	DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;	/*	 * Hang up line?	 */	if (tp->t_speeds.lobyte==0) {		tp->t_flags =| HUPCL;		dmclose(tp->t_dev);		return;	}	lpr = (tp->t_speeds.hibyte<<10) | (tp->t_speeds.lobyte<<6);	if (tp->t_speeds.lobyte == 4)		/* 134.5 baud */		lpr =| BITS6|PENABLE|HDUPLX; else		if (tp->t_flags&EVENP)			if (tp->t_flags&ODDP)				lpr =| BITS8; else				lpr =| BITS7|PENABLE; else			lpr =| BITS7|OPAR|PENABLE;	if (tp->t_speeds.lobyte == 3)	/* 110 baud */		lpr =| TWOSB;	DHADDR->dhlpr = lpr;	spl0();}/* * DH11 transmitter interrupt. * Restart each line which used to be active but has * terminated transmission since the last interrupt. */dhxint(){	register struct tty *tp;	register ttybit, bar;	bar = dhsar & ~DHADDR->dhbar;	DHADDR->dhcsr =& ~XINT;	ttybit = 1;	for (tp = dh11; bar; tp++) {		if(bar&ttybit) {			dhsar =& ~ttybit;			bar =& ~ttybit;			tp->t_state =& ~BUSY;			dhstart(tp);		}		ttybit =<< 1;	}}/* * Start (restart) transmission on the given DH11 line. */dhstart(atp)struct tty *atp;{	extern ttrstrt();	register c, nch;	register struct tty *tp;	int sps;	char *cp;	sps = PS->integ;	spl5();	tp = atp;	/*	 * If it's currently active, or delaying,	 * no need to do anything.	 */	if (tp->t_state&(TIMEOUT|BUSY))		goto out;	/*	 * t_char is a delay indicator which may have been	 * left over from the last start.	 * Arrange for the delay.	 */	if (c = tp->t_char) {		tp->t_char = 0;		timeout(ttrstrt, tp, (c&0177)+6);		tp->t_state =| TIMEOUT;		goto out;	}	cp = dh_clist[tp->t_dev.d_minor];	nch = 0;	/*	 * Copy DHNCH characters, or up to a delay indicator,	 * to the DMA area.	 */	while (nch > -DHNCH && (c = getc(&tp->t_outq))>=0) {		if (c >= 0200) {			tp->t_char = c;			break;		}		*cp++ = c;		nch--;	}	/*	 * If the writer was sleeping on output overflow,	 * wake him when low tide is reached.	 */	if (tp->t_outq.c_cc<=TTLOWAT && tp->t_state&ASLEEP) {		tp->t_state =& ~ASLEEP;		wakeup(&tp->t_outq);	}	/*	 * If any characters were set up, start transmission;	 * otherwise, check for possible delay.	 */	if (nch) {		DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;		DHADDR->dhcar = cp+nch;		DHADDR->dhbcr = nch;		c = 1<<tp->t_dev.d_minor;		DHADDR->dhbar =| c;		dhsar =| c;		tp->t_state =| BUSY;	} else if (c = tp->t_char) {		tp->t_char = 0;		timeout(ttrstrt, tp, (c&0177)+6);		tp->t_state =| TIMEOUT;	}    out:	PS->integ = sps;}

⌨️ 快捷键说明

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