home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume3
/
pcmail
/
part03
/
xpres.c
< prev
Wrap
C/C++ Source or Header
|
1989-02-03
|
7KB
|
332 lines
/*++
/* 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 */