thomas@utah-gr.UUCP (Spencer W. Thomas) (09/23/86)
A recent article in the Delphi digest asked for working code using the serial drivers. Here is some code that (at least used to -- I haven't tried it since I upgraded to the 128K roms) work for me. It is written in SUMACC, but should be close to whatever you are using. Since these are fragments of a larger program, there are undefined routines referenced, but I think everything necessary to use the serial lines is here. Good luck! First I open the serial driver #define sPortA 0 int XL_outRefNum, XL_inRefNum; if ( RomSDOpen( sPortA ) < 0 ) ... appropriate error code ... (Actually, I followed this by attempting to open the RAM driver.) RomSDOpen( sPort ) int sPort; { XL_outRefNum = OpenDriver( ".AOut" ); if ( XL_outRefNum == 0 ) return -1; XL_inRefNum = OpenDriver( ".AIn" ); if ( XL_inRefNum == 0 ) return -1; return 0; } Then I set up the communications parameters: int XL_baud = baud9600; char * XL_serBuffer; struct SerShk shk; SerReset( XL_inRefNum, XL_baud | stop10 | noParity | data8 ); SerReset( XL_outRefNum, XL_baud | stop10 | noParity | data8 ); if ( XL_serDriver ) /* If RAM driver open succeeded */ { shk.fXOn = 1; /* Do XON/XOFF Flow control */ shk.fCTS = 0; /* No CTS Flow control */ shk.xOn = '\21'; /* Control Q */ shk.xOff = '\23'; /* Control S */ shk.fInX = 1; /* Generate Xon/Xoff flow control */ } else { shk.fXOn = 0; /* no Flow control */ shk.fCTS = 0; /* at all */ shk.fInX = 0; } shk.errs = 0; /* Ignore errors */ shk.evts = 0; /* No events */ SerHShake( XL_inRefNum, &shk ); SerHShake( XL_outRefNum, &shk ); /* Create a big buffer so we don't lose anything */ if ( XL_serBuffer == NIL ) { XL_serBuffer = NewPtr( XL_serBufSize ); SerSetBuf( XL_inRefNum, XL_serBuffer, XL_serBufSize ); } } Here is the input code. This routine should be called frequently enough to keep the serBuffer from filling up between calls. The testFlag argument was added to permit other events to "get in" even if the serial line was receiving like mad. My top loop gave preference to serial input over other events, so needed some way to break out every so often. /* * Simulate getchar() from serial line. Return -1 if nothing there. * If testFlag is TRUE, just see if there's any more in the internal * buffer. */ static char SGBuffer[256]; static int SGptr, SGsize = 0; XL_SerGetChar(testFlag) { int count, err; if ( SGsize > 0 && SGptr < SGsize ) return SGBuffer[SGptr++] & 0x7f; /* strip parity */ if ( testFlag ) return -1; /* Check for more available */ SerGetBuf( XL_inRefNum, &SGsize ); if ( SGsize > 0 ) { if ( SGsize > sizeof SGBuffer ) SGsize = sizeof SGBuffer; if ( (err = FSRead( XL_inRefNum, &SGsize, SGBuffer )) < 0 ) { XL_Error( "Read error", err ); SGsize = 0; } else { SGptr = 1; return SGBuffer[0] & 0x7f; /* strip parity */ } } return -1; /* Nothing there */ } And, of course, output code. /* Put a string to the serial line */ XL_SerPutBuf( buf, len ) char *buf; int len; { int err, wrlen; while ( len > 0 ) { wrlen = len; if ( (err = FSWrite( XL_outRefNum, &wrlen, buf )) < 0 || wrlen == 0 ) { XL_Error( "Serial Write Error, Code=", err ); return; } len -= wrlen; } } -- =Spencer ({ihnp4,decvax}!utah-cs!thomas, thomas@utah-cs.ARPA)