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

📄 dc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
voiddcintr(unit)	register int unit;{	register dcregs *dcaddr;	register unsigned csr;	unit <<= 2;	dcaddr = (dcregs *)dcpdma[unit].p_addr;	while ((csr = dcaddr->dc_csr) & (CSR_RDONE | CSR_TRDY)) {		if (csr & CSR_RDONE)			dcrint(unit);		if (csr & CSR_TRDY)			dcxint(&dc_tty[unit + ((csr >> 8) & 03)]);	}}dcrint(unit)	register int unit;{	register dcregs *dcaddr;	register struct tty *tp;	register int c, cc;	register struct tty *tp0;	int overrun = 0;	dcaddr = (dcregs *)dcpdma[unit].p_addr;	tp0 = &dc_tty[unit];	while ((c = dcaddr->dc_rbuf) < 0) {	/* char present */		cc = c & 0xff;		tp = tp0 + ((c >> 8) & 03);		if ((c & RBUF_OERR) && overrun == 0) {			log(LOG_WARNING, "dc%d,%d: silo overflow\n", unit >> 2,				(c >> 8) & 03);			overrun = 1;		}		/* the keyboard requires special translation */		if (tp == &dc_tty[DCKBD_PORT] && cn_tab.cn_screen) {#ifdef KADB			if (cc == LK_DO) {				spl0();				kdbpanic();				return;			}#endif#ifdef DEBUG			debugChar = cc;#endif			if (dcDivertXInput) {				(*dcDivertXInput)(cc);				return;			}			if ((cc = kbdMapChar(cc)) < 0)				return;		} else if (tp == &dc_tty[DCMOUSE_PORT] && dcMouseButtons) {			register MouseReport *mrp;			static MouseReport currentRep;			mrp = &currentRep;			mrp->byteCount++;			if (cc & MOUSE_START_FRAME) {				/*				 * The first mouse report byte (button state).				 */				mrp->state = cc;				if (mrp->byteCount > 1)					mrp->byteCount = 1;			} else if (mrp->byteCount == 2) {				/*				 * The second mouse report byte (delta x).				 */				mrp->dx = cc;			} else if (mrp->byteCount == 3) {				/*				 * The final mouse report byte (delta y).				 */				mrp->dy = cc;				mrp->byteCount = 0;				if (mrp->dx != 0 || mrp->dy != 0) {					/*					 * If the mouse moved,					 * post a motion event.					 */					(*dcMouseEvent)(mrp);				}				(*dcMouseButtons)(mrp);			}			return;		}		if (!(tp->t_state & TS_ISOPEN)) {			wakeup((caddr_t)&tp->t_rawq);#ifdef PORTSELECTOR			if (!(tp->t_state & TS_WOPEN))#endif				return;		}		if (c & RBUF_FERR)			cc |= TTY_FE;		if (c & RBUF_PERR)			cc |= TTY_PE;		(*linesw[tp->t_line].l_rint)(cc, tp);	}	DELAY(10);}voiddcxint(tp)	register struct tty *tp;{	register struct pdma *dp;	register dcregs *dcaddr;	dp = &dcpdma[minor(tp->t_dev)];	if (dp->p_mem < dp->p_end) {		dcaddr = (dcregs *)dp->p_addr;		dcaddr->dc_tdr = dc_brk[(tp - dc_tty) >> 2] | *dp->p_mem++;		MachEmptyWriteBuffer();		DELAY(10);		return;	}	tp->t_state &= ~TS_BUSY;	if (tp->t_state & TS_FLUSH)		tp->t_state &= ~TS_FLUSH;	else {		ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);		dp->p_end = dp->p_mem = tp->t_outq.c_cf;	}	if (tp->t_line)		(*linesw[tp->t_line].l_start)(tp);	else		dcstart(tp);	if (tp->t_outq.c_cc == 0 || !(tp->t_state & TS_BUSY)) {		dcaddr = (dcregs *)dp->p_addr;		dcaddr->dc_tcr &= ~(1 << (minor(tp->t_dev) & 03));		MachEmptyWriteBuffer();		DELAY(10);	}}voiddcstart(tp)	register struct tty *tp;{	register struct pdma *dp;	register dcregs *dcaddr;	register int cc;	int s;	dp = &dcpdma[minor(tp->t_dev)];	dcaddr = (dcregs *)dp->p_addr;	s = spltty();	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))		goto out;	if (tp->t_outq.c_cc <= tp->t_lowat) {		if (tp->t_state & TS_ASLEEP) {			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}		selwakeup(&tp->t_wsel);	}	if (tp->t_outq.c_cc == 0)		goto out;	/* handle console specially */	if (tp == &dc_tty[DCKBD_PORT] && cn_tab.cn_screen) {		while (tp->t_outq.c_cc > 0) {			cc = getc(&tp->t_outq) & 0x7f;			cnputc(cc);		}		/*		 * After we flush the output queue we may need to wake		 * up the process that made the output.		 */		if (tp->t_outq.c_cc <= tp->t_lowat) {			if (tp->t_state & TS_ASLEEP) {				tp->t_state &= ~TS_ASLEEP;				wakeup((caddr_t)&tp->t_outq);			}			selwakeup(&tp->t_wsel);		}		goto out;	}	if (tp->t_flags & (RAW|LITOUT))		cc = ndqb(&tp->t_outq, 0);	else {		cc = ndqb(&tp->t_outq, 0200);		if (cc == 0) {			cc = getc(&tp->t_outq);			timeout(ttrstrt, (void *)tp, (cc & 0x7f) + 6);			tp->t_state |= TS_TIMEOUT;			goto out;		}	}	tp->t_state |= TS_BUSY;	dp->p_end = dp->p_mem = tp->t_outq.c_cf;	dp->p_end += cc;	dcaddr->dc_tcr |= 1 << (minor(tp->t_dev) & 03);	MachEmptyWriteBuffer();out:	splx(s);}/* * Stop output on a line. *//*ARGSUSED*/dcstop(tp, flag)	register struct tty *tp;{	register struct pdma *dp;	register int s;	dp = &dcpdma[minor(tp->t_dev)];	s = spltty();	if (tp->t_state & TS_BUSY) {		dp->p_end = dp->p_mem;		if (!(tp->t_state & TS_TTSTOP))			tp->t_state |= TS_FLUSH;	}	splx(s);}dcmctl(dev, bits, how)	dev_t dev;	int bits, how;{	register dcregs *dcaddr;	register int unit, mbits;	int b, s;	register int msr;	unit = minor(dev);	b = 1 << (unit & 03);	dcaddr = (dcregs *)dcpdma[unit].p_addr;	s = spltty();	/* only channel 2 has modem control (what about line 3?) */	mbits = DML_DTR | DML_DSR | DML_CAR;	switch (unit & 03) {	case 2:		mbits = 0;		if (dcaddr->dc_tcr & TCR_DTR2)			mbits |= DML_DTR;		msr = dcaddr->dc_msr;		if (msr & MSR_CD2)			mbits |= DML_CAR;		if (msr & MSR_DSR2) {			if (pmax_boardtype == DS_PMAX)				mbits |= DML_CAR | DML_DSR;			else				mbits |= DML_DSR;		}		break;	case 3:		if (pmax_boardtype != DS_PMAX) {			mbits = 0;			if (dcaddr->dc_tcr & TCR_DTR3)				mbits |= DML_DTR;			msr = dcaddr->dc_msr;			if (msr & MSR_CD3)				mbits |= DML_CAR;			if (msr & MSR_DSR3)				mbits |= DML_DSR;		}	}	switch (how) {	case DMSET:		mbits = bits;		break;	case DMBIS:		mbits |= bits;		break;	case DMBIC:		mbits &= ~bits;		break;	case DMGET:		(void) splx(s);		return (mbits);	}	switch (unit & 03) {	case 2:		if (mbits & DML_DTR)			dcaddr->dc_tcr |= TCR_DTR2;		else			dcaddr->dc_tcr &= ~TCR_DTR2;		break;	case 3:		if (pmax_boardtype != DS_PMAX) {			if (mbits & DML_DTR)				dcaddr->dc_tcr |= TCR_DTR3;			else				dcaddr->dc_tcr &= ~TCR_DTR3;		}	}	if ((mbits & DML_DTR) && (dcsoftCAR[unit >> 2] & b))		dc_tty[unit].t_state |= TS_CARR_ON;	(void) splx(s);	return (mbits);}/* * This is called by timeout() periodically. * Check to see if modem status bits have changed. */voiddcscan(arg)	void *arg;{	register dcregs *dcaddr;	register struct tty *tp;	register int i, bit, car;	int s;	s = spltty();	/* only channel 2 has modem control (what about line 3?) */	dcaddr = (dcregs *)dcpdma[i = 2].p_addr;	tp = &dc_tty[i];	bit = TCR_DTR2;	if (dcsoftCAR[i >> 2] & bit)		car = 1;	else		car = dcaddr->dc_msr & MSR_DSR2;	if (car) {		/* carrier present */		if (!(tp->t_state & TS_CARR_ON))			(void)(*linesw[tp->t_line].l_modem)(tp, 1);	} else if ((tp->t_state & TS_CARR_ON) &&	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0)		dcaddr->dc_tcr &= ~bit;	splx(s);	timeout(dcscan, (void *)0, hz);}/* * ---------------------------------------------------------------------------- * * dcGetc -- * *	Read a character from a serial line. * * Results: *	A character read from the serial port. * * Side effects: *	None. * * ---------------------------------------------------------------------------- */intdcGetc(dev)	dev_t dev;{	register dcregs *dcaddr;	register int c;	int s;	dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr;	if (!dcaddr)		return (0);	s = spltty();	for (;;) {		if (!(dcaddr->dc_csr & CSR_RDONE))			continue;		c = dcaddr->dc_rbuf;		DELAY(10);		if (((c >> 8) & 03) == (minor(dev) & 03))			break;	}	splx(s);	return (c & 0xff);}/* * Send a char on a port, non interrupt driven. */voiddcPutc(dev, c)	dev_t dev;	int c;{	register dcregs *dcaddr;	register u_short tcr;	register int timeout;	int s, line;	s = spltty();	dcaddr = (dcregs *)dcpdma[minor(dev)].p_addr;	tcr = dcaddr->dc_tcr;	dcaddr->dc_tcr = tcr | (1 << minor(dev));	MachEmptyWriteBuffer();	DELAY(10);	while (1) {		/*		 * Wait for transmitter to be not busy.		 */		timeout = 1000000;		while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)			timeout--;		if (timeout == 0) {			printf("dcPutc: timeout waiting for CSR_TRDY\n");			break;		}		line = (dcaddr->dc_csr >> 8) & 3;		/*		 * Check to be sure its the right port.		 */		if (line != minor(dev)) {			tcr |= 1 << line;			dcaddr->dc_tcr &= ~(1 << line);			MachEmptyWriteBuffer();			DELAY(10);			continue;		}		/*		 * Start sending the character.		 */		dcaddr->dc_tdr = dc_brk[0] | (c & 0xff);		MachEmptyWriteBuffer();		DELAY(10);		/*		 * Wait for character to be sent.		 */		while (1) {			/*			 * cc -O bug: this code produces and infinite loop!			 * while (!(dcaddr->dc_csr & CSR_TRDY))			 *	;			 */			timeout = 1000000;			while (!(dcaddr->dc_csr & CSR_TRDY) && timeout > 0)				timeout--;			line = (dcaddr->dc_csr >> 8) & 3;			if (line != minor(dev)) {				tcr |= 1 << line;				dcaddr->dc_tcr &= ~(1 << line);				MachEmptyWriteBuffer();				DELAY(10);				continue;			}			dcaddr->dc_tcr &= ~(1 << minor(dev));			MachEmptyWriteBuffer();			DELAY(10);			break;		}		break;	}	/*	 * Enable interrupts for other lines which became ready.	 */	if (tcr & 0xF) {		dcaddr->dc_tcr = tcr;		MachEmptyWriteBuffer();		DELAY(10);	}	splx(s);}#endif /* NDC */

⌨️ 快捷键说明

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