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

📄 scc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
    IOC_WR(IOC_SIR, ~scc_xerror[line]);}/* * Used to pass mouse (or tablet) reports to the graphics * device driver interrupt service routine. * Entire report passed instead of byte at a time. */struct	mouse_report	current_rep;u_short pointer_id;#define MOUSE_ID	0x2scc_mkbd_rint(unit)     register int unit;{    register struct scc_softc *sc = sccsc;    register u_short ch;	/* ch is 16 bits long */    register u_short c;    struct mouse_report *new_rep;    u_short data;    register struct scc_reg *rsp;    register char ip;        /*     * If console is a graphics device,     * pass keyboard input characters to     * its device driver's receive interrupt routine.     * Save up complete mouse report and pass it.     */    if ((unit <= 1) && vs_gdkint) {	new_rep = &current_rep;			/* mouse report pointer */	rsp = sc->sc_regs[unit];                      /* line = mouse or keybd */	SCC_READ(rsp, SCC_RR3, ip);                   /* read IP bits from RR3A */	while (ip & SCC_RR3_A_RIP) {                /* channel A receiver */	    c = (rsp->SCC_DATA)>>8;			/* read char */	    ch = (unit<<8)| c;                  /* encode line in ch */	    if(unit == 0) {		/* keyboard char */		(*vs_gdkint)(ch);	    } else {			/* mouse or tablet report */		if (pointer_id == MOUSE_ID) { /* mouse report */		    data = ch & 0xff;	/* get report byte */		    ++new_rep->bytcnt;	/* inc report byte count */		    if (data & START_FRAME) { /* 1st byte of report? */			new_rep->state = data;			if (new_rep->bytcnt > 1)			    new_rep->bytcnt = 1;  /* start new frame */		    }		    else if (new_rep->bytcnt == 2) {	/* 2nd byte */			new_rep->dx = data;		    }		    else if (new_rep->bytcnt == 3) {	/* 3rd byte */			new_rep->dy = data;			new_rep->bytcnt = 0;			(*vs_gdkint)(0400); /* 400 says line 1 */		    }		} else { /* tablet report */		    data = ch;	/* get report byte */		    ++new_rep->bytcnt;	/* inc report byte count */		    		    if (data & START_FRAME) { /* 1st byte of report? */			new_rep->state = data;			if (new_rep->bytcnt > 1)			    new_rep->bytcnt = 1;  /* start new frame */		    }		    else if (new_rep->bytcnt == 2)	/* 2nd byte */			new_rep->dx = data & 0x3f;		    		    else if (new_rep->bytcnt == 3)	/* 3rd byte */			new_rep->dx |= (data & 0x3f) << 6;		    		    else if (new_rep->bytcnt == 4)	/* 4th byte */			new_rep->dy = data & 0x3f;		    		    else if (new_rep->bytcnt == 5){	/* 5th byte */			new_rep->dy |= (data & 0x3f) << 6;			new_rep->bytcnt = 0;			(*vs_gdkint)(0400); /* 400 says line 1 */		    }		}	    }	    SCC_READ(rsp, SCC_RR3, ip);         /* read IP bits again */	} /* while */    } /* if */ }scc_spec_rint(line)     register int line;{    scc_dma_rint(line);}scc_dma_rint(unit)     register int unit;{    register struct scc_softc *sc = sccsc;    register struct tty *tp = &scc_tty[unit];    register u_short c;	    register int flg;    register int status, vector, status0;    register int num;    register char *endptr;    register char *ptr;    register struct scc_reg *rsp;    register char ip;    int overrun = 0;    int counter = 0;    register int c_mask;    IOC_CLR(IOC_SSR, scc_rdma_en[unit]);    /* disable rdma */    IOC_WR(IOC_SIR, ~(scc_rint[unit]));       /* clear rdma int */    /* compute the offset from the beginning of the page */    /* read rdma ptr */    endptr = (char *)(((sc->ioc_regs[unit]->RDMA_REG) >> 3) & 0xfff);     /* add the base of the receive buffer to the endptr */    num = sc->rflag[unit];     /* save flag */    /* pgt - check for boundary crossing */    if (endptr == 0) 	endptr += (long)(sc->rbuf[unit][num]) + SCC_PAGE_SIZE ;    else         endptr += (long)(sc->rbuf[unit][num]);    endptr -= SCC_WORD;        /* move to previous word */    sc->rflag[unit] ^= 1;      /* toggle buffer flag */    /*     * set rdma ptr to other buffer      */    sc->ioc_regs[unit]->RDMA_REG = (u_long)(svtophy(sc->rbuf[unit][sc->rflag[unit]] 					    + SCC_HALF_PAGE - SCC_WORD) << 3);        /* unit = comm1 or comm2 */    rsp = sc->sc_regs[scc_other[unit]];   /* channel A */    SCC_READ(rsp, SCC_RR3, ip);		/* read IP from RR3A */    if (ip & SCC_RR3_B_RIP) {             /* channel B receiver */	rsp = sc->sc_regs[unit];   /* channel B */	SCC_READ(rsp, SCC_RR1, status);	/* read status */    	rsp->SCC_CMD = (SCC_WR0_ERROR_RESET)<<8;    } else {	status = 0;    }        IOC_SET(IOC_SSR, scc_rdma_en[unit]);     /* enable rdma */    if ((tp->t_state & TS_ISOPEN) == 0) {	wakeup((caddr_t)&tp->t_rawq);	return;    }    flg = tp->t_iflag;        ptr = sc->rbuf[unit][num] + SCC_HALF_PAGE - SCC_WORD;    /* need to do following because SCC sets unused bits to ones */    switch(tp->t_cflag&CSIZE) {      case CS5:	c_mask = 0x1f;	break;      case CS6:	c_mask = 0x3f;	break;      case CS7:	c_mask = 0x7f;	break;      case CS8:	c_mask = 0xff;    }    while (ptr < endptr) {	c = ((*(u_short *)ptr)>>8)&c_mask;	ptr += SCC_WORD;		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);    }    c = ((*(u_short *)ptr)>>8)&c_mask;    /*     *		This code handles the following termio input flags.  Also     *		listed is what the default should be for propper Ultrix     *		backward compatibility.     *     *		IGNBRK		FALSE     *		BRKINT		TRUE     *		IGNPAR		TRUE     *		PARMRK		FALSE     *		INPCK		TRUE     *		ISTRIP		TRUE     */    if (status) {	/* SCC_FE is interpreted as a break */	if (status & SCC_RR1_FE) {  	    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;		}	    }	    /*	     * TERMIO: If neither IGNBRK or BRKINT is set, a	     * break condition is read as a single '\0',	     * or if PARMRK is set as '\377', '\0' , '\0'.	     */	    else {		if (flg & PARMRK){		    (*linesw[tp->t_line].l_rint)(0377,tp);		    (*linesw[tp->t_line].l_rint)(0,tp);		}		c = 0;	    }	}	/* Parity Error */	else 	    if (status & SCC_RR1_PE){	    /*	     * If input parity checking is not enabled, clear out	     * parity error in this character.	     */	    if ((flg & INPCK) == 0)		;	     /* don't do anything */	    else {		if (flg & IGNPAR)		    return;		/* If PARMRK is set, return a character with		 * framing or parity errors as a 3 character		 * sequence (0377,0,c).		 */		if (flg & PARMRK){		    (*linesw[tp->t_line].l_rint)(0377,tp);		    (*linesw[tp->t_line].l_rint)(0,tp);		}		/*		 * TERMIO: If neither PARMRK or IGNPAR is set, a		 * parity error is read as a single '\0'.		 */		else		    c = 0;	    }	}		/* SVID does not say what to do with overrun errors */	if (status & SCC_RR1_DO) {	    if(overrun == 0) {		printf("scc%d: input silo overflow\n", 0);		overrun = 1;	    }	    sc->sc_softcnt[unit]++;	}    }    if (flg & ISTRIP){	c &= 0177;    } else {	c &= 0377;	/* 	 * If ISTRIP is not set a valid character of 377	 * is read as 0377,0377 to avoid ambiguity with	 * the PARMARK sequence.	 */	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);}/*ARGSUSED*/sccioctl(dev, cmd, data, flag)     dev_t dev;     register int cmd;     caddr_t data;     int flag;{    register struct scc_softc *sc = sccsc;    register int unit;    register struct tty *tp;    register int s;    struct uba_device *ui;    struct devget *devget;    int error;    register struct scc_reg *rsp;    register int status;    register int timo;    unit = minor(dev);    if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))	unit |= 3;	/* diag console on SLU line 3 */        /*     * If there is a graphics device and the ioctl call     * is for it, pass the call to the graphics driver.     */    if (vs_gdioctl && (unit <= 1)) {	return((*vs_gdioctl)(dev, cmd, data, flag));    }    tp = &scc_tty[unit];    error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);    if (error >= 0)	return (error);    error = ttioctl(tp, cmd, data, flag);    if (error >= 0) {	/*	 * If the call is to set terminal attributes which are	 * represented in the device's line parameter register then	 * call the param routine to update the device registers.	 */	switch(cmd) {	  case TCSANOW:			/* POSIX termios */	  case TCSADRAIN:		/* POSIX termios */	  case TCSAFLUSH:		/* POSIX termios */	  case TCSETA:			/* SVID termio */	  case TCSETAW:			/* SVID termio */	  case TCSETAF:			/* SVID termio */	  case TIOCSETP:		/* Berkeley sgttyb */	  case TIOCSETN:		/* Berkeley sgttyb */	  case TIOCLBIS:		/* Berkeley lmode */	  case TIOCLBIC:		/* Berkeley lmode */	  case TIOCLSET:		/* Berkeley lmode */	  case TIOCLGET:		/* Berkeley lmode */	    sccparam(unit);	    break;	}	return (error);    }    switch (cmd) {	      case TIOCSBRK:	s = spltty();	rsp = sc->sc_regs[unit];	SCC_READ(rsp, SCC_RR1, status);	/* read status */	for(timo=10000; timo > 0; --timo) {	    if (status & SCC_RR1_ALL_SENT) 		break;		    else {		SCC_READ(rsp, SCC_RR1, status);	    }	}	SCC_SET_BRK(unit);	splx(s);	break;	      case TIOCCBRK:	s = spltty();	SCC_CLR_BRK(unit);	splx(s);	break;      case TIOCSDTR:	(void) sccmctl(dev, DC_DTR | DC_RTS, DMBIS);	break;	      case TIOCCDTR:	(void) sccmctl(dev, DC_DTR | DC_RTS, DMBIC);	break;	      case TIOCMSET:	(void) sccmctl(dev, dmtoscc(*(int *)data), DMSET);	break;	      case TIOCMBIS:	(void) sccmctl(dev, dmtoscc(*(int *)data), DMBIS);	break;	      case TIOCMBIC:	(void) sccmctl(dev, dmtoscc(*(int *)data), DMBIC);	break;	      case TIOCMGET:	*(int *)data = scctodm(sccmctl(dev, 0, DMGET));	break;	      case TIOCNMODEM:  /* ignore modem status */	/*	 * By setting the software representation of modem signals	 * to "on" we fake the system into thinking that this is an	 * established modem connection.	 */	s = spltty();	sccsoftCAR |= (1<<(unit&LINEMASK));	if (*(int *)data) /* make mode permanent */	    sccdefaultCAR |= (1<<(unit&LINEMASK));	tp->t_state |= TS_CARR_ON;	tp->t_cflag |= CLOCAL;		/* Map to termio */	SCC_MODEM_OFF(unit);	splx(s);	break;	      case TIOCMODEM:  	s = spltty();	SCC_MODEM_ON(unit);	sccsoftCAR &= ~(1<<(unit&LINEMASK));	if (*(int *)data) /* make mode permanent */	    sccdefaultCAR &= ~(1<<(unit&LINEMASK));	/*	 * See if signals necessary for modem connection are present	 */	if (SCC_XMIT(unit)) {	    tp->t_state &= ~(TS_ONDELAY);	    tp->t_state |= TS_CARR_ON;	    sccspeedi(unit);  /* check speed indicate */	    sccmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;	} else {	    tp->t_state &= ~(TS_CARR_ON);	    sccmodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR);	}	tp->t_cflag &= ~CLOCAL;		/* Map to termio */	splx(s);	break; 	      case TIOCWONLINE: /* look at modem status - sleep if no carrier */	s = spltty();	/*	 * See if signals necessary for modem connection are present	 */	if (SCC_XMIT(unit)) {	    tp->t_state |= TS_CARR_ON;	    sccspeedi(unit);	    tp->t_state &= ~(TS_ONDELAY);	    sccmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR;	} else {	    while ((tp->t_state & TS_CARR_ON) == 0)		sleep((caddr_t)&tp->t_rawq, TTIPRI);	}	splx(s);	break;	      case DEVIOCGET:				/* device status */	devget = (struct devget *)data;	bzero(devget,sizeof(struct devget));	if (tp->t_cflag & CLOCAL) {	    sc->sc_category_flags[unit&LINEMASK] |= DEV_MODEM;	    sc->sc_category_flags[unit&LINEMASK] &= ~DEV_MODEM_ON;	} else	    sc->sc_category_flags[unit&LINEMASK] |= (DEV_MODEM|DEV_MODEM_ON);	devget->category = DEV_TERMINAL;	/* terminal cat.*/	devget->bus = DEV_NB;			/* NO bus	*/	bcopy(DEV_VS_SLU,devget->interface,	      strlen(DEV_VS_SLU));		/* interface	*/	bcopy(DEV_UNKNOWN,devget->device,	      strlen(DEV_UNKNOWN));		/* terminal	*/	devget->adpt_num = 0;			/* NO adapter	*/	devget->nexus_num = 0;			/* fake nexus 0 */	devget->bus_num = 0;			/* NO bus	*/	devget->ctlr_num = 0;			/* cntlr number */	devget->slave_num = unit&LINEMASK;	/* line number	*/	bcopy("scc", devget->dev_name, 3);	/* Ultrix "scc"	*/	devget->unit_num = unit&LINEMASK;	/* scc line?	*/	devget->soft_count =	    sc->sc_softcnt[unit&LINEMASK];	/* soft err cnt */

⌨️ 快捷键说明

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