www.pudn.com > 日期、菜单、字符串的C函数.rar > IBMTTY.C


/*                          *** ibmtty.c ***                         */ 
/*                                                                   */ 
/* IBM-PC microsoft "C" under PC-DOS                                 */ 
/*                                                                   */ 
/* Terminal emulation program with file upload and download capabili-*/ 
/* ties.  Optimized to communicate with a DEC VAX 11/780.            */ 
/*                                                                   */ 
/* Written by L. Cuthbertson, April 1984.                            */ 
/*                                                                   */ 
/*********************************************************************/ 
/*                                                                   */ 
  
#include  
  
#define TRUE 1 
#define FALSE 0 
#define XON '\021' 
#define XOFF '\023' 
#define ESC '\033' 
#define CONZ '\032' 
#define DEL '\177' 
  
#define LCR 0x3FB	/* 8250 line control register */ 
#define DLL 0x3F8	/* 8250 least significant divisor latch */ 
#define DLM 0x3F9	/* 8250 most significant divisor latch */ 
#define LSR 0x3FD	/* 8250 line status register */ 
#define IIR 0x3FA	/* 8250 interrupt identification register */ 
#define IER 0x3F9	/* 8250 interrupt enable register */ 
#define MCR 0x3FC	/* 8250 modem control register */ 
#define MSR 0x3FE	/* 8250 modem status register */ 
#define RBR 0x3F8	/* 8250 receiver buffer register */ 
#define THR 0x3F8	/* 8250 transmitter holding register */ 
 
char *lcr=(char*)LCR, *dll=(char*)DLL, *dlm=(char*)DLM; 
char *lsr=(char*)LSR, *iir=(char*)IIR, *ier=(char*)IER; 
char *mcr=(char*)MCR, *msr=(char*)MSR, *rbr=(char*)RBR; 
char *thr=(char*)THR; 
  
struct buf { 
	char *fbuf; 
	char *wbuf,*rbuf; 
	char *lbuf; 
}; 
  
struct buf mem;			/* file receiption/transmission buff */ 
 
char combuf[64];		/* transmission buffer */ 
struct buf com; 
 
char crtbuf[512];		/* receiption buffer */ 
struct buf crt; 
  
char outfil[13];		/* transmit file name */ 
FILE *outchan; 
  
char infil[13];			/* receive file name */ 
FILE *inchan; 
  
char lecho = FALSE; 
char gotxoff = FALSE; 
char sendxoff = FALSE; 
char sentxoff = FALSE; 
  
/*********************************************************************/ 
/*                                                                   */ 
main(argc,argv) 
int argc; 
char *argv[]; 
{ 
	char *malloc(); 
	int iret,port; 
	unsigned u; 
  
	/* initialize file receiption/transmission */ 
	inchan = FALSE; 
	outchan = FALSE; 
 
	/* set up buffer structures */ 
	com.fbuf = com.wbuf = com.rbuf = &combuf[0]; 
	com.lbuf = &combuf[0] + sizeof(combuf) - 1; 
	crt.fbuf = crt.wbuf = crt.rbuf = &crtbuf[0]; 
	crt.lbuf = &crtbuf[0] + sizeof(crtbuf) - 1; 
 
	/* allocate as much memory as possible to file buffer */ 
	for (u=65023;;u -= 512) { 
		if (u < (512+(5*_BUFSIZ))) { 
			writes("\r\n\007*** not enough memory available ***"); 
			exit(); 
		} 
		mem.fbuf = malloc(u); 
		if (mem.fbuf != 0) { 
			free(mem.fbuf); 
			u -= 5*_BUFSIZ; 
			mem.fbuf = malloc(u); 
			break; 
		} 
	} 
 
	mem.wbuf = mem.rbuf = mem.fbuf; 
	mem.lbuf = mem.fbuf + u - 1; 
 
	/* determine communications port to use */ 
	if (argc > 1) { 
		sscanf(argv[1],"%d",&port); 
		port--; 
		if ((port < 0) || (port > 1)) { 
			writes("\r\n\007*** invalid communications port - enter 1 or 2 ***"); 
			exit(); 
		} 
	} else { 
		port = 0; 
	} 
 
	/* adjust port addresses if neccessary */ 
	if (port == 1) { 
		lcr -= 0x100; 
		dll -= 0x100; 
		dlm -= 0x100; 
		lsr -= 0x100; 
		iir -= 0x100; 
		ier -= 0x100; 
		mcr -= 0x100; 
		msr -= 0x100; 
		rbr -= 0x100; 
		thr -= 0x100; 
	} 
  
	/* initialize 8250  - use DOS "MODE" command */ 
	outp(mcr,3);		/* send DTR and RTS */ 
	pause(1.); 
 
	/* check for carrier */ 
	if ((inp(msr)&48) != 48) { 
		writes("\r\n\007*** carrier not detected - please check your connections ***"); 
		exit(); 
	} 
 
	/* courtesy message */ 
	cursor(25,1); 
	writes("\r\n*** you are now connected ***\r\n"); 
  
	/* polling loop */ 
	for (;;) { 
 
		/* check communications port for reception of data */ 
		if ((readcomm()) != 0) 
			; 
 
		/* check if screen output needed */ 
		if ((wrtscr()) != 0) 
			; 
 
		/* check communications port for receiption of data */ 
		if ((readcomm()) != 0) 
			; 
 
		/* write characters to comm port for transmission */ 
		if ((wrtcomm()) != 0) 
			; 
 
		/* check communications port for receiption of data */ 
		if ((readcomm()) != 0) 
			; 
 
		/* check for screen output */ 
		if ((wrtscr()) != 0) 
			; 
 
		/* check communications port for receiption of data */ 
		if ((readcomm()) != 0) 
			; 
 
		/* check for keyboard entry */ 
		if ((readkey()) != 0) 
			; 
  
	} 
} 
 
