/*--------------------------------------------------------------*/ /* SerialIO.c: Amiga Serial I/O Device Routines */ /* Created: June 1986 by J.A. Lydiatt */ /* */ /* Note: */ /* A Task may only open the serial port once. */ /*--------------------------------------------------------------*/ #include #include #include #include #include /* Allowable Mode Values */ #define MODEHALF 0 #define MODEFULL 1 #define MODEECHO 2 /* Default starting values */ #define STARTBAUD 1200 /* default baud rate */ #define STARTMODE MODEFULL #define SERFLAGS (SERF_SHARED | SERF_XDISABLED) #define CTLCHAR 0x11130501 static int Mode = STARTMODE; static int amClosing = FALSE; /* declarations for the serial stuff */ static struct IOExtSer *Read_Request = NULL; static UBYTE rs_in[2]; static struct IOExtSer *Write_Request = NULL; static UBYTE rs_out[2]; /* stack to save Serial Port flags */ #define MAXSTACK 10 static int stackSize = 0; static int modeStack[ MAXSTACK ]; static UBYTE flagStack[ MAXSTACK ]; /*------------------------------------------------------------*/ /* GetSerialSigBit: return Read_Request's Signal Bit */ /*------------------------------------------------------------*/ int GetSerialSigBit() { return Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit; } /*------------------------------------------------------------*/ /* CheckSerIO : return TRUE if serial port has a character */ /*------------------------------------------------------------*/ BOOL CheckSerIO() { return (BOOL)( CheckIO( Read_Request ) != NULL); } /*------------------------------------------------------------*/ /* FlushSerIO: Flush the receive buffer */ /*------------------------------------------------------------*/ void FlushSerIO() { register struct IOExtSer *r = Read_Request; AbortIO( r ); /* abort it */ AbortIO( Write_Request ); r->IOSer.io_Command = CMD_FLUSH; DoIO( r ); /* flush all IO requests */ r->IOSer.io_Command = CMD_CLEAR; DoIO( r); /* flush receive buffer */ if ( !amClosing ) { Read_Request->IOSer.io_Command = CMD_READ; BeginIO( r ); /* start receive request */ } } /*------------------------------------------------------------*/ /* PushSerState: save current io flags */ /*------------------------------------------------------------*/ void PushSerState() { register struct IOExtSer *r = Read_Request; if ( stackSize < MAXSTACK ) { /* Save the current Mode */ modeStack[ stackSize ] = Mode; /* Get the current flags */ AbortIO( r ); flagStack[ stackSize++ ] = r->io_SerFlags; BeginIO( r ); } } /*------------------------------------------------------------*/ /* PullSerState: restore last saved flag state */ /*------------------------------------------------------------*/ void PullSerState() { register struct IOExtSer *r = Read_Request; if ( stackSize > 0 ) { /* Reset the Mode */ Mode = modeStack[ --stackSize ]; /* Set the old flags */ AbortIO( r ); r->io_SerFlags = flagStack[ stackSize ]; r->IOSer.io_Command = SDCMD_SETPARAMS; DoIO( r ); r->IOSer.io_Command = CMD_READ; BeginIO( r ); } } /*-------------------------------------------------------------*/ /* CloseSerialIO: Close the serial port */ /*-------------------------------------------------------------*/ void CloseSerialIO() { register struct IOExtSer *r = Read_Request; register struct IOExtSer *w = Write_Request; if ( r != NULL ) { amClosing = TRUE; CloseDevice( r ); DeletePort( r->IOSer.io_Message.mn_ReplyPort ); FreeMem( r, (long)sizeof( struct IOExtSer ) ); Read_Request = NULL; } if ( w != NULL ) { CloseDevice( w ); DeletePort( w->IOSer.io_Message.mn_ReplyPort ); FreeMem( w, (long)sizeof( struct IOExtSer ) ); Write_Request = NULL; } } /*-------------------------------------------------------------*/ /* InitSerialIO: Open serial IO - return read Port */ /*-------------------------------------------------------------*/ struct IOExtSer *InitSerialIO() { register struct IOExtSer *r, *w; if ( Read_Request != NULL ) { fprintf( stderr, "Error: Serial Port already open for read.\n"); return NULL; } r = (struct IOExtSer *) AllocMem( (long)sizeof(struct IOExtSer), (long)(MEMF_PUBLIC|MEMF_CLEAR)); if (r == NULL) return NULL; Read_Request = r; r->io_SerFlags = SERFLAGS; r->io_CtlChar = CTLCHAR; r->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",NULL); if(OpenDevice(SERIALNAME,NULL,r,NULL)) { fprintf( stderr, "Can't open Read device\n"); goto q4; } r->io_Baud = STARTBAUD; r->io_ReadLen = 8; r->io_WriteLen = 8; r->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(r); r->IOSer.io_Command = CMD_READ; r->IOSer.io_Length = 1; r->IOSer.io_Data = (APTR)&rs_in[0]; if ( Write_Request != NULL ) { fprintf( stderr, "Error: Serial Port already open for writing.\n"); goto q3; } w = (struct IOExtSer *)AllocMem( (long)sizeof( struct IOExtSer ), (long)MEMF_PUBLIC|MEMF_CLEAR); if (w == NULL) goto q3; Write_Request = w; w->io_SerFlags = SERFLAGS; w->io_CtlChar = CTLCHAR; w->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",NULL); if(OpenDevice(SERIALNAME,NULL,w,NULL)) { fprintf( stderr, "Can't open Write device\n"); goto q1; } w->io_Baud = STARTBAUD; w->io_ReadLen = 8; w->io_WriteLen = 8; w->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(w); w->IOSer.io_Command = CMD_WRITE; w->IOSer.io_Length = 1; w->IOSer.io_Data = (APTR)&rs_out[0]; BeginIO( r ); stackSize = 0; return r; q1: DeletePort( w->IOSer.io_Message.mn_ReplyPort ); q2: FreeMem( w, (long)sizeof( *w) ); q3: CloseDevice( r ); q4: DeletePort( r->IOSer.io_Message.mn_ReplyPort ); q5: FreeMem( r, (long)sizeof( *r) ); return NULL; } /*----------------------------------------------------------*/ /* SetXonMode: set Xon On or Off */ /*----------------------------------------------------------*/ void SetXonMode( status ) BOOL status; { register UBYTE flags; register struct IOExtSer *r = Read_Request; /* Get the current flags */ AbortIO( r ); flags = r->io_SerFlags; if ( status ) flags &= ~(SERF_XDISABLED); else flags |= SERF_XDISABLED; r->io_SerFlags = flags; r->IOSer.io_Command = SDCMD_SETPARAMS; DoIO( r ); r->IOSer.io_Command = CMD_READ; BeginIO( r ); } /*----------------------------------------------------------*/ /* SetSerBaud: set Serial Baud Rate */ /*----------------------------------------------------------*/ void SetSerBaud( baud ) int baud; { register struct IOExtSer *r = Read_Request; /* Get the current flags */ AbortIO( r ); r->io_Baud = baud; r->IOSer.io_Command = SDCMD_SETPARAMS; DoIO( r ); r->IOSer.io_Command = CMD_READ; BeginIO( r ); } /*----------------------------------------------------------*/ /* SetSerMode: set the Serial Mode */ /*----------------------------------------------------------*/ void SetSerMode( mode ) int mode; { Mode = mode; } /*----------------------------------------------------------*/ /* SerIOWrite: Write a byte out the serial port (no echo) */ /*----------------------------------------------------------*/ void SerIOWrite( c ) register UBYTE c; { *rs_out = c; DoIO( Write_Request ); } /*----------------------------------------------------------*/ /* SerIORead: read a byte from the serial port (no echo) */ /*----------------------------------------------------------*/ UBYTE SerIORead() { register struct IOExtSer *r = Read_Request; register UBYTE c; WaitIO( r ); c = *rs_in; BeginIO( r ); return c; }