ttyiin.c,v

来自「TCP-IP红宝书源代码」· C,V 代码 · 共 490 行

C,V
490
字号
head	1.2;
access;
symbols;
locks
	dls:1.2; strict;
comment	@ * @;


1.2
date	97.09.21.19.30.23;	author dls;	state Dist;
branches;
next	1.1;

1.1
date	94.05.08.06.01.42;	author dls;	state Old;
branches;
next	;


desc
@@


1.2
log
@pre-3e code
@
text
@/* ttyiin.c - ttyiin */

#include <conf.h>
#include <kernel.h>
#include <tty.h>

static	iputchar(), delchar(), delword(), reprint();

/*------------------------------------------------------------------------
 * ttyiin - handle interrupt-level input for a tty
 *------------------------------------------------------------------------
 */
int
ttyiin(pdev, ch)
struct devsw	*pdev;
unsigned char	ch;
{
	struct tty	*ptty = (struct tty *)pdev->dvioblk;
	struct tchars	*ptc;
	static unsigned char	lastc;

	if (ch == '\n' && lastc == '\r')
		return;
	lastc = ch;
	if (ch == '\r')
		ch = '\n';
	if (ptty->tty_iflags & TIF_RAW) {
		iputchar(ptty, ch);
		return;
	}
	ptc = &ptty->tty_tchars;
	if (ch == ptc->tc_erase) {
		delchar(ptty);
		return;
	} else if (ch == ptc->tc_werase) {
		delword(ptty);
		return;
	} else if (ch == ptc->tc_reprint) {
		reprint(ptty);
		return;
	} else if (ch == ptc->tc_intr) {
		send(ptty->tty_cpid, INTRMSG);
		return;
	} else if (ch == ptc->tc_eof) {
		ptty->tty_iflags |= TIF_EOF;
	}
	iputchar(ptty, ch);
	if ((ptty->tty_iflags & (TIF_CBREAK|TIF_RAW)) ||
	    ch == ptty->tty_tchars.tc_eol ||
	    ch == ptty->tty_tchars.tc_eof)
		if (scount(ptty->tty_isema) <= 0)
			signal(ptty->tty_isema);
}

/*------------------------------------------------------------------------
 * iputchar - put a character on a tty's input queue
 *------------------------------------------------------------------------
 */
static int
iputchar(ptty, ch)
struct tty	*ptty;
unsigned char	ch;
{
	struct devsw	*pdev = ptty->tty_pdev;
	int		pos;

	if (ptty->tty_icount >= IBLEN) {
		ttyputc(pdev, '\007');
		return;
	}
	pos = ptty->tty_istart + ptty->tty_icount;
	if (pos >= IBLEN)
		pos -= IBLEN;
	ptty->tty_in[pos] = ch;
	ptty->tty_icount++;
	if (ptty->tty_iflags & TIF_NOECHO)
		return;
	echo(ptty, ch);
}

/*------------------------------------------------------------------------
 * echo - echo an input character on a tty's output
 *------------------------------------------------------------------------
 */
static int
echo(ptty, ch)
struct tty	*ptty;
unsigned char	ch;
{
	struct devsw	*pdev = ptty->tty_pdev;

	if ((ptty->tty_iflags & TIF_RAW) == 0) {
		if (ch > 127) {
			ttyputc(pdev, 'M');
			ttyputc(pdev, '-');
			ch -= 128;
		}
		if (ch < ' ' &&
		  !(ch == '\n' || ch == '\b' || ch == '\f' ||
		    ch == '\r' || ch == '\t')) {
			ttyputc(pdev, '^');
			ch += 64;	/* make it printable */
		} else if (ch == 127) {
			ttyputc(pdev, '^');
			ch = '?';
		}
	}
	ttyputc(pdev, ch);
}

#define RUBOUT(pdev) {		\
	ttyputc(pdev, '\b');	\
	ttyputc(pdev, ' ');	\
	ttyputc(pdev, '\b');	\
}

/*------------------------------------------------------------------------
 * delchar - delete a character from the input queue
 *------------------------------------------------------------------------
 */
static int
delchar(ptty)
struct tty	*ptty;
{
	struct devsw	*pdev = ptty->tty_pdev;
	unsigned int	ch;
	int		pos;

	if (ptty->tty_icount == 0)
		return;
	pos = ptty->tty_istart + ptty->tty_icount - 1;
	if (pos >= IBLEN)
		pos -= IBLEN;
	if (ptty->tty_in[pos] == '\n')
		return;
	ptty->tty_icount--;
	if (ptty->tty_iflags & TIF_NOECHO)
		return;
	/* update display, including multi-character sequences */
	ch = ptty->tty_in[pos];
	if (ch > 127) {
		RUBOUT(pdev);	/* also remove "M-" */
		RUBOUT(pdev);
	}
	if (ch == 127 || ch < ' ')
		RUBOUT(pdev);	/* also remove "^" */
	RUBOUT(pdev);
}

