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

📄 tty.n.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** *	TTY handler			T.Barnaby 	1/6/85 ****************************************************************************** * *	Interupt or polled driven TTY handler for OMU to emulate the Codata *	TTY interface. * *	Implements :- *		RAW, CBREAK, ECHO, CRMOD, TANDEM, XTABS, CRDELAY * *		Knows about special characters (erase, kill, start, *			stop, interupt, quit, eof, input delim). * *		Does Xon, Xoff  properly ? * *		Full 8 bits in RAW, 7 bits masked on all other inputs *			8 bits on all outputs * *		No parity checking performed, tested, done, thought about *			etc etc ... * *		Baud rates settable as per Codata On output speed only. * *		Most Ioctls work except TIOCEXCL, TIOCNXLL and TIOCHPCL. * *		CR and NL delays included with simple loop timmer (delaym()) *			NL1 is set to around 5ms * *		Quit, and interupt not implemented as yet * *	Main routines called from KERNEL are:- * *		o_tty()		Opens and sets up a new device for I/O * *		c_tty()		Closes a device * *		r_tty()		Reads characters from device, waits till *				they are available and returns number read. * *		w_tty()		Write characters to the device waits till *				TTY buffer has them all * *		i_tty()		Ioctl routine does all ioctl's * *	Routines for Kernel error print etc (Polled output):- * *		putchar()	Console character output polled direct *				output. * *		getchar()	Console character input polled direct *				input. * *	Routines called from device drivers :- * *		ttyin()		Input a character from the device to input *				buffer. * *		ttyout()	Output a character to device from output *				buffer. * *	Other routines :- * *		ttywait()	While the TTY handler is waiting around *				it passes through this routine , and is *				given the device number and a flag *				 indicating if the wait is for *				write or for read . *				This routine calls sleep() which will *				cause the process to sleep unitil the *				required event has occured. *				NOTE Wait during WWAITB could have a race *				hazard if sleep is called after the last *				character in the buffer has been transmitted * *		tputout()	Puts a number of characters into the *				Output buffer and initiates real device *				output. * *		tputbuf()	Puts as many characters as posible, or *				the number given into the input, or output *				buffer given. * *		tgetbuf()	Gets as many characters as posible, or *				the number given from the input, or output *				buffer given. * *		writechar()	Does actual character write * *		readchar()	Does actual character read * *	NOTE at the moment the extending of characters on output *		(CRMOD, XTABS etc), is done when an interupt or *		the next character is required from the buffer. *		This means that the extra characters added are *		polled out even when in interupt mode. *		CR, and NL delays are done here. * *	External routines used:- * *		All the device driver routines in tty device switch. * *		SPLTTY()	Mask interupt level (Noramlly level 6 *				defined in excep.h). *		splx()		Sets the interupt level back *		sleep()		Causes the process to go to sleep awaiting *				an event *		wakeup()	Flags all processes that an event has occured *		sendgrp()	Sends a signal to a process group using this tty * *	Events *		If EVENTSON is defined, every time a buffer is ready, *		devevent() is called with the major and minor dev numbers. */# include	"../../include/param.h"# include	<sgtty.h># include	<sys/ioctl.h># include	"../../include/inode.h"# include	"../../include/signal.h"# include	"../../include/procs.h"# include	"../../include/excep.h"# include	"../../include/dev.h"# include	"../../include/state.h"# include       "tty.h"extern struct ttydev ttydevsw[];	/* TTY dev switch */char	putchar(), getchar(), writechar(), readchar();/* TTY structure */struct ttystruct ttys[NDEVS];/* *	Open a tty device * *	If the minor device is not open it is opened by calling *		Its initialisation routine as defined in the *		minor, minor tty device switch (ttydevsw[]) */o_tty(dev){	struct ttystruct *tty;	/* Check if device valid */	if (dev < NDEVS){		tty = &ttys[dev];		/* Pointer to dev structure */		/* Sets processes controlling terminal if this is it.		 * Checks if no valid controlling tty if so set it.		 * I don't like this bit so it may be changed later.		 */		if(cur_proc->tty == -1) cur_proc->tty = dev;		/* If first open set up line */		if (tty->nopens++ == 0){			/* valid device, unopened */			tty->dev = dev;		/* Device No */			tty->col = 0;		/* Column 0 */			tty->line = 0;		/* Line 0 */			/* Input buffer */			flush(&tty->inbuf);			/* Output buffer */			flush(&tty->outbuf);			tty->inxoff = XONSTATE;	/* Xon Xoff flags */			tty->outxoff = XONSTATE;			/* Setup tty.sgtty */			tty->sgtty.sg_ispeed = tty->sgtty.sg_ospeed = INITBAUD;			tty->sgtty.sg_erase = CERASE;			tty->sgtty.sg_kill = CKILL;			tty->sgtty.sg_flags = INITFLAGS;			/* Gets special charcters */			tty->tchars.t_intrc = CINTR;			tty->tchars.t_quitc = CQUIT;			tty->tchars.t_startc = CSTART;			tty->tchars.t_stopc = CSTOP;			tty->tchars.t_eofc = CEOT;			tty->tchars.t_brkc = CBRK;			/* Sets up physical device defined in ttydevsw[] */			(*ttydevsw[dev].setfnc)(ttydevsw[dev].m_m_dev);			tty->tx_ewait = 0;	/* Normal output of buffer */			tty->tx_rdy = RDY;	/* Tx is ready for output */		}		return 0;	}	/* invalid minor device */	return -1;}/* *	Close a TTY device */c_tty(dev){	/* Check if valid device opened */	if (dev < NDEVS && ttys[dev].nopens > 0){		ttys[dev].nopens--;		return 0;	}	else return -1;}/* *	R_tty	Read characters from input buffer if available *		Returns number actualy read. *		Will wait untill the buffer is ready for output *		ie in line mode will wait for NL before returning. */r_tty(dev, buffer, nbytes)char *buffer;{	int bytecount;	struct ttystruct *tty;	tty = &ttys[dev];	/* Waits until characters are available and will return	 * a maxinum of nbytes	 */	while(!tty->inbuf.outrdy){		/* If polled Gets a character when available */		if(ttydevsw[dev].type == POLLED){			 ttyin(dev);			/* Get a character */		}		/* Call ttywait to indicate tty handler is dossing around */		else{			ttywait(dev,RWAITB);		}	}	/* Fetches the characters from the buffer */	bytecount = tgetbuf((&tty->inbuf),buffer,nbytes);	/* Do tandem bit if nescecary */	if(tty->sgtty.sg_flags & TANDEM){		/* If bellow LW mark and in Xoff state send Xon char */		if(tty->inbuf.inrdy && tty->inxoff){			tty->inxoff = XONSTATE;			/* Send character immeadiatly */			writechar(dev, tty->tchars.t_startc);		}	}	return bytecount;}/* *	W_tty	write characters to output buffer, wait until all *		the characters are in the buffer */w_tty(dev, buffer, nbytes)int nbytes;int dev;char *buffer;{	int bytecount;	int no;	/* Write all bytes to tty buffer */	bytecount = nbytes;	/* Wait until all bytes are written */	while(bytecount>0){		/* Puts as many bytes as possible to the output buffer		 * And starts transmission if nessecary		 */		no = tputout(dev,buffer,bytecount);		bytecount -= no;		buffer += no;		/* Call ttywait to indicate tty handler is dossing around */		if(bytecount > 0) ttywait(dev,WWAITB);	}	return nbytes;}/* *	ttywait		All functions withing the tty handler *			will pass through here when they are *			waiting around for somthing or other. */ttywait(dev,type)short dev;char type;{	int c;	switch(type){	case RWAITB:		/* Sets process to sleep on rxbuf */		sleep((caddr_t)&ttys[dev].inbuf,PTTY);		break;	case WWAITB:		/* Sets process to sleep on txbuf */		sleep((caddr_t)&ttys[dev].outbuf,PTTY);		break;	case WWAITC:		/* Sets process to sleep on txbuf waiting for character to		 * be written.		 */		ttys[dev].tx_ewait = 1;		sleep((caddr_t)&ttys[dev].outbuf,PTTY);		ttys[dev].tx_ewait = 0;		break;	}}/* *	ttyin	Character to buffer from device *		This routine is called whenever there is a character *		ready for input (interupt mode), or when one is required *		(polled mode). */ttyin(dev)int dev;{	register struct ttystruct *tty;	char ch, bufrdy, dont_put;	/* If polled Waits untill there is a character ready before	 * Getting it. ttywait() is called to indicate that the tty	 * Handler is dossing arround from within readchar().	 */	ch = readchar(dev);	tty = &ttys[dev];	/* Gets address of tty structure for device */	tty->inbuf.outrdy = bufrdy = 0;	/* Sets buffer to notready for output */	dont_put = 0;			/* Dont put character to buffer flag */	/* Checks if not in RAW mode */	if(!(tty->sgtty.sg_flags & RAW)){		ch &= ~TOPB;		/* Masks top bit */		/* Check special characters */		do {			if(ch == tty->tchars.t_intrc){				/* Send signal to processes flag signal only */				sendgrp(tty->dev,SIGINT,0);				dont_put = 1;		/* Don't output */				break;			}			if(ch == tty->tchars.t_quitc){				/* Send signal to processes flag signal only */				sendgrp(tty->dev,SIGQUIT,0);				dont_put = 1;		/* Don't output */				break;			}			/* Xoff handler , First check if Xoff character */			if(ch == tty->tchars.t_stopc){				dont_put = 1;		/* Don't output */				/* Stops output if going */				if(!tty->outxoff){					tty->outxoff = XOFFSTATE;					break;				}			}			/* NOTE Xoff can fall through here to allow			 *	Single character Xon/Xoff			 */			/* Xon handler, first check if Xon character */			if(ch == tty->tchars.t_startc){				dont_put = 1;		/* Don't output */				/* Starts output if stoped */				if(tty->outxoff){					tty->outxoff = XONSTATE;					if(tty->tx_rdy) ttyout(tty->dev);					break;				}			}			/* Do these bits unless in CBREAK mode */			if(!(tty->sgtty.sg_flags & CBREAK)){				/* Eof handler */				if(ch == tty->tchars.t_eofc){					bufrdy = RDY;	/* Sets buffer ready */					dont_put = 1;	/* Don't output */					break;				}				/* Erase character */				if(ch == tty->sgtty.sg_erase){					/* rubout - not before start of line */					rubout(tty, 1);					dont_put = 1;	/* Don't output */					break;				}				/* Line kill character */				if(ch == tty->sgtty.sg_kill){					/* Rubout till start of buffer */					rubout(tty, tty->inbuf.count);					/* Make sure buffer pointers correct */					tty->inbuf.outptr = tty->inbuf.inptr;					dont_put = 1;	/* Don't output */					break;				}			}			/* End of line character */			if(ch == tty->tchars.t_brkc){				if(ch != (char)(-1)) bufrdy = RDY;				break;			}		}while(0);		/* Checks for CRMOD conversion */		if(ch == CR){			/* Check if CRMOD if so do so */			if(tty->sgtty.sg_flags & CRMOD) ch = NL;		}		/* If line termination set buffer to ready for output */		if(ch == NL) bufrdy = RDY;	}	/* If RAW or CBREAK set buffer ready all all characters unless	 * dontput has been set.	 */	if(!dont_put && (tty->sgtty.sg_flags & (CBREAK | RAW))) bufrdy = RDY;	/* Put character to input buffer if required */	if(!dont_put){		/* If no characters have been put then don't echo */		if(tputbuf(&ch,&tty->inbuf,1)){			/* Do echo if required */			if((tty->sgtty.sg_flags & ECHO) &&				!(tty->sgtty.sg_flags & RAW)){				tputout(tty->dev,&ch,1);  /* No check if done */			}		}	}	/* Sets buffer ready flag if apropriate */	if(bufrdy){		tty->inbuf.outrdy = RDY;		wakeup((caddr_t)&tty->inbuf);#ifdef	EVENTSON		devevent(DEVTTYMAJ, tty->dev);#endif	EVENTSON	}	/* Tandem mode check */	if(tty->sgtty.sg_flags & TANDEM){		/* If above HW mark and not in Xoff state send Xoff */		if(!tty->inbuf.inrdy && !tty->inxoff){			tty->inxoff = XOFFSTATE;			/* Send character imediatly wait untill device ready */			writechar(dev,tty->tchars.t_stopc);		}	}	return 1;}/* *	Readchar	Will wait until a character is ready *			passing through ttywait(), to indicate *			that the tty handler is dossing around again. *			Then low and behold it gets the character Weyyy! *			(ps thats a Mark'ism.) */charreadchar(dev)short dev;{	short intlevel;	char ch;	intlevel = SPLTTY();	/* Wait until device is ready , only if polled device */	if(!ttydevsw[dev].type){		while(!((*ttydevsw[dev].status)(ttydevsw[dev].m_m_dev) & RRDY))			ttywait(dev,RWAITC); 	}	/* Get character character */	ch = (*ttydevsw[dev].rchar)(ttydevsw[dev].m_m_dev);	splx(intlevel);	return ch;}/* * Rubout - rubs out chars in buffer  *              will rub out no more than 'count' chars. *		will rub out only till the start of the buffer *              Returns actual no. rubbed out. */rubout(tty,count)struct ttystruct *tty;int count;{	char ch;	int cnt;	char *botbuf;		/* Start address of buffer */	

⌨️ 快捷键说明

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