home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* xpres 3
- /* SUMMARY
- /* communications port i/o
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* cico
- /* SYNOPSIS
- /* xopen()
- /*
- /* xclose()
- /*
- /* xread(dummy,buf,len)
- /* int dummy,len;
- /* char *buf;
- /*
- /* xwrite(dummy,buf,len)
- /* int dummy,len;
- /* char *buf;
- /*
- /* xioctl(flag)
- /* int flag;
- /* DESCRIPTION
- /* The functions in this module perform functions analogous
- /* to unix system calls, for the serial port of IBM-PC workalikes.
- /*
- /* xopen() initializes a serial port. Also needed under UNIX.
- /*
- /* xclose() closes a port.
- /*
- /* xread(), xwrite() do not use their first argument. Under UNIX
- /* one should use the standard read() and write() system calls.
- /*
- /* xioctl() enables xon/xoff flow control if its argument
- /* is nonzero. Not used under UNIX.
- /* SEE ALSO
- /* comport.asm, IBM-PC comm routines by Tim Pozar
- /* DIAGNOSTICS
- /* The read functions returns EOF in case of timeout; the write
- /* function never detects any failure.
- /* BUGS
- /* The xioctl() function is utterly primitive.
- /* AUTHOR(S)
- /* MS-DOS parts derived from uuslave software (John Gilmore)
- /* published on usenet early 1987. Bugs fixed & severely hacked by
- /*
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Sat Mar 28 23:01:43 GMT+1:00 1987
- /* LAST MODIFICATION
- /* Mon Apr 4 23:51:55 MET 1988
- /* VERSION/RELEASE
- /* 1.3
- /*--*/
-
- #include "defs.h"
- #include "params.h"
- #include "comm.h" /* baud rates, tty ports,... */
- #include "status.h"
- #include "sysdep.h" /* other system dependencies */
- #include "logs.h"
-
- #ifdef unix
- # include <sgtty.h>
- # include <signal.h>
- # include <setjmp.h>
- #endif
-
- #ifdef MSDOS
- # define B(x) (115200/(x))
- static int sigint();
- static void get_time();
- #endif
-
- typedef struct { /* baud-rate lookup table */
- char *name;
- int code;
- } Baud_table;
-
- Baud_table btable[] = {
- #ifdef unix
- "50", B50,
- "75", B75,
- "110", B110,
- "134", B134,
- "150", B150,
- "300", B300,
- "600", B600,
- "1200", B1200,
- "1800", B1800,
- "2400", B2400,
- "4800", B4800,
- "9600", B9600,
- #endif
- #ifdef MSDOS
- "50", B(50),
- "75", B(75),
- "110", B(110),
- "134", B(134),
- "150", B(150),
- "300", B(300),
- "600", B(600),
- "1200", B(1200),
- "1800", B(1800),
- "2400", B(2400),
- "4800", B(4800),
- "9600", B(9600),
- #endif
- 0, 0,
- };
-
- /* xopen - open communications port; parameters taken from setup table */
-
- xopen()
- {
- register Baud_table *bp;
- #ifdef unix
- struct sgttyb ttmode;
- #endif
-
- for (bp = btable; bp->name; bp++) /* look up baud rate */
- if (strcmp(bp->name,COMM_RATE) == 0)
- break;
- if (bp->name == 0) { /* bad baud rate in setup */
- debug(4)("Invalid baud rate %s\n",COMM_RATE);
- exit(E_BADSETUP);
- }
-
- #ifdef unix
- if ((ttfd = open(COMM_LINE,2)) < 0) { /* try to access port */
- debug(4)("Cannot access %s\n",COMM_LINE);
- exit(E_BADSETUP);
- }
- #ifndef SIII
- if (ioctl(ttfd,TIOCEXCL)) /* exclusive access */
- exit(E_BADSETUP); /* not a terminal */
- #endif
- ioctl(ttfd,TIOCHPCL); /* hangup when done */
- gtty(ttfd,&ttmode); /* get port status */
- ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code;/* set baud rate */
- ttmode.sg_flags |= (RAW); /* raw mode */
- #ifdef SIII
- ttmode.sg_flags &= ~ECHO;
- #else
- ttmode.sg_flags &= ~(ECHO|TANDEM|CBREAK); /* no echo, crlf, flow ctrl */
- #endif
- stty(ttfd,&ttmode);
- #endif
-
- #ifdef MSDOS
- set_tty(bp->code); /* set baud rate, DTR */
- init_comm(); /* turn interrupts on */
- signal(SIGINT,sigint); /* must reset tty */
- inp_flush(); /* flush garbage */
- sleep(3);
- #endif
- }
-
- /* xclose - release the communications port */
-
- xclose()
- {
- #ifdef unix
- close(ttfd);
- #endif
-
- #ifdef MSDOS
- uninit_comm();
- #endif
- }
-
- /* xread - read from the serial port */
-
- #ifdef MSDOS
-
- xread(fd,buf,cnt)
- int fd;
- char *buf;
- register int cnt;
- {
- register char *p = buf;
- register int c;
-
- while (cnt > 0 && (c = xgetc()) != EOF) {
- *p++ = c;
- cnt--;
- }
- return(p-buf ? p-buf : -1);
- }
- #endif /* MSDOS xwrite() */
-
- /* xgetc - read one character from serial port */
-
- #ifdef unix
- jmp_buf xbuf;
-
- static timeout() /* aux function for xgetc */
- {
- longjmp(xbuf,1);
- }
-
- xgetc() /* return next char */
- {
- char ch;
-
- if (setjmp(xbuf)) /* in case we time out */
- return(EOF); /* we just did */
- signal(SIGALRM,timeout); /* set timer response */
- alarm(BYTE_TIMEOUT); /* set timer */
-
- read(ttfd,&ch,1); /* go wait for character */
- alarm(0); /* turn timer off */
- return(ch&0377); /* successfull termination */
- }
- #endif /* unix xgetc() */
-
- #ifdef MSDOS
-
- xgetc()
- {
- char data;
-
- int i;
- unsigned s;
- TIME n;
-
- i = 0;
- get_time(&n);
- s = n.sec;
-
- /*
- * Implement timeouts by staring at the clock while we wait.
- * When the second hand moves, bump our counter. This is a lot
- * easier than figuring out the time when we'd time out (in hours,
- * minutes, and seconds!) and comparing against that, which is
- * what people tend to do in Unix where the time is just an integer
- * number of seconds.
- */
- while (i < BYTE_TIMEOUT) {
- while (s == n.sec) {
- if(inp_cnt() != 0) {
- data = inp_char();
- return (data & 0xFF);
- }
- get_time (&n);
- }
- s = n.sec;
- ++i;
- }
- return(EOF);
- }
-
- /* xwrite - write buffer to serial port */
-
- xwrite(fd,buf,ctr)
- int fd;
- register char *buf;
- int ctr;
- {
- register int i = ctr;
-
- while (i-- > 0)
- outp_char(*buf++);
- return ctr;
- }
-
- /*
- * Routines specific to MS-DOS
- *
- * xioctl() enable xon/xoff
- * get_timer() read current time
- * sigint() clean up interrupt handler and exit
- * sleep() unix lookalike
- */
-
- /* xioctl - enable xon/xoff protocol */
-
- xioctl(flag)
- int flag;
- {
- set_xoff(flag); /* Enable (flag != 0) or disable flow control */
- }
-
- /* sigint - restore terminal settings on dialout line */
-
- static int sigint()
- {
- uninit_comm();
- reset_tty();
- exit(0);
- }
-
- /* get_time - read time with dos call */
-
- static void get_time(n)
- TIME_PTR n;
- {
- union REGS inregs;
- union REGS outregs;
-
- inregs.h.ah = 0x2c; /* Please make a #define for this, Tim */
-
- int86(0x21, &inregs, &outregs);/* Please #define the 0x21 too */
-
- n->hour = outregs.h.ch;
- n->minute = outregs.h.cl;
- n->sec = outregs.h.dh;
- n->hsec = outregs.h.dl;
- }
-
- #define get_sec(n) (get_time(&n),n.sec)
-
- sleep(x)
- int x;
- {
- TIME n; /* current time record */
- unsigned s = get_sec(n);
-
- while (x-- > 0) {
- while (s == get_sec(n))
- /* void */ ;
- s = n.sec;
- }
- }
-
- #endif /* MSDOS */
-