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 + -
显示快捷键?