/*********************************************************************/ 
/* Check the comm port for receiption of data and puts recieved data */ 
/* into buffers.  Returns a -1 if error detected, 0 if no data, or   */ 
/* the character received.                                           */ 
/*                                                                   */ 
int readcomm() 
{ 
	static char oldc = NULL; 
	static char c; 
	static int iret; 
 
	/* check comm port for data receiption */ 
	iret = inp(lsr); 
	if ((iret&1) != 0) { 
 
		/* ignore data overrun errors */ 
		/* expect to loose padd characters at high baud rate */ 
		if ((iret&2) != 0) { 
			; 
 
		/* framing or parity error */ 
		} else if ((iret&12) != 0) { 
			writes("\007*** data reception error ***"); 
			return(-1); 
 
		/* break currenly being sent */ 
		} else if ((iret&16) != 0) { 
			return(0);	/* break detect */ 
		} 
 
		/* read character */ 
		c = inp(rbr)&127; 
 
		/* process character */ 
		if (c == XOFF) { 
			gotxoff = TRUE; 
		} else if (c == XON) { 
			gotxoff = FALSE; 
		} else if (c != NULL) { 
 
			/* prevent CR CR LF line endings */ 
			if ((c != '\r') || (oldc != '\r')) { 
 
				/* store character in receiption buffer */ 
				if ((putbuf(&crt,c)) == (-1)) { 
					writes("\007*** screen buffer overflow ***"); 
					return(-1); 
				} 
 
				/* store character if file receiption buffer */ 
				if (inchan) { 
					if ((putbuf(&mem,c)) == (-1)) { 
						writes("\007*** file receiption buffer overflow ***"); 
						inchan = FALSE; 
						return(-1); 
					} 
				} 
			} 
			oldc = c; 
		} 
		return(c); 
	} 
  
	/* no character found */ 
	return(0); 
} 
 
/*********************************************************************/ 
/* write characters from the screen buffer to the screen.  Returns a */ 
/* -1 if error occured, 0 if no characters in buffer, or character   */ 
/* written.                                                          */ 
/*                                                                   */ 
int wrtscr() 
{ 
	static char c; 
	static int i,iret; 
 
	/* get character from screen buffer */ 
	if ((iret = getbuf(&crt)) != (-1)) { 
		c = iret&127;	/* strip parity */ 
 
		/* if line feed then scroll screen */ 
		if (c == '\n') { 
			if ((iret = doscr()) == (-1)) { 
				return(-1); 
			} 
 
		/* handle tabs seperatly */ 
		} else if (c == '\t') { 
			if ((iret = dotab()) == (-1)) { 
				return(-1); 
			} 
 
		/* output other characters */ 
		} else { 
			biostty(c); 
		} 
		return(c); 
	} 
 
	/* no character in buffer */ 
	return(0); 
} 
 
