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

📄 tty.n.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -