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

📄 termio.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: lib/termio.c * Purpose: Part of C runtime library * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970304	Start of revision history *	970826	Created addDevice. Changed devinit to use addDevice. *	980616	Removed devinit. *	980618	Added ioctl call to get baudlist from driver. */#include <queue.h>#include <stdio.h>#include <termio.h>#include <mips.h>#include <errno.h>#include <terms.h>fFunc *clkinit_ptr;void *_clkinfo;DevEntry DevTable[DEV_MAX];File _file[OPEN_MAX] = {	{0,1},{0,1},{0,1}	};struct TermEntry {	char *name;	Func *func;	};int tvi920(),vt100();int p2681();struct TermEntry TermTable[] = {	{"tvi920",tvi920},	{"vt100",vt100},	{0}};int *curlst;  /* list of files open in the current context */int re_ether;/**************************************************************  _write(fd,buf,n) write n bytes from buf to fd*/_write(fd,buf,n)int fd,n;char *buf;{int i;DevEntry *p;char *t;if (fd == ETHERFD) return(0);p = &DevTable[_file[fd].dev];for (i=0;i<n;i++) {	scandevs();	if (p->t.c_oflag&ONLCR && buf[i] == '\n') _chwrite(p,'\r');	if (p->t.c_lflag&ECHOE && buf[i] == p->t.c_cc[VERASE]) {		for (t="\b \b";*t;t++) _chwrite(p,*t);		}	else _chwrite(p,buf[i]);	}return(i);}/**************************************************************  _chwrite(p,ch)*	write one character*/_chwrite(p,ch)DevEntry *p;char ch;{while (p->txoff) reschedule("write txoff");while (!(*p->handler)(OP_TXRDY,p->sio,p->chan)) reschedule("write txrdy");(*p->handler)(OP_TX,p->sio,p->chan,ch);}/**************************************************************  scandevs()*	scan devices for input*/scandevs(){int i,c,n;DevEntry *p;for (i=0;DevTable[i].rxq && DevTable[i].pollin;i++) {	p = &DevTable[i];	if ((*p->handler)(OP_RXRDY,p->sio,p->chan)) {		c = (*p->handler)(OP_RX,p->sio,p->chan);		if (p->t.c_iflag&ISTRIP) c &= 0x7f;		n = Qinquiry(p->rxq,Q_SPACE);		if (c == p->t.c_cc[VINTR] && p->intr) longjmp(p->intr,1);		else if (p->t.c_iflag&IXON && p->t.c_iflag&IXANY 			&& p->txoff) p->txoff = 0;		else if (p->t.c_iflag&IXON && c == p->t.c_cc[V_STOP]) 			p->txoff = 1;		else if (p->t.c_iflag&IXON && c == p->t.c_cc[V_START]) 			p->txoff = 0;		else if (n > 0) {			Qput(p->rxq,c);			if (n < 10 && p->t.c_iflag&IXOFF && !p->rxoff) {				p->rxoff = 1;				_chwrite(p,CNTRL('S'));				}			}		}	}}#ifdef BSO_TASKING#pragma nooptim#endif/**************************************************************  _ioctl(fd,op,argp) perform control operation on fd */_ioctl(fd,op,argp)int fd,op,*argp;{DevEntry *p;struct termio *t;int i;if (fd == ETHERFD) return(0);switch (op) {	case TXRDY  :		p = &DevTable[_file[fd].dev];		if ((*p->handler)(OP_TXRDY,p->sio,p->chan,0)) return(1);		break;	case TCGETA :		p = &DevTable[_file[fd].dev];		t = (struct termio *) argp;		*t = p->t;		break;	case TCSETAF : /* after flush of input queue */		p = &DevTable[_file[fd].dev];		while (! Qempty(p->rxq)) Qget(p->rxq);	case TCSETAW : /* after write */		/* no txq, so no delay needed */		p = &DevTable[_file[fd].dev];		if (p->t.c_cflag != ((struct termio *)argp)->c_cflag) {			if ((*p->handler)(OP_BAUD,p->sio,p->chan,				CBAUD&((struct termio *)argp)->c_cflag)) 					return(-1);			}		p->t = *((struct termio *) argp);		break;	case FIONREAD :		p = &DevTable[_file[fd].dev];		scandevs();		*argp = Qinquiry(p->rxq,Q_USED);		break;	case SETINTR :		p = &DevTable[_file[fd].dev];		p->intr = (jmp_buf *)argp;		break;	case GETINTR :		p = &DevTable[_file[fd].dev];		*argp = (unsigned long)p->intr;		break;	case SETICEE : /* ICANON & ECHOE */		p = &DevTable[_file[fd].dev];		p->t.c_lflag = (ICANON|ECHOE);		break;	case SETSANE :		p = &DevTable[_file[fd].dev];		p->t.c_iflag |= (ISTRIP|ICRNL|IXON);		p->t.c_lflag = (ICANON|ECHO|ECHOE); /* required */		p->t.c_oflag = (ONLCR);		p->t.c_cc[VINTR] = CNTRL('c');		p->t.c_cc[VEOL] = '\n';		p->t.c_cc[VEOL2] = CNTRL('c');		p->t.c_cc[VERASE] = CNTRL('h');		p->t.c_cc[V_STOP] = CNTRL('s');		p->t.c_cc[V_START] = CNTRL('q');		break;	case SETNCNE : 		p = &DevTable[_file[fd].dev];		if (argp != 0) {			t = (struct termio *) argp;			*t = p->t;			}		p->t.c_lflag &= ~(ICANON|ECHO|ECHOE);		p->t.c_cc[4] = 1;		break;	case CBREAK :		p = &DevTable[_file[fd].dev];		if (argp != 0) {			t = (struct termio *) argp;			*t = p->t;			}		p->t.c_lflag &= ~(ICANON|ECHO);		p->t.c_cc[4] = 1;		break;	case GETTERM :		p = &DevTable[_file[fd].dev];		*argp = 0;		if (p->tfunc == 0) return(-1);		strcpy((char *)argp,p->tname);		break;	case SETTERM :		p = &DevTable[_file[fd].dev];		for (i=0;TermTable[i].name;i++) {			if (strequ(argp,TermTable[i].name)) break;			}		if (TermTable[i].name == 0) return(-1);		p->tname = TermTable[i].name;		p->tfunc = TermTable[i].func;		break;	case TERMTYPE :		if (TermTable[fd].name == 0) return(-1);		strcpy((char *)argp,TermTable[fd].name);		return(fd+1);	case DEVENTRY :		p = &DevTable[_file[fd].dev];		*argp = (int)p;		break;	case BAUDRATES  :		p = &DevTable[_file[fd].dev];		*argp = (*p->handler)(OP_BAUDRATES,p->sio,p->chan,0);		break;	default:		return(-1);	}return(0);}#ifdef BSO_TASKING#pragma optim#endif/**************************************************************  reschedule(p)*	gets called when there's nothing better to do*/reschedule(p)char *p;{ scandevs();}/**************************************************************  ttctl(fd,op,a1,a2) perform terminal specific operation */ttctl(fd,op,a1,a2)int fd,op,a1,a2;{DevEntry *p;int r;p = &DevTable[_file[fd].dev];if (p->tfunc == 0) return(-1);r = (*p->tfunc)(fd,op,a1,a2);return(r);}/**************************************************************  _open(fname,mode,perms) *	return fd for fname. mode and perms are ignored.*/_open(fname,mode,perms)char *fname;int mode,perms;{int i,c,dev,len;char tmp[80];#ifdef ETHERNETif (strequ(fname,"ethernet")) return ether_open(getMonEnv("etheraddr"));#endiffor (i=0;i<OPEN_MAX && _file[i].valid;i++) ;if (i == OPEN_MAX) {	errno = EMFILE;	return(-1);	}len = strlen(fname);if (len == 9) fname += 5; /* step past "/dev/" */else if (len != 4) { /* name too short */	errno = ENOENT;	return(-1);	}strncpy(tmp,fname,3);if (!strequ(tmp,"tty")) { /* must be ttyX */	errno = ENOENT;	return(-1);	}c = fname[3]; /* accept tty[a-z] tty[A-Z] tty[0-9] */if (c >= 'a' && c <= 'z') dev = c - 'a';if (c >= 'A' && c <= 'Z') dev = c - 'A';if (c >= '0' && c <= '9') dev = c - '0';if (dev > DEV_MAX) { /* device number too large */	errno = ENOENT;	return(-1);	}if (DevTable[dev].rxq == 0) { /* device not initialized */	errno = ENOENT;	return(-1);	}_file[i].valid = 1;_file[i].dev = dev;ioctl(i,SETSANE);if (curlst) *curlst |= (1<<i);return(i);}/**************************************************************  _close(fd) close fd */_close(fd)int fd;{#ifdef ETHERNETif (fd == ETHERFD) {	ether_close();	return;	}#endif_file[fd].valid = 0;if (curlst) *curlst &= ~(1<<fd);}/**************************************************************  _read(fd,buf,n) read n bytes into buf from fd */_read(fd,buf,n)int fd,n;char *buf;{int i,used;DevEntry *p;char ch;#ifdef ETHERNETif (fd == ETHERFD) return ether_read(fd,buf,n);#endifp = &DevTable[_file[fd].dev];for (i=0;i<n;) {	scandevs();	while ((used=Qinquiry(p->rxq,Q_USED)) == 0) reschedule("read Qempty");	if (used < 10 && p->rxoff) {		p->rxoff = 0;		_chwrite(p,CNTRL('Q'));		}	ch = Qget(p->rxq);	if (p->t.c_iflag&ICRNL && ch == '\r') ch = '\n';	if (p->t.c_lflag&ICANON) {		if (p->t.c_cc[VERASE] != 0xff && ch == p->t.c_cc[VERASE]) {			if (i > 0) {				i--;				if (p->t.c_lflag&ECHO) write(fd,&ch,1);				}			}		else {			if (p->t.c_lflag&ECHO) write(fd,&ch,1);			buf[i++] = ch;			}		if (ch == p->t.c_cc[VEOL]) break;		if (ch == p->t.c_cc[VEOL2]) break;		}	else {		if (p->t.c_lflag&ECHO) write(fd,&ch,1);		buf[i++] = ch;		break;		}	}return(i);}/**************************************************************  Func *_clkinit()*/Func *_clkinit(){if (!clkinit_ptr) return(0);return (* clkinit_ptr)();}/**************************************************************  addDevice(devinfo,chan,handler,rxqsize,brate)*/addDevice(devinfo,chan,handler,rxqsize,brate)Addr devinfo;	/* addr of struct containing device address etc */int chan;	/* channel#. Used for DUARTS */Func *handler;	/* addr of driver */int rxqsize;	/* size of receive buffer */int brate;	/* default baudrate */{int i,r;DevEntry *p;/* find first available device */for (i=0;DevTable[i].rxq && i < DEV_MAX;i++) ;if (i >= DEV_MAX) return;p = &DevTable[i];p->txoff = 0;p->rxoff = 0;if (chan == 0) (*handler)(OP_INIT,devinfo,brate);p->qsize = rxqsize;p->rxq = Qcreate(p->qsize);if (p->rxq == 0) return(-1);r = (*handler)(OP_BAUD,devinfo,chan,brate);p->sio = devinfo;p->chan = chan;p->handler = handler;p->intr = 0;p->pollin = 1;p->tfunc = 0;p->t.c_iflag = (ISTRIP|ICRNL|IXON);p->t.c_oflag = (ONLCR);p->t.c_lflag = (ICANON|ECHO|ECHOE);p->t.c_cflag = brate;p->t.c_cc[VINTR] = CNTRL('c');p->t.c_cc[VEOL] = '\n';p->t.c_cc[VEOL2] = CNTRL('c');p->t.c_cc[VERASE] = CNTRL('h');p->t.c_cc[V_STOP] = CNTRL('s');p->t.c_cc[V_START] = CNTRL('q');if (r==0) _chwrite(p,CNTRL('Q'));}

⌨️ 快捷键说明

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