/*********************************************************************/ 
/* scroll the screen up one line at a time while checking the comm   */ 
/* port for data receiption.  Returns a -1 if an error occured.      */ 
/*                                                                   */ 
int doscr() 
{ 
	static char fillchar; 
	static int trow,tlcol,brow,brcol; 
	static int iret; 
 
	/* initialize */ 
	fillchar = 0x20;	/* fill opened line with blanks */ 
	tlcol = 0;		/* top left column of window */ 
	brcol = 79;		/* bottom right column of window */ 
 
	/* begin check and scroll loop */ 
	for(trow=0;trow<24;trow++) { 
 
		/* check comm port for data receiption */ 
		if ((iret = readcomm()) == (-1)) { 
			return(-1); 
		} 
 
		/* scroll 1 line up */ 
		brow = trow + 1; 
		biosup(1,trow,tlcol,brow,brcol,fillchar); 
	} 
 
	return(0); 
} 
 
/*********************************************************************/ 
/* Output a horizontal tab to screen while checking communications   */ 
/* port for transmission.  Returns a -1 if an error occured.         */ 
/*                                                                   */ 
int dotab() 
{ 
	static int iret,irow,icol; 
 
	/* check comm port for receiption of data */ 
	if ((iret = readcomm()) == (-1)) { 
		return(-1); 
	} 
 
	/* find cursor position */ 
	iret = biospos(); 
	icol = iret & 255;	/* column returned in low order bits */ 
	irow = iret >> 8;	/* row returned in high order bits */ 
 
	/* check comm port for receiption of data */ 
	if ((iret = readcomm()) == (-1)) { 
		return(-1); 
	} 
 
	/* calculate tab position */ 
	icol++; 
	while ((icol % 8) != 0) { 
		icol++; 
	} 
 
	/* set cursor to that position */ 
	biosset(irow,icol); 
 
	return(0); 
} 
 
/*********************************************************************/ 
/* write characters to communications port for transmission.  Return */ 
/* a -1 if error, 0 if no characters written, or character written.  */ 
/*                                                                   */ 
int wrtcomm() 
{ 
	static char c,pushback; 
	static int iret,lstat; 
 
	/* write characters to communications port for transmission */ 
	lstat=inp(lsr); 
	if (((lstat&32) != 0) && (!gotxoff)) { 
 
		/* write characters received from keyboard */ 
		if ((iret=getbuf(&com)) != (-1)) { 
			c = iret&127; 
			outp(thr,c); 
			if (lecho) putbuf(&crt,c); 
			return(c); 
 
		/* write characters from file */ 
		} else if (outchan) { 
			if (pushback != NULL) { 
				outp(thr,pushback); 
				pushback = NULL; 
				if (lecho) putbuf(&crt,pushback); 
				return(pushback); 
			} 
 
			if ((iret=getbuf(&mem)) == (-1)) { 
				outp(thr,CONZ); 
				fclose(outchan); 
				outchan = FALSE; 
				mem.wbuf = mem.rbuf = mem.fbuf; 
				return(0); 
			} 
 
			c = iret&127; 
			if (c == '\n') { 
				outp(thr,'\r'); 
				if (lecho) { 
					putbuf(&crt,'\r'); 
					putbuf(&crt,'\n'); 
				} else { 
					dowait(); 
				} 
			} else { 
				outp(thr,c); 
				if (lecho) putbuf(&crt,c); 
			} 
			return(c); 
		} 
	} 
 
	return(0); 
} 
 
/*********************************************************************/ 
/* Function to wait until the receiption of a line feed after the    */ 
/* transmission of a carriage return.                                */ 
/*                                                                   */ 
int dowait() 
{ 
	int iret; 
 
	/* loop */ 
	while ((iret=readcomm()) != '\n') { 
		if (iret == -1) break; 
	} 
 
	return(0); 
} 
 
/*********************************************************************/ 
/* Check the keyboard for receipt of a character and buffer it.      */ 
/* Returns a -1 if error occured, 0 if no character at keyboard, or  */ 
/* character typed.                                                  */ 
/*                                                                   */ 
/* kbhit() is a special IBM-PC microsoft "C" function.               */ 
/*                                                                   */ 
int readkey() 
{ 
	static char c; 
 
	/* check for keyboard entry */ 
	if (kbhit()) { 
		c = readc(); 
 
		/* display menu if ESCAPE entered */ 
		if (c == ESC) { 
			doesc(); 
			return(c); 
		} 
 
		/* character mapping */ 
		if (c == '\b') { 
			c = DEL; 
		} else if (c == '\n') { 
			c = '\r'; 
		} 
 
		/* store character in keyboard buffer */ 
		if (putbuf(&com,c) == (-1)) { 
			writes("\007");		/* buffer full */ 
			return(-1); 
		} 
		return(c); 
	} 
  
	return(0); 
} 
 