#define	KIND(ch) ( ((ch) == ' ' || (ch == '\t')) ? 0 : (((ch) == '/') + 1))

/*------------------------------------------------------------------------
 * delword - delete a word from the input buffer
 *------------------------------------------------------------------------
 */
static int
delword(ptty)
struct tty	*ptty;
{
	unsigned char	ch;
	int		firstkind, kind, pos;

	if (ptty->tty_icount == 0)
		return;
	pos = ptty->tty_istart + ptty->tty_icount - 1;
	if (pos >= IBLEN)
		pos -= IBLEN;
	ch = ptty->tty_in[pos];
	kind = firstkind = KIND(ch);
	while (ptty->tty_icount && kind == firstkind) {
		delchar(ptty);
		if (pos-- == 0)
			pos = IBLEN - 1;
		ch = ptty->tty_in[pos];
		if (ch == '\n')
			break;
		kind = KIND(ch);
	}
}

/*------------------------------------------------------------------------
 * reprint - reprint a line from the input buffer
 *------------------------------------------------------------------------
 */
static int
reprint(ptty)
struct tty	*ptty;
{
	int	i, pos, count;

	pos = ptty->tty_istart + ptty->tty_icount;
	if (pos > IBLEN)
		pos -= IBLEN;
	count = 0;
	for (i=ptty->tty_icount; i > 0; --i) {
		if (ptty->tty_in[pos] == '\n')
			break;
		if (pos-- == 0)
			pos = IBLEN - 1;
		count++;
	}
	if (ptty->tty_in[pos] == '\n')	/* if newline, one too far */
		if (++pos >= IBLEN)
			pos -= IBLEN;
	echo(ptty, ptty->tty_tchars.tc_reprint);
	echo(ptty, '\n');
	for (i=count; i > 0; --i) {
		echo(ptty, ptty->tty_in[pos]);
		if (++pos >= IBLEN)
			pos = 0;
	}
}
@


1.1
log
@Initial revision
@
text
@d1 1
a1 1
/* ttyiin.c ttyiin, ttybreak, erase1, eputc, echoch */
a5 3
#include <io.h>
#include <slu.h>
#include <zsreg.h>
d7 1
d10 36
a45 135
 *  ttyiin  --  lower-half tty device driver for input interrupts
 *------------------------------------------------------------------------
 */
