mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-18 17:07:24 +00:00
termios is available via `<termios.h>` on all supported platforms, so variants of `<sys/termio.h>` and `<sys/termios.h>` are no longer needed.
305 lines
6.9 KiB
C
305 lines
6.9 KiB
C
/* $Id: rawrs232c.c,v 1.2 1999/01/03 02:07:31 sybalsky Exp $ (C) Copyright Venue, All Rights
|
|
* Reserved */
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* (C) Copyright 1989-95 Venue. All Rights Reserved. */
|
|
/* Manufactured in the United States of America. */
|
|
/* */
|
|
/************************************************************************/
|
|
|
|
#include "version.h"
|
|
|
|
#include <sys/select.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ttold.h>
|
|
#include <sys/time.h>
|
|
#include <stropts.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <termios.h>
|
|
|
|
#include "lispemul.h"
|
|
#include "address.h"
|
|
#include "adr68k.h"
|
|
#include "lsptypes.h"
|
|
#include "lispmap.h"
|
|
#include "emlglob.h"
|
|
#include "lspglob.h"
|
|
#include "debug.h"
|
|
#include "rawrs232c.h"
|
|
|
|
#define MIN_CHARS 256
|
|
#define MIN_TIME 1
|
|
|
|
/************************************************************/
|
|
/*
|
|
|
|
raw232c.c
|
|
Access RS device from Lisp by using FD
|
|
This provides low-level access to RS device.
|
|
|
|
Created: Feb.12 1991
|
|
By Takeshi Shimizu
|
|
|
|
CopyRight Fuji Xerox Co., LTD 1991
|
|
|
|
|
|
*/
|
|
/************************************************************/
|
|
|
|
LispPTR raw_rs232c_open(LispPTR portname)
|
|
{
|
|
ONED_ARRAY *head;
|
|
|
|
char *lispname;
|
|
int fd;
|
|
|
|
if (GetTypeNumber(portname) != TYPE_ONED_ARRAY) error("PORTNAME is not string");
|
|
head = (ONED_ARRAY *)Addr68k_from_LADDR(portname);
|
|
lispname = (char *)Addr68k_from_LADDR(head->BASE);
|
|
|
|
if ((fd = open(lispname, O_RDWR)) < 0) {
|
|
perror("RS open fail: ");
|
|
return (NIL);
|
|
}
|
|
|
|
return (S_POSITIVE | fd);
|
|
|
|
} /* raw_rs232c_open */
|
|
|
|
LispPTR raw_rs232c_setparams(LispPTR fd, LispPTR data)
|
|
{
|
|
RawRSParam *ndata;
|
|
struct termios termdata;
|
|
|
|
/* Get Current params */
|
|
if (ioctl((fd & 0xffff), TCGETS, &termdata) < 0) {
|
|
perror("RS get params:");
|
|
return (NIL);
|
|
}
|
|
|
|
ndata = (RawRSParam *)Addr68k_from_LADDR(data);
|
|
|
|
/* Input */
|
|
termdata.c_iflag |= IXON | IXOFF;
|
|
termdata.c_iflag &= ~(INPCK);
|
|
|
|
/*termdata.c_iflag &= ~IGNBRK;*/
|
|
termdata.c_iflag &= ~IGNPAR;
|
|
termdata.c_iflag &= ~IUCLC;
|
|
if (ndata->InEOL == RAW_RS_CR) {
|
|
termdata.c_iflag |= INLCR;
|
|
termdata.c_iflag &= ~ICRNL;
|
|
}
|
|
|
|
else if (ndata->InEOL == RAW_RS_LF) {
|
|
termdata.c_iflag &= ~INLCR;
|
|
termdata.c_iflag |= ICRNL;
|
|
} else if (ndata->InEOL == RAW_RS_CRLF) {
|
|
termdata.c_iflag &= ~INLCR;
|
|
termdata.c_iflag &= ~ICRNL;
|
|
}
|
|
/* Flow CNT */
|
|
if ((ndata->FlowCnt & 0xff) == RAW_RS_XON)
|
|
termdata.c_iflag |= IXON | IXOFF;
|
|
else {
|
|
termdata.c_iflag &= ~(IXON | IXOFF);
|
|
}
|
|
|
|
termdata.c_iflag &= ~(ISTRIP);
|
|
|
|
/* Output */
|
|
|
|
termdata.c_oflag |= ~OPOST;
|
|
termdata.c_oflag &= ~OLCUC;
|
|
termdata.c_oflag &= ~OFILL;
|
|
termdata.c_oflag &= ~OFDEL;
|
|
termdata.c_oflag &= ~NLDLY;
|
|
termdata.c_oflag &= ~CRDLY;
|
|
termdata.c_oflag &= ~BSDLY;
|
|
termdata.c_oflag &= ~VTDLY;
|
|
termdata.c_oflag &= ~FFDLY;
|
|
|
|
if (ndata->OutEOL == RAW_RS_CR) {
|
|
termdata.c_oflag |= ONLRET;
|
|
termdata.c_oflag &= ~OCRNL;
|
|
termdata.c_oflag &= ~ONLCR;
|
|
} else if (ndata->OutEOL == RAW_RS_LF) {
|
|
termdata.c_oflag &= ~ONLRET;
|
|
termdata.c_oflag |= OCRNL;
|
|
termdata.c_oflag &= ~ONLCR;
|
|
} else if (ndata->OutEOL == RAW_RS_CRLF) {
|
|
termdata.c_oflag &= ~ONLRET;
|
|
termdata.c_oflag &= ~OCRNL;
|
|
termdata.c_oflag |= ONLCR;
|
|
}
|
|
|
|
/* LOCAL */
|
|
|
|
termdata.c_lflag &= ~ISIG;
|
|
termdata.c_lflag &= ~ICANON;
|
|
termdata.c_lflag &= ~XCASE;
|
|
|
|
if (ndata->Echo == ATOM_T)
|
|
termdata.c_lflag |= ECHO;
|
|
else
|
|
termdata.c_lflag &= ~ECHO;
|
|
|
|
termdata.c_lflag &= ~ECHOE;
|
|
termdata.c_lflag &= ~ECHOK;
|
|
termdata.c_lflag &= ~ECHONL;
|
|
termdata.c_lflag &= ~NOFLSH;
|
|
termdata.c_lflag &= ~TOSTOP;
|
|
termdata.c_lflag &= ~ECHOCTL;
|
|
termdata.c_lflag &= ~ECHOPRT;
|
|
termdata.c_lflag &= ~ECHOKE;
|
|
termdata.c_lflag &= ~FLUSHO;
|
|
termdata.c_lflag &= ~PENDIN;
|
|
|
|
/* Minimum and Timeout */
|
|
termdata.c_cc[VMIN] = MIN_CHARS;
|
|
termdata.c_cc[VTIME] = MIN_TIME;
|
|
|
|
/* Control */
|
|
|
|
termdata.c_cflag = (CREAD | HUPCL);
|
|
|
|
/* Local or DialUP */
|
|
|
|
if (ndata->LocalLine == ATOM_T)
|
|
termdata.c_cflag |= CLOCAL;
|
|
else
|
|
termdata.c_cflag &= ~CLOCAL;
|
|
|
|
/* Bau Rate */
|
|
|
|
if (ndata->BauRate != NIL) {
|
|
switch (ndata->BauRate & 0xffff) {
|
|
case 1200: termdata.c_cflag |= B1200; break;
|
|
|
|
case 2400: termdata.c_cflag |= B2400; break;
|
|
|
|
case 4800: termdata.c_cflag |= B4800; break;
|
|
|
|
case 9600: termdata.c_cflag |= 96200; break;
|
|
|
|
default: termdata.c_cflag |= B1200;
|
|
}
|
|
}
|
|
|
|
/* CTS/RTS */
|
|
if ((ndata->RTSCTSCnt & 0xff) == ATOM_T)
|
|
termdata.c_cflag |= CRTSCTS;
|
|
else
|
|
termdata.c_cflag &= ~CRTSCTS;
|
|
|
|
/* Character size */
|
|
|
|
if ((ndata->BitsPerChar & 0xf) == 7)
|
|
termdata.c_cflag |= CS7;
|
|
else if ((ndata->BitsPerChar & 0xf) == 8)
|
|
termdata.c_cflag |= CS8;
|
|
else {
|
|
error("RS232:Not supported char size");
|
|
return (NIL);
|
|
}
|
|
|
|
/* Parity */
|
|
if ((ndata->Parity & 0xf) == RAW_RS_NONE) {
|
|
termdata.c_iflag &= (~(INPCK));
|
|
termdata.c_cflag &= (~PARENB);
|
|
} else if ((ndata->Parity & 0xf) == RAW_RS_EVEN)
|
|
termdata.c_cflag |= PARENB;
|
|
else if ((ndata->Parity & 0xf) == RAW_RS_ODD)
|
|
termdata.c_cflag |= (PARENB | PARODD);
|
|
|
|
/* Stop bits */
|
|
if ((ndata->NoOfStopBits & 0x2) == 2)
|
|
termdata.c_cflag |= CSTOPB;
|
|
else
|
|
termdata.c_cflag &= ~(CSTOPB);
|
|
|
|
/* Set parameters */
|
|
|
|
if (ioctl((fd & 0xffff), TCSETS, &termdata) < 0) {
|
|
perror("RS set params");
|
|
return (NIL);
|
|
}
|
|
|
|
return (ATOM_T);
|
|
|
|
} /* raw_rs232c_setparams */
|
|
|
|
LispPTR raw_rs232c_close(LispPTR fd)
|
|
{
|
|
if (close(0xffff & fd) < 0) {
|
|
perror("RS close : ");
|
|
return (NIL);
|
|
} else
|
|
return (ATOM_T);
|
|
}
|
|
|
|
LispPTR raw_rs232c_write(LispPTR fd, LispPTR baseptr, LispPTR len)
|
|
{
|
|
unsigned char *ptr;
|
|
|
|
ptr = (unsigned char *)Addr68k_from_LADDR(baseptr);
|
|
|
|
if (write((fd & 0xffff), ptr, (len & 0xffff)) < 0) {
|
|
perror("RS-write :");
|
|
return (NIL);
|
|
}
|
|
return (ATOM_T);
|
|
}
|
|
|
|
/* Assume numbers are SMALLPOSP */
|
|
struct timeval RS_TimeOut = {0, 0};
|
|
LispPTR raw_rs232c_read(LispPTR fd, LispPTR buff, LispPTR nbytes)
|
|
{
|
|
unsigned char *buffptr;
|
|
int length;
|
|
u_int real_fd;
|
|
fd_set readfds;
|
|
|
|
real_fd = fd & 0xffff; /* FIXME: should be GetSmallp() ? */
|
|
FD_SET(real_fd, &readfds);
|
|
|
|
select(32, &readfds, NULL, NULL, &RS_TimeOut);
|
|
if (FD_ISSET(real_fd, &readfds)) {
|
|
buffptr = (unsigned char *)Addr68k_from_LADDR(buff);
|
|
|
|
if ((length = read(real_fd, buffptr, (nbytes & 0xffff))) < 0) {
|
|
perror("RS read :");
|
|
return (NIL);
|
|
} else {
|
|
Irq_Stk_End = Irq_Stk_Check = 0;
|
|
return (S_POSITIVE | length);
|
|
}
|
|
}
|
|
|
|
return (S_POSITIVE); /* There is nothing to read */
|
|
|
|
} /* raw_rs232c_read */
|
|
|
|
LispPTR raw_rs232c_setint(LispPTR fd, LispPTR onoff)
|
|
{
|
|
extern fd_set LispReadFds;
|
|
extern fd_set LispIOFds;
|
|
u_int real_fd;
|
|
|
|
real_fd = (fd & 0xffff); /* FIXME: should be GetSmallp() */
|
|
|
|
if (onoff == ATOM_T) {
|
|
FD_SET(real_fd, &LispReadFds);
|
|
FD_SET(real_fd, &LispIOFds);
|
|
int_io_open(real_fd);
|
|
} else {
|
|
int_io_close(real_fd);
|
|
FD_CLR(real_fd, &LispReadFds);
|
|
FD_CLR(real_fd, &LispIOFds);
|
|
}
|
|
return (ATOM_T);
|
|
}
|