home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d8xx
/
d801
/
cyberx10.lha
/
CyberX10
/
Source
/
serial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-24
|
5KB
|
204 lines
/* storage for various magic items */
struct Library *OwnDevUnitBase;
static struct IOExtSer SerialRead;
static struct IOExtSer SerialWrite;
static struct MsgPort *SReadPort;
static struct MsgPort *SWritePort;
static ULONG SReadSigMask;
static ULONG SWriteSigMask;
static UBYTE SReadBuf[256];
static ULONG SReadPos;
static ULONG SReadSize;
static UBYTE SWriteBuf[256];
static ULONG SWritePos;
static STRPTR SerDevice;
static ULONG SerUnit;
/* open up the serial device */
BOOL OpenSerial(STRPTR Device, ULONG Unit, BOOL AttemptMode)
{
register struct IOExtSer *ior = &SerialRead;
register struct IOExtSer *iow = &SerialWrite;
STRPTR ODUresult;
/* save these away for when we need to close the device */
SerDevice = Device;
SerUnit = Unit;
/* allocate our message ports */
if (!(SReadPort = CreatePort(NULL, 0)))
return FALSE;
if (!(SWritePort = CreatePort(NULL, 0))) {
DeletePort(SReadPort);
return FALSE;
}
SReadSigMask = 1L << SReadPort->mp_SigBit;
SWriteSigMask = 1L << SWritePort->mp_SigBit;
/*
* if OwnDevUnit.library is around then use it to try and lock the
* port
*/
if (OwnDevUnitBase = OpenLibrary(ODU_NAME, 0)) {
if (AttemptMode)
ODUresult = AttemptDevUnit(Device, Unit, PROGNAME, 0L);
else
ODUresult = LockDevUnit(Device, Unit, PROGNAME, 0L);
if (ODUresult) {
CloseLibrary(OwnDevUnitBase);
DeletePort(SWritePort);
DeletePort(SReadPort);
return FALSE;
}
}
/* try and open the device */
ior->io_SerFlags = SERF_XDISABLED;
ior->IOSer.io_Message.mn_ReplyPort = SReadPort;
if (OpenDevice(Device, Unit, (struct IORequest *) ior, 0)) {
if (OwnDevUnitBase) {
FreeDevUnit(Device, Unit);
CloseLibrary(OwnDevUnitBase);
}
DeletePort(SWritePort);
DeletePort(SReadPort);
return FALSE;
}
ior->IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *) ior);
ior->io_Baud = 600;
ior->io_ReadLen = ior->io_WriteLen = 8;
ior->io_StopBits = 1;
ior->IOSer.io_Command = SDCMD_SETPARAMS;
if (DoIO((struct IORequest *) ior)) {
CloseSerial();
return FALSE;
}
CopyMem((APTR) ior, (APTR) iow, sizeof(struct IOExtSer));
iow->IOSer.io_Message.mn_ReplyPort = SWritePort;
SReadPos = SReadSize = 0;
return TRUE;
}
/* close down the serial handling stuff */
void CloseSerial(void)
{
CloseDevice((struct IORequest *) & SerialRead);
if (OwnDevUnitBase) {
FreeDevUnit(SerDevice, SerUnit);
CloseLibrary(OwnDevUnitBase);
}
DeletePort(SWritePort);
DeletePort(SReadPort);
}
/* flush out the serial read buffer */
void ClearSerial(void)
{
SReadPos = SReadSize = 0;
SerialRead.IOSer.io_Command = CMD_CLEAR;
DoIO((struct IORequest *) & SerialRead);
}
/* send a string to the serial device */
void SerWrite(STRPTR Buf, ULONG Len)
{
SerialWrite.IOSer.io_Command = CMD_WRITE;
SerialWrite.IOSer.io_Length = Len;
SerialWrite.IOSer.io_Data = (APTR) Buf;
DoIO((struct IORequest *) & SerialWrite);
}
/* get a character from the serial device with a timeout */
UWORD SerGetRawChar(ULONG timeout)
{
UBYTE Buffer[2];
ULONG Signals;
if (SReadPos < SReadSize)
return (UWORD) SReadBuf[SReadPos++];
SetSignal(0L, SReadSigMask | TimerSigMask);
SerialRead.IOSer.io_Command = CMD_READ;
SerialRead.IOSer.io_Length = 1;
SerialRead.IOSer.io_Data = (APTR) Buffer;
SendIO((struct IORequest *) & SerialRead);
TimerIO.tr_node.io_Command = TR_ADDREQUEST;
TimerIO.tr_time.tv_secs = timeout;
TimerIO.tr_time.tv_micro = 0;
SendIO((struct IORequest *) & TimerIO);
Signals = Wait(SReadSigMask | TimerSigMask);
if (Signals & SReadSigMask) {
if (!CheckIO((struct IORequest *) & TimerIO)) {
AbortIO((struct IORequest *) & TimerIO);
}
WaitIO((struct IORequest *) & TimerIO);
WaitIO((struct IORequest *) & SerialRead);
if (!SerialRead.IOSer.io_Error && SerialRead.IOSer.io_Actual) {
SerialRead.IOSer.io_Command = SDCMD_QUERY;
DoIO((struct IORequest *) & SerialRead);
if (SerialRead.IOSer.io_Actual) {
SerialRead.IOSer.io_Command = CMD_READ;
SerialRead.IOSer.io_Length = min(sizeof(SReadBuf), SerialRead.IOSer.io_Actual);
SerialRead.IOSer.io_Data = (APTR) SReadBuf;
DoIO((struct IORequest *) & SerialRead);
if (!SerialRead.IOSer.io_Error) {
SReadPos = 0;
SReadSize = SerialRead.IOSer.io_Actual;
}
}
return (UWORD) Buffer[0];
}
else
return 0;
}
if (Signals & TimerSigMask)
WaitIO((struct IORequest *) & TimerIO);
/* if we get down here we have timed out waiting for a character */
if (!CheckIO((struct IORequest *) & SerialRead)) {
AbortIO((struct IORequest *) & SerialRead);
}
WaitIO((struct IORequest *) & SerialRead);
return TIMEOUT;
}