INTPROC	ttyiin(iptr)
	register struct	tty	*iptr;	/* pointer to tty block		*/
{
	STATWORD ps;    
    
	register struct	zscc_device *zptr;
	register int	ch;
	int	err;
	int	cerr;
	int	ct;

	zptr = iptr->ioaddr;
        ch = zptr->zscc_data;

	/* get the contents of RR1 */
	zptr->zscc_control = 1;
	DELAY(2);
	err = zptr->zscc_control;

	/* check for Parity, Overrun, and Framing errors */
	err &= (ZSRR1_PE | ZSRR1_DO | ZSRR1_FE);

	cerr = 0;
	if (err != 0) {
#ifdef PRINTERRORS	    
	    kprintf("recv error, ch: 0x%x ", (unsigned int) ch);
	    if (err & ZSRR1_PE)
		kprintf(", Parity Error");
	    if (err & ZSRR1_DO)
		kprintf(", Data Overrun");
	    if (err & ZSRR1_PE)
		kprintf(", Framing Error");
	    kprintf("\n");
#endif	    
	    cerr = IOCHERR;
	    zptr->zscc_control = ZSWR0_RESET_ERRORS;	/* reset the error */
	}
#ifdef DEBUG	
	kprintf("\n<%c,%x,%x,%x>	",
		ch,(unsigned int) ch, (unsigned int) err,
		(unsigned int) cerr);
#endif	
	
	if (iptr->imode == IMRAW) {
		if (iptr->icnt >= IBUFLEN){
			return;
		}
		iptr->ibuff[iptr->ihead++] = ch | cerr;
		++iptr->icnt;
		if (iptr->ihead	>= IBUFLEN)	/* wrap buffer pointer	*/
			iptr->ihead = 0;
	        signal(iptr->isem);
	} else {				/* cbreak | cooked mode	*/
		if ( ch	== RETURN && iptr->icrlf )
			ch = NEWLINE;
		if (iptr->iintr && ch == iptr->iintrc) {
			send(iptr->iintpid, INTRMSG);
			eputc(ch, iptr, zptr);
			return;
		}
		if (iptr->oflow) {
			if (ch == iptr->ostart)	{
				iptr->oheld = FALSE;
				ttyostart(iptr);
				return;
			}
			if (ch == iptr->ostop) {
				iptr->oheld = TRUE;
				return;
			}
		}
		iptr->oheld = FALSE;
		if (iptr->imode	== IMCBREAK) {		/* cbreak mode	*/
			if (iptr->icnt >= IBUFLEN) {
				eputc(iptr->ifullc,iptr,zptr);
				return;
			}
			iptr->ibuff[iptr->ihead++] = ch	| cerr;
			if (iptr->ihead	>= IBUFLEN)
				iptr->ihead = 0;
			if (iptr->iecho)
				echoch(ch,iptr,zptr);
			if (iptr->icnt < IBUFLEN) {
				++iptr->icnt;
				signal(iptr->isem);
			}
		} else {				/* cooked mode	*/
			if (ch == iptr->ikillc && iptr->ikill) {
				iptr->ihead -= iptr->icursor;
				if (iptr->ihead	< 0)
					iptr->ihead += IBUFLEN;
				iptr->icursor =	0;
				eputc(RETURN,iptr,zptr);
				eputc(NEWLINE,iptr,zptr);
				return;
			}
			if (ch == iptr->ierasec	&& iptr->ierase) {
				if (iptr->icursor > 0) {
					iptr->icursor--;
					erase1(iptr,zptr);
				}
				return;
			}
			if (ch == NEWLINE || ch == RETURN ||
				(iptr->ieof && ch == iptr->ieofc)) {
				if (iptr->iecho) {
					echoch(ch,iptr,zptr);
					if (ch == iptr->ieofc)
						echoch(NEWLINE,iptr,zptr);
				}
				iptr->ibuff[iptr->ihead++] = ch | cerr;
				if (iptr->ihead	>= IBUFLEN)
					iptr->ihead = 0;
				ct = iptr->icursor+1; /* +1 for \n or \r*/
				iptr->icursor =	0;
				iptr->icnt += ct;
				signaln(iptr->isem,ct);
				return;
			}
			ct = iptr->icnt;
			ct = ct	< 0 ? 0	: ct;
			if ((ct	+ iptr->icursor) >= IBUFLEN-1) {
				eputc(iptr->ifullc,iptr,zptr);
				return;
			}
			if (iptr->iecho)
				echoch(ch,iptr,zptr);
			iptr->icursor++;
			iptr->ibuff[iptr->ihead++] = ch	| cerr;
			if (iptr->ihead	>= IBUFLEN)
				iptr->ihead = 0;
		}
d47 6
d56 1
a56 1
 *  erase1  --  erase one character honoring erasing backspace
d59 20
a78 33
LOCAL erase1(iptr,zptr)
	struct	tty   *iptr;
	struct	zscc_device	*zptr;
{
	char	ch;

	if (--(iptr->ihead) < 0)
		iptr->ihead += IBUFLEN;
	ch = iptr->ibuff[iptr->ihead];
	if (iptr->iecho) {
		if (ch < BLANK || ch == 0177) {
			if (iptr->evis)	{
				eputc(BACKSP,iptr,zptr);
				if (iptr->ieback) {
					eputc(BLANK,iptr,zptr);
					eputc(BACKSP,iptr,zptr);
				}
			}
			eputc(BACKSP,iptr,zptr);
			if (iptr->ieback) {
				eputc(BLANK,iptr,zptr);
				eputc(BACKSP,iptr,zptr);
			}
		} else {
			eputc(BACKSP,iptr,zptr);
			if (iptr->ieback) {
				eputc(BLANK,iptr,zptr);
				eputc(BACKSP,iptr,zptr);
			}
		}
	} 
        else
            ttyostart(iptr);
d81 10
d92 18
d111 5
d118 1
a118 1
 *  echoch  --  echo a character with visual and ocrlf options
d121 3
a123 4
LOCAL echoch(ch, iptr, zptr)
	char	ch;		/* character to	echo			*/
	struct	tty   *iptr;	/* pointer to I/O block for this devptr	*/
	struct	zscc_device	*zptr;	/* zscc_device address for this devptr		*/
d125 19
a143 8
	if ((ch==NEWLINE||ch==RETURN)&&iptr->ecrlf) {
		eputc(RETURN,iptr,zptr);
		eputc(NEWLINE,iptr,zptr);
	} else if ((ch<BLANK||ch==0177) && iptr->evis) {
		eputc(UPARROW,iptr,zptr);
		eputc(ch+0100,iptr,zptr);	/* make it printable	*/
	} else {
		eputc(ch,iptr,zptr);
d145 3
d150 2
d153 1
a153 1
 *  eputc - put one character in the echo queue
d156 3
a158 4
LOCAL eputc(ch,iptr,zptr)
	char	ch;
	struct	tty   *iptr;
	struct	zscc_device *zptr;
d160 19
a178 4
	iptr->ebuff[iptr->ehead++] = ch;
	if (iptr->ehead	>= EBUFLEN)
		iptr->ehead = 0;
	ttyostart(iptr);
a180 1

d182 1
a182 1
 *  ttybreak -- handle a break received on the serial line
d185 3
a187 1
ttybreak()
d189 23
a211 7
    STATWORD ps;
    
    disable(ps);
    kprintf("\n\nSerial line BREAK detected.\n");
    ret_mon();
    restore(ps);
    return;
@

⌨️ 快捷键说明

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