home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
550b.lha
/
Term_v1.8a
/
Source.LZH
/
Serial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-11
|
10KB
|
527 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by Olaf 'Olsen' Barthel & MXM
*
* Name .....: Serial.c
* Created ..: Monday 21-Jan-91 20:12
* Revision .: 0
*
* Date Author Comment
* ========= ======== ====================
* 21-Jan-91 Olsen Created this file!
*
* $Revision Header ********************************************************/
#include "TermGlobal.h"
/* XOn():
*
* Perform XON (stop data flow).
*/
VOID
XOn()
{
if(Config . Handshaking == HANDSHAKING_XONXOFF)
Status = STATUS_HOLDING;
}
/* SerialCommand(UBYTE *String):
*
* Send a command string to the serial line and
* interprete the control sequences.
*/
VOID
SerialCommand(UBYTE *String)
{
LONG Count = 0,i;
BYTE GotControl = FALSE,GotEscape = FALSE;
BYTE OldStatus,BlockSet;
/* Scan the string. */
for(i = 0 ; i < strlen(String) ; i++)
{
/* We are looking for plain characters
* and the control ('\') and escape
* ('^') characters.
*/
if(!GotControl && !GotEscape)
{
/* Got a control character,
* the next byte will probably be
* a command sequence.
*/
if(String[i] == '\\')
{
GotControl = TRUE;
continue;
}
/* Got an escape character,
* the next byte will be some
* kind of control character
* (such as XON, XOF, bell, etc.).
*/
if(String[i] == '^')
{
GotEscape = TRUE;
continue;
}
/* This tells us to wait another
* second before continuing with
* the scanning.
*/
if(String[i] == '~')
{
if(Count)
{
SerWrite(SharedBuffer,Count);
Count = 0;
}
WaitTime(0,MILLION / 2);
HandleSerial();
continue;
}
/* Stuff the character into the
* buffer.
*/
SharedBuffer[Count++] = String[i];
}
else
{
/* Convert the character to a control
* style character (^C, etc.).
*/
if(GotEscape)
{
if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= 91)
SharedBuffer[Count++] = ToUpper(String[i]) - '@';
else
SharedBuffer[Count++] = String[i];
GotEscape = FALSE;
}
/* The next character represents a command. */
if(GotControl)
{
switch(ToUpper(String[i]))
{
/* Execute an AmigaDOS command. */
case 'D': if(!WeAreBlocking)
{
BlockSet = TRUE;
BlockWindows();
}
else
BlockSet = FALSE;
SendAmigaDOSCommand(&String[i + 1]);
if(BlockSet)
ReleaseWindows();
return;
/* Execute an ARexx command. */
case 'A': if(!WeAreBlocking)
{
BlockSet = TRUE;
BlockWindows();
}
else
BlockSet = FALSE;
SendARexxCommand(&String[i + 1]);
if(BlockSet)
ReleaseWindows();
return;
/* Add the control character ('\'). */
case '\\': SharedBuffer[Count++] = '\\';
break;
/* This is a backspace. */
case 'B': SharedBuffer[Count++] = '\b';
break;
/* This is a form feed. */
case 'F': SharedBuffer[Count++] = '\f';
break;
/* This is a line feed. */
case 'N': SharedBuffer[Count++] = '\n';
break;
/* Send the current password. */
case 'P': if(Password[0])
{
if(Count)
{
SerWrite(SharedBuffer,Count);
Count = 0;
}
SerWrite(Password,strlen(Password));
}
break;
/* This is a carriage return. */
case 'R': SharedBuffer[Count++] = '\r';
break;
/* This is a tab. */
case 'T': SharedBuffer[Count++] = '\t';
break;
/* Send a break across the serial line. */
case 'X': if(Count)
{
SerWrite(SharedBuffer,Count);
Count = 0;
}
if(WriteRequest)
{
OldStatus = Status;
Status = STATUS_BREAKING;
WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
DoIO(WriteRequest);
Status = OldStatus;
}
break;
/* Feed the contents of the
* clipboard into the input
* stream.
*/
case 'I': if(Count)
SerWrite(SharedBuffer,Count);
Count = LoadClip(SharedBuffer,256);
break;
/* Send a string to the clipboard. */
case 'G': if(String[i + 1])
SaveClip(&String[i + 1],strlen(&String[i + 1]));
return;
/* Produce the escape character. */
case 'E': SharedBuffer[Count++] = ESC;
break;
/* Stuff the character into the buffer. */
default: SharedBuffer[Count++] = String[i];
break;
}
GotControl = FALSE;
}
}
/* If the buffer is full, release it. */
if(Count == 256)
{
SerWrite(SharedBuffer,Count);
Count = 0;
}
}
if(Count)
SerWrite(SharedBuffer,Count);
}
/* SerWrite(APTR Buffer,LONG Size):
*
* Send a number of bytes across the serial line.
*/
VOID
SerWrite(APTR Buffer,LONG Size)
{
if(WriteRequest && Size)
{
/* xpr wants to see the data before it is
* transferred.
*/
if(TransferBits & XPRS_USERMON)
if(!(Size = XProtocolUserMon(XprIO,Buffer,Size,Size)))
return;
/* If full duplex is enabled, send the entire
* buffer.
*/
if(Config . Duplex == DUPLEX_FULL)
{
WriteRequest -> IOSer . io_Command = CMD_WRITE;
WriteRequest -> IOSer . io_Data = Buffer;
WriteRequest -> IOSer . io_Length = Size;
DoIO(WriteRequest);
}
else
{
UBYTE *ByteBuffer = Buffer;
/* Half duplex is enabled, send only
* a single character at a time.
*/
WriteRequest -> IOSer . io_Command = CMD_WRITE;
WriteRequest -> IOSer . io_Length = 1;
while(Size--)
{
WriteRequest -> IOSer . io_Data = ByteBuffer;
DoIO(WriteRequest);
ConProcess(ByteBuffer,1);
ByteBuffer++;
}
}
}
}
/* SetFlags(struct IOExtSer *SomeRequest):
*
* Set the contents of a serial device request according
* to the current configuration settings.
*/
VOID
SetFlags(struct IOExtSer *SomeRequest)
{
SomeRequest -> io_Baud = Config . BaudRate;
SomeRequest -> io_BrkTime = Config . BreakLength;
SomeRequest -> io_ReadLen = Config . BitsPerChar;
SomeRequest -> io_WriteLen = Config . BitsPerChar;
SomeRequest -> io_StopBits = Config . StopBits;
SomeRequest -> io_ExtFlags &= ~(SEXTF_MSPON|SEXTF_MARK);
SomeRequest -> io_SerFlags &= ~(SERF_PARTY_ON|SERF_PARTY_ODD|SERF_7WIRE|SERF_RAD_BOOGIE);
switch(Config . Parity)
{
case PARITY_EVEN: SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
break;
case PARITY_ODD: SomeRequest -> io_SerFlags |= SERF_PARTY_ON|SERF_PARTY_ODD;
break;
case PARITY_MARK: SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
SomeRequest -> io_ExtFlags |= SEXTF_MSPON|SEXTF_MARK;
break;
case PARITY_SPACE: SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
SomeRequest -> io_ExtFlags |= SEXTF_MSPON;
break;
default: break;
}
if(Config . Handshaking == HANDSHAKING_RTSCTS)
SomeRequest -> io_SerFlags |= SERF_7WIRE;
if(Config . HighSpeed)
SomeRequest -> io_SerFlags |= SERF_RAD_BOOGIE;
SomeRequest -> io_SerFlags |= SERF_XDISABLED;
}
/* SetParameters():
*
* Set the parameters for both serial requests and the
* serial line.
*/
VOID
SetParameters()
{
if(WriteRequest)
{
WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
SetFlags(WriteRequest);
SetFlags(ReadRequest);
DoIO(WriteRequest);
}
}
/* FlushSerial():
*
* Terminate all read/write activity on the serial
* line.
*/
VOID
FlushSerial()
{
if(ReadPort)
{
if(!CheckIO(ReadRequest))
AbortIO(ReadRequest);
WaitIO(ReadRequest);
GetMsg(ReadRequest -> IOSer . io_Message . mn_ReplyPort);
WriteRequest -> IOSer . io_Command = CMD_CLEAR;
DoIO(WriteRequest);
}
}
/* DeleteSerial():
*
* Close the serial device and release all associated
* resources.
*/
VOID
DeleteSerial()
{
BYTE Closed = FALSE;
if(ReadBuffer)
{
FreeMem(ReadBuffer,1024);
ReadBuffer = NULL;
}
if(ReadRequest)
{
if(ReadRequest -> IOSer . io_Device)
{
ReadRequest -> IOSer . io_Command = CMD_RESET;
DoIO(ReadRequest);
CloseDevice(ReadRequest);
Closed = TRUE;
}
if(ReadRequest -> IOSer . io_Message . mn_ReplyPort)
DeleteMsgPort(ReadRequest -> IOSer . io_Message . mn_ReplyPort);
DeleteIORequest(ReadRequest);
ReadRequest = NULL;
}
if(WriteRequest)
{
if(WriteRequest -> IOSer . io_Device && !Closed)
{
WriteRequest -> IOSer . io_Command = CMD_RESET;
DoIO(WriteRequest);
CloseDevice(WriteRequest);
}
if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
DeleteIORequest(WriteRequest);
WriteRequest = NULL;
}
ReadPort = NULL;
}
/* CreateSerial():
*
* Create handles for the serial device and open it.
*/
BYTE
CreateSerial()
{
struct MsgPort *WritePort;
if(ReadBuffer = AllocMem(1024,MEMF_PUBLIC))
{
if(ReadPort = (struct MsgPort *)CreateMsgPort())
{
if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
{
SetFlags(ReadRequest);
ReadRequest -> io_RBufLen = 8000;
if(!OpenDevice(Config . SerialDevice,Config . UnitNumber,ReadRequest,0))
{
if(WritePort = (struct MsgPort *)CreateMsgPort())
{
if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
{
CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
SetParameters();
ReadRequest -> IOSer . io_Command = CMD_READ;
ReadRequest -> IOSer . io_Data = ReadBuffer;
ReadRequest -> IOSer . io_Length = 1;
SendIO(ReadRequest);
return(TRUE);
}
}
}
}
}
}
return(FALSE);
}