/*********************************************************************/ 
/* Write a character into a buffer.  Returns a -1 if overflow.       */ 
/*                                                                   */ 
int putbuf(p,c) 
struct buf *p; 
char c; 
{ 
	*p->wbuf = c; 
  
	/* increment (possible wrap-around) pointer */ 
	if (++p->wbuf > p->lbuf) p->wbuf = p->fbuf; 
  
	/* if overflow, indicate */ 
	if (p->wbuf == p->rbuf) { 
		if (--p->wbuf < p->fbuf) p->wbuf = p->lbuf; 
		return(-1); 
	} 
  
	return(0); 
} 
  
/*********************************************************************/ 
/* Read a character from a buffer.  Returns a -1 if buffer is empty. */ 
/*                                                                   */ 
int getbuf(p) 
struct buf *p; 
{ 
	static int c; 
  
	/* empty */ 
	if (p->rbuf == p->wbuf) return(-1); 
  
	/* get char, increment (possible wrap-around) pointer */ 
	c = *p->rbuf; 
	if (++p->rbuf > p->lbuf) p->rbuf = p->fbuf; 
  
	return(c); 
} 
  
/*********************************************************************/ 
/* Function to do special features.                                  */ 
/*                                                                   */ 
int doesc() 
{ 
	char ans[3],memsiz[6]; 
	char c; 
	int iret,ians; 
 
	/* output special information */ 
	loop: 
	escreen(2);		/* erase screen */ 
 
	writes("\r\n memory buffer is : "); 
	sprintf(memsiz,"%u",(mem.wbuf-mem.fbuf)); 
	writes(memsiz); 
	writes("/"); 
	sprintf(memsiz,"%u",(mem.lbuf-mem.fbuf)); 
	writes(memsiz); 
 
	writes("\r\n receive file is  : "); 
	writes((inchan)?infil:""); 
  
	writes("\r\n transmit file is : "); 
	writes((outchan)?outfil:""); 
  
	writes("\r\n local echo is    : "); 
	writes((lecho)?"":""); 
 
	/* output menu and accept choice */ 
	if ((ians=chosit("comm",ans,sizeof(ans))) == (-1)) { 
		writes("\r\n\007*** error displaying menu ***"); 
		ians = 4; 
	} 
 
	/* execute command */ 
	switch (ians) { 
  
		case 5: 
			if (inchan) { 
				wrtbuf(); 
				fclose(inchan); 
			} 
			if (outchan) fclose(outchan); 
			outp(mcr,0);	/* drop DTR and RTS */ 
			writes("\r\n"); 
			exit(); 
			break; 
 
		case 4: 
			cursor(25,1); 
			writes("\r\n*** you are now back as a terminal ***\r\n"); 
			return(0); 
			break; 
  
		case 3: 
			lecho = !lecho; 
			break; 
  
		case 2: 
			if (outchan) { 
				fclose(outchan); 
				outchan = FALSE; 
				mem.wbuf = mem.rbuf = mem.fbuf; 
			} else { 
				if (inchan) { 
					wrtbuf(); 
					fclose(inchan); 
					inchan = FALSE; 
				} 
				sendfile: 
				writes("\r\n\nFilename? "); 
				reads(outfil,sizeof(outfil)); 
				if (outfil[0] == NULL) goto done; 
 
				if ((outchan=fopen(&outfil[0],"r")) == NULL) { 
					writes("\007  *** can't open file ***"); 
					goto sendfile; 
				} 
 
				readbuf(); 
			} 
			break; 
  
		case 1: 
			if (inchan) { 
				wrtbuf(); 
				fclose(inchan); 
				inchan = FALSE; 
			} else { 
				if (outchan) { 
					fclose(outchan); 
					outchan = FALSE; 
					mem.wbuf = mem.rbuf = mem.fbuf; 
				} 
				savefile: 
				writes("\r\n\nFilename? "); 
				reads(infil,sizeof(infil)); 
				if (infil[0] == NULL) goto done; 
 
				if ((inchan=fopen(&infil[0],"w")) == NULL) { 
					writes("\007  *** can't open file ***"); 
					goto savefile; 
				} 
			} 
			break; 
  
	} 
	done: 
	goto loop; 
} 
  
/*********************************************************************/ 
/* Function to write the data receiption buffer to output file.      */ 
/*                                                                   */ 
int wrtbuf() 
{ 
	for (mem.rbuf=mem.fbuf;mem.rbuf