📄 tty.n.c
字号:
botbuf = &tty->inbuf.buf[0]; /* If no characters in buffer return */ if(tty->inbuf.count <= 0){ tty->inbuf.count = 0; return 0; } cnt = 0; /* Rubout characters untill start of buffer or count */ while (count-- && (tty->inbuf.count-- > 0)){ /* Decrement pointer to last character */ if((--(tty->inbuf.inptr)) < botbuf) tty->inbuf.inptr = &tty->inbuf.buf[TTYBUFSIZE]; /* Echos backspace space backspace */ if(tty->sgtty.sg_flags & ECHO){ /* Send out bs,sp,bs (note no check if worked) nauty */ tputout(tty->dev,"\b \b",3); } cnt++; } return cnt;}/* * ttyout Output a character from tty buffer to device * All output conversions done here. * This is either called by a device when requesting output * interupt mode, or by the TTY handler for output * in polled mode */ttyout(dev)short dev;{ int cnt, nchars; struct ttystruct *tty; char ch; tty = &ttys[dev]; /* Gets address of tty entry for device */ /* Checks if waiting for an extended character to be output * eg CRNL, tabs etc. if so return waking up process */ if(tty->tx_ewait){ wakeup((caddr_t)&tty->outbuf); return 0; } /* Checks if no more characters in buffer or Xoff is in progress * if so sets tx_rdy flag to indicate acias requirement for tx char */ if(tty->outxoff || !tgetbuf(&tty->outbuf,&ch,1)){ tty->tx_rdy = RDY; return 0; } tty->tx_rdy = NOTRDY; /* Check If in raw mode */ if(tty->sgtty.sg_flags & RAW){ /* Prints the character to device */ writechar(dev, ch); tty->col++; } /* If not raw do any output conversions */ else{ switch (ch){ case TAB: /* skip to next col modulo 8 */ nchars = ((tty->col+TABSIZE) & TABMASK) - tty->col; tty->col += nchars; /* If Xtabs print spaces */ if(tty->sgtty.sg_flags & XTABS){ /* Output number of tab spaces */ for (cnt = nchars; cnt; cnt--){ /* Wait until device ready and * print a space */ writechar(dev, ' '); } } /* Else output tab character */ else writechar(dev, ch); break; case BS: /* Back space */ writechar(dev, ch); if(tty->col-- < 0) tty->col = 0; /* back one space */ break; case NL: /* implement CRMOD type of conversion */ if(tty->sgtty.sg_flags&CRMOD){ writechar(dev, CR); crdelay(tty); /* Do CR delay */ tty->col = 0; /* Polled output of char wait until device ready */ writechar(dev, NL); nldelay(tty); /* Do NL delay */ tty->line++; } else{ writechar(dev, NL); tty->line++; nldelay(tty); /* Do NL delay */ } break; case CR: /* Do CR */ writechar(dev, CR); tty->col = 0; crdelay(tty); /* Do CR delay */ break; default: /* Prints the character to device */ writechar(dev, ch); tty->col++; break; } } /* Check if buffer is valid if so wake up any processes waiting */ if(tty->outbuf.inrdy == RDY) wakeup((caddr_t)&tty->outbuf); return 1;}/* * Writchar Will wait until a character is ready * passing through ttywait(), to indicate * that the tty handler is dossing around again. * and then write the character. */charwritechar(dev,ch)short dev;char ch;{ short intlevel; intlevel = SPLTTY(); /* Wait until device is ready note no need if interupt */ while(!((*ttydevsw[dev].status)(ttydevsw[dev].m_m_dev) & WRDY)) ttywait(dev,WWAITC); /* Write character */ (*ttydevsw[dev].wchar)(ttydevsw[dev].m_m_dev, ch); splx(intlevel); return;}/* * Crdelay CR delay algorithm */crdelay(tty)struct ttystruct *tty;{ int delay; /* Checks if there is CR delay */ if(delay = (tty->sgtty.sg_flags & CRDELAY)){ switch(delay){ case CR1: delaym(tty->dev,80); /* 80 mS delay */ break; case CR2: delaym(tty->dev,160); /* 160 mS delay */ break; } } return;}/* * nldelay NL delay algorithm */nldelay(tty)struct ttystruct *tty;{ int delay; /* Checks if there is NL delay */ if(delay = (tty->sgtty.sg_flags & NLDELAY)){ switch(delay){ case NL1: delaym(tty->dev,10); /* 5 mS delay */ break; case NL2: delaym(tty->dev,100); /* 160 mS delay */ break; } } return;}/* * Simple delay very, very, very inacurate. */delaym(dev,count)short dev;int count;{ int c; short intlevel; while(count--){ /* 1ms delay very aprox! , dependent on ttywait !*/ for(c=0; c<200; c++) ttywait(dev,DWAIT); }}/* * Kernel routines need putchar + getchar to console. * Polled access is used, as errors don't want to be interupt * bound incase they mess up. */chargetchar(){ return readchar(CONSOLE);}charputchar(ch)char ch;{ int c; /* Perform simple output conversions */ switch(ch){ case NL: /* implement CRMOD type of conversion */ if(ttys[CONSOLE].sgtty.sg_flags&CRMOD){ writechar(CONSOLE,CR); crdelay(&ttys[CONSOLE]); /* Do CR delay */ /* Wait untill port is ready */ writechar(CONSOLE,NL); ttys[CONSOLE].col = 0; ttys[CONSOLE].line++; nldelay(&ttys[CONSOLE]); /* Do NL delay */ } else{ writechar(CONSOLE,ch); ttys[CONSOLE].line++; nldelay(&ttys[CONSOLE]); /* Do NL delay */ } break; case CR: writechar(CONSOLE,ch); ttys[CONSOLE].col = 0; crdelay(&ttys[CONSOLE]); /* Do CR delay */ break; case TAB: for(c = 0; c < 8; c++) writechar(CONSOLE,' '); break; default: /* Normal character output */ writechar(CONSOLE,ch); break; } return;}/* * tputout Puts the number of bytes given into the output buffer * Setting the buffer to print the characters and * starting off the print if nessecary */tputout(dev, buffer, nbytes)int dev;char *buffer;int nbytes;{ int bytecount; short intlevel; /* Put as many as possible bytes into the output buffer * for this device */ bytecount = tputbuf(buffer,(&ttys[dev].outbuf),nbytes); ttys[dev].outbuf.outrdy = RDY; /* Sets the buffer to print */ /* If acia is waiting for a character give it one to start * The output ( tx_rdy flag notes this ) interupt driven only. */ if(ttydevsw[dev].type == INTERUPT){ if(ttys[dev].tx_rdy){ intlevel = SPLTTY(); /* Disables interupts */ ttyout(dev); /* Outputs a character*/ splx(intlevel); /* Renables them again*/ } } /* If polled type of device print out all characters */ if(ttydevsw[dev].type == POLLED){ while(ttys[dev].outbuf.count>0){ /* If device has character for RX then get it */ if((*ttydevsw[dev].status)(ttydevsw[dev].m_m_dev) & RRDY) ttyin(dev); ttyout(dev); } } return bytecount;}/* * Tputbuf Puts the number of bytes into the buffer if possible * Returns the number of bytes entered. * Common for both input and output buffers * is passed a pointer to the buffer structure */tputbuf(from,tbuf,number)char *from;struct ttybuf *tbuf;short number;{ register int num; register char *topbuf; short intlevel; intlevel = SPLTTY(); /* Disable all interupts */ /* Finds number of characters to write (max is full buffer) */ if((tbuf->count + number) > TTYBUFSIZE){ number = TTYBUFSIZE - tbuf->count; } num = number; topbuf = &tbuf->buf[TTYBUFSIZE]; /* Address of buffer top */ /* Puts data into buffer at inptr wrapping inptr to start of buffer * if necessary */ while(num--){ *tbuf->inptr++ = *from++; if(tbuf->inptr >= topbuf) tbuf->inptr = &tbuf->buf[0]; } /* Updates buffer byte count and high water mark flag */ if((tbuf->count += number) > HIGHMARK) tbuf->inrdy = 0; splx(intlevel); /* Renable interupts */ return number; }/* * Tgetbuf Gets the number of bytes from the buffer if possible * Returns the number of bytes got. */tgetbuf(tbuf,to,number)char *to;struct ttybuf *tbuf;short number;{ register int num; register char *topbuf; short intlevel; /* Test if buffer is ready to output characters */ if(!tbuf->outrdy) return 0; intlevel = SPLTTY(); /* Mask all interupts */ /* Finds number of characters to read */ if(tbuf->count < number){ number = tbuf->count; } num = number; topbuf = &tbuf->buf[TTYBUFSIZE]; /* Address of buffer top */ /* Puts data from buffer to pointer wrapping outptr to start of buffer * if necessary */ while(num--){ *to++ = *tbuf->outptr++; if(tbuf->outptr >= topbuf) tbuf->outptr = &tbuf->buf[0]; } /* Updates buffer count and checks for bellow low water mark */ if(!(tbuf->count -= number)) tbuf->outrdy = 0; if(tbuf->count < LOWMARK) tbuf->inrdy = RDY; splx(intlevel); /* Renable interupts */ return number;}/* * Flush Flush the buffer whose address is given */flush(tbuf)struct ttybuf *tbuf;{ short intlevel; /* If not in an interupt then mask all temparily */ intlevel = SPLTTY(); tbuf->inptr = &tbuf->buf[0]; tbuf->outptr = &tbuf->buf[0]; tbuf->count = 0; tbuf->inrdy = RDY; tbuf->outrdy = NOTRDY; /* Recover last interupt state */ splx(intlevel);}/* * I_tty - implement ioctl for this device (Almost fake), infact its * allmost real now. */i_tty(dev, request, argp)int *argp;{ struct ttystruct *tty; short intlevel; /* Gets address of relevent tty structure */ tty = &ttys[dev]; intlevel = SPLTTY(); /* Mask out those yeuchy interupts */ switch (request) { case TIOCGETP: /* old gtty call in effect */ bytecp(&tty->sgtty, argp, sizeof(struct sgttyb)); break; case TIOCGETC: /* Gets special charcters */ bytecp(&tty->tchars, argp, sizeof(struct tchars)); break; case TIOCGLTC: /* Gets local special charcters */ bytecp(&tty->ltchars, argp, sizeof(struct ltchars)); break; case TIOCSETP: /* Setting params */ bytecp(argp, &tty->sgtty, sizeof(struct sgttyb)); /* Wait until output queue is empty, renable interupts * While this is happening. Call ttywait() to indicate * That the tty handler is dossing around */ splx(intlevel); while(tty->outbuf.count) ttywait(dev,WWAITB); intlevel = SPLTTY(); /* Flush buffers */ flush(&tty->inbuf); flush(&tty->outbuf); /* Sets up physical device */ (*ttydevsw[dev].setfnc)(ttydevsw[dev].m_m_dev); /* Ouput a character if one in output buffer, there * Won't be but ttyout will find this out the hard * way, (such is life!) and set the tx_rdy flag. */ ttyout(dev); break; case TIOCSETN: /* Setting params */ bytecp(argp, &tty->sgtty, sizeof(struct sgttyb)); /* Sets up physical device */ (*ttydevsw[dev].setfnc)(ttydevsw[dev].m_m_dev); /* Ouput a character if one in output buffer */ ttyout(dev); break; case TIOCSETC: /* Sets special charcters */ bytecp(argp, &tty->tchars, sizeof(struct tchars)); break; case TIOCSLTC: /* Sets local special charcters */ bytecp(argp, &tty->ltchars, sizeof(struct ltchars)); break; case TIOCFLUSH: /* Flush all buffers */ flush(&tty->inbuf); flush(&tty->outbuf); break; case FIONREAD: /* Number of bytes in buffer */ *argp = tty->inbuf.count; break; default: /* illegal */ if(state.warning) printf("IOCTL not available %d\n\r",request); splx(intlevel); /* Reset interupt level */ return -1; } /* successful.. */ splx(intlevel); /* Reset interupts good luck! */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -