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

📄 scc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		untimeout(wakeup, (caddr_t) &tp->t_dev);		wakeup((caddr_t) &tp->t_dev);	    }	    if (tp->t_state&TS_CARR_ON) {		scc_tty_drop(tp);	    }	} else {		/* DSR has come up */	    /*	     * If DSR comes up for the first time we allow	     * 30 seconds for a live connection.	     */	    if ((sccmodem[i] & MODEM_DSR)==0) {		sccmodem[i] |= (MODEM_DSR_START|MODEM_DSR);		/*		 * we should not look for CTS|CD for about		 * 500 ms.		 */		timeout(scc_dsr_check, tp, hz*30);		scc_dsr_check(tp);}	}		/*	 * look for modem transitions in an already	 * established connection.	 */	if (tp->t_state & TS_CARR_ON) {	    if (SCC_DCD(i)) {		/*		 * CD has come up again.		 * Stop timeout from occurring if set.		 * If interval is more than 2 secs then		 * drop DTR.		 */		if ((sccmodem[i] & MODEM_CD) == 0) {		    untimeout(scc_cd_drop, tp);		    if (scc_cd_down(tp)) {			/* drop connection */			scc_tty_drop(tp);		    }		    sccmodem[i] |= MODEM_CD;		}	    } else {		/*		 * Carrier must be down for greater than		 * 2 secs before closing down the line.		 */		if (sccmodem[i] & MODEM_CD) {		    /* only start timer once */		    sccmodem[i] &= ~MODEM_CD;		    /*		     * Record present time so that if carrier		     * comes up after 2 secs, the line will drop.		     */		    scctimestamp[i] = time;		    timeout(scc_cd_drop, tp, hz * 2);		}	    }	    	    /* CTS flow control check */	    	    if (!(SCC_CTS(i))) {		/*		 * Only allow transmission when CTS is set.		 */		tp->t_state |= TS_TTSTOP;		sccmodem[i] &= ~MODEM_CTS;		sccstop(tp, 0);	    } else if (!(sccmodem[i] & MODEM_CTS)) {		/*		 * Restart transmission upon return of CTS.		 */		tp->t_state &= ~TS_TTSTOP;		sccmodem[i] |= MODEM_CTS;		sccstart(tp);	    }	}		/*	 * See if a modem transition has occured.  If we are waiting	 * for this signal, cause action to be take via	 * scc_start_tty.	 */	if ((SCC_XMIT(i)) &&	    (!(sccmodem[i] & MODEM_DSR_START)) &&	    (!(tp->t_state & TS_CARR_ON))) {	    scc_start_tty(tp);	}    }}/* * Note: When a break condition occurs, the SCC chip detects the condition, *       sets the BREAK bit and generates an ext/status interrupt. Upon *       termination of the break, the receive FIFO will contain a single  *       NULL character. This NULL character will cause a dma rint. The *       Framing Error bit will not be set for this character, but if odd *       parity has been selected, the parity error bit will be set.  */ sccbrkint(unit)     register int unit;{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register struct scc_reg *rsp;    register struct scc_saved_reg *ssp;    register u_short c;	    register int flg;        tp = &scc_tty[unit];    rsp = sc->sc_regs[unit];    ssp = &sc->sc_saved_regs[unit];    c = (unit<<8)| 0x0000;    /*     * We need to disable both the SCC rint and the IOASIC rdma int     * because we just want to read and discard the NULL character     * that will be deposited in the receive FIFO upon termination     * of the break.     */    if (scc_brk[unit]) {	ssp->wr1 &= ~SCC_WR1_RINT;   /* disable rint on special conditions */	SCC_WRITE(rsp, SCC_WR1, ssp->wr1);	IOC_CLR(IOC_SSR, scc_rdma_en[unit]);    /* disable rdma */		if ((tp->t_state & TS_ISOPEN) == 0) {   /* process break */	    wakeup((caddr_t)&tp->t_rawq);	    return;	}	flg = tp->t_iflag;	if (do_tpath) {	    tp->t_tpath |= TP_DOSAK;	    (*linesw[tp->t_line].l_rint)(c, tp);	    return;	}	if (flg & IGNBRK)	  return;	if (flg & BRKINT) {	    if ((tp->t_lflag_ext & PRAW) && 		(tp->t_line != TERMIODISC))	      c = 0;	    else {		ttyflush(tp, FREAD | FWRITE);		gsignal(tp->t_pgrp, SIGINT);		return;	    }	}	else {	    if (flg & PARMRK){		(*linesw[tp->t_line].l_rint)(0377,tp);		(*linesw[tp->t_line].l_rint)(0,tp);	    }	    c = 0;	}	if (flg & ISTRIP){	    c &= 0177;	}	else {	    c &= 0377;	    if ((c == 0377) && (tp->t_line == TERMIODISC) &&		(flg & PARMRK))	      (*linesw[tp->t_line].l_rint)(0377,tp);	}	(*linesw[tp->t_line].l_rint)(c, tp);    } else {	c = ((rsp->SCC_DATA)>>8)&0xff;	/* read NULL character */	IOC_SET(IOC_SSR, scc_rdma_en[unit]);  /* enable RDMA */	ssp->wr1 &= ~SCC_WR1_RINT;		/* clear rint bits */	ssp->wr1 |= SCC_WR1_RINT_SPC;		/* enable rint */	SCC_WRITE(rsp, SCC_WR1, ssp->wr1);    }}int  sccputc();int  sccgetc();sccputc(c)     register int c;{    if (consDev == GRAPHIC_DEV) {	if ( v_consputc ) {	    (*v_consputc) (c);	    if ( c == '\n' )		(*v_consputc)( '\r' );	    return;	}    }    scc_putc(3, c);    if ( c == '\n')	scc_putc(3, '\r');}/* * polled-mode DMA: need to do this because SCC can not be touched in * scc_putc. */scc_putc(unit, c)     int unit;     register int c;{    register struct scc_softc *sc = sccsc;    register int s;    register struct scc_reg *rsp;    char *ptr;    int intr_pending = 0, save_word;    u_int sir, save_SSR, save_xmt_ptr;    if (unit == 2 || unit == 3) {	/* set pointer to be the word before the end of the page */	ptr = sc->tbuf[unit] + SCC_PAGE_SIZE - SCC_WORD;		/* rpbfix : do we need to be at extreme ??? */	s = splextreme();	IOC_RD(IOC_SSR, save_SSR);	/* save copy of SSR */	IOC_WR(IOC_SSR, (save_SSR & ~(scc_xdma_en[unit]))); /* disable XMT DMA */	IOC_RD(IOC_SIR, sir);	if (sir & scc_xint[unit]) {	    intr_pending = 1;	    IOC_WR(IOC_SIR, ~(scc_xint[unit]));	} else {	    save_xmt_ptr = sc->ioc_regs[unit]->XDMA_REG;	    save_word = *(int *)ptr;	}	*(u_short *)ptr = ((u_short)c) << 8;	sc->ioc_regs[unit]->XDMA_REG = (u_long)(svtophy(ptr) << 3);	IOC_SET(IOC_SSR, scc_xdma_en[unit]);	IOC_RD(IOC_SIR, sir);	while ((sir & scc_xint[unit]) == 0) 	    IOC_RD(IOC_SIR, sir);		if (intr_pending == 0) {	    IOC_CLR(IOC_SSR, scc_xdma_en[unit]);	    IOC_WR(IOC_SIR, ~(scc_xint[unit]));	    sc->ioc_regs[unit]->XDMA_REG = save_xmt_ptr;	    *(long *)ptr = save_word;	    IOC_WR(IOC_SSR, save_SSR);	}	splx(s);    } else {	s = splhigh();	rsp = sc->sc_regs[unit];	while ((((rsp->SCC_CMD)>>8) & SCC_RR0_TBUF_EMPTY) == 0)	    ;	rsp->SCC_DATA = (c&0xff)<<8;        /* output char */  	while ((((rsp->SCC_CMD)>>8) & SCC_RR0_TBUF_EMPTY) == 0)	    ;	splx(s);    }}/* pgt - new sccgetc() */sccgetc(){    register u_char c;    register int line;        /*     * Line number we expect input from.      */    if (consDev == GRAPHIC_DEV)	line = 0x0;    else	line = 0x3;    c = scc_getc(line);    if (v_consgetc)	return ((*v_consgetc)(c & 0xff));    else	return (c & 0xff);}scc_getc(unit)     int unit;{    register struct scc_softc *sc = sccsc;    register u_char c, status;    register int timo;    register struct scc_reg *rsp;    rsp = sc->sc_regs[unit];    SCC_WRITE(rsp, SCC_WR9, 0x00); /* disable MIE ? */    if (unit == 2 || unit == 3)	IOC_CLR(IOC_SSR, scc_rdma_en[unit]);    /* disable rdma ? */    for(timo=1000000; timo > 0; --timo) {	if (((rsp->SCC_CMD)>>8) & SCC_RR0_RCHAR_AVAIL) {	    SCC_READ(rsp, SCC_RR1, status);	    c = ((rsp->SCC_DATA)>>8)&0xff;      /* read data */	    DELAY(50000);	    if (status & (SCC_RR1_PE | SCC_RR1_DO | SCC_RR1_FE)) 	        continue;	    break;	}    }    SCC_WRITE(rsp, SCC_WR9, SCC_WR9_MIE); /* enable MIE ? */    if (unit == 2 || unit == 3)	IOC_SET(IOC_SSR, scc_rdma_en[unit]);    /* enable rdma ? */    if (timo == 0)	return(-1);    else	return(c & 0xff);}scc_mouse_init(){    register struct scc_softc *sc = sccsc;    register struct scc_reg *rsp;    register struct scc_saved_reg *ssp;    register int unit = 1;    rsp = sc->sc_regs[unit];    ssp = &sc->sc_saved_regs[unit];    scc_init(unit);    /*      * enable functions ?     */    ssp->wr14 |= SCC_WR14_BRGEN_EN;    SCC_WRITE(rsp, SCC_WR14, ssp->wr14);	     /*	 WR14 BRG enable */    ssp->wr3 |= SCC_WR3_RXEN;    SCC_WRITE(rsp, SCC_WR3, ssp->wr3);	      /*  WR3 Rx enable */    ssp->wr5 |= SCC_WR5_TXEN;    SCC_WRITE(rsp, SCC_WR5, ssp->wr5);        /*  WR5 Tx enable */}scc_mouse_putc(c)int c;{    scc_putc(1, c);}scc_mouse_getc(){    return (scc_getc(1));}scc_kbd_init(){    register struct scc_softc *sc = sccsc;    register struct scc_reg *rsp;    register struct scc_saved_reg *ssp;    register int unit = 0;    rsp = sc->sc_regs[unit];    ssp = &sc->sc_saved_regs[unit];    scc_init(unit);    /*      * enable functions ?     */    ssp->wr14 |= SCC_WR14_BRGEN_EN;    SCC_WRITE(rsp, SCC_WR14, ssp->wr14);	     /*	 WR14 BRG enable */    ssp->wr3 |= SCC_WR3_RXEN;    SCC_WRITE(rsp, SCC_WR3, ssp->wr3);	      /*  WR3 Rx enable */    ssp->wr5 |= SCC_WR5_TXEN;    SCC_WRITE(rsp, SCC_WR5, ssp->wr5);        /*  WR5 Tx enable */}scc_kbd_putc(c)int c;{    scc_putc(0, c);}scc_kbd_getc(){    return (scc_getc(0));}/* * Modem Control Routines *//* * * Function: * *	scc_cd_drop * * Functional description: * * 	Determine if carrier has dropped.  If so call scc_tty_drop to terminate * 	the connection. * * Arguments: * *	register struct tty *tp  -  terminal pointer ( for terminal attributes ) * * Return value: * *	none * */scc_cd_drop(tp)     register struct tty *tp;{    register struct scc_softc *sc = sccsc;    register int unit;        unit = minor(tp->t_dev);    if ((tp->t_state & TS_CARR_ON) && (!(SCC_DCD(unit)))) {	scc_tty_drop(tp);	return;    }    sccmodem[unit] |= MODEM_CD;}/* * * Function: * *	scc_dsr_check * * Functional description: * *	DSR must be asserted for a connection to be established.  Here we  *	either start or terminate a connection on the basis of DSR. * * Arguments: * *	register struct tty *tp  -  terminal pointer (for terminal attributes) * * Return value: * *	none * */scc_dsr_check(tp)     register struct tty *tp;{    register struct scc_softc *sc = sccsc;    register int unit;        unit = minor(tp->t_dev);    if (sccmodem[unit] & MODEM_DSR_START) {	sccmodem[unit] &= ~MODEM_DSR_START;	/*	 * since dc7085 chip on PMAX only provides DSR then assume that CD	 * has come up after 1 sec and start tty.  If CD has not	 * come up the modem should deassert DSR thus closing the line	 *	 * On 3max, we look for DSR|CTS|CD before establishing a	 * connection.	 */	if (SCC_XMIT(unit)) {	    scc_start_tty(tp);	}	return;    }    if ((tp->t_state&TS_CARR_ON)==0)	scc_tty_drop(tp);}/* * * Function: * *	scc_cd_down * * Functional description: * *	Determine whether or not carrier has been down

⌨️ 快捷键说明

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