harrow@exodus.dec.com (Jeff Harrow, NCSE LKG1-3/F16 DTN=226-7445) (10/22/86)
I'm in the process of going bananas over an attempt to get the Serial Driver to behave in a reasonable manner. Here are some code fragments and explainations of what I'm doing and what I (hah!) expect: In my globals I allocate: {----------------------------------------------------------------------} LargeModemBuffer : packed array[1..2000] of Char; {Special large buffer for Modem} {----------------------------------------------------------------------} Then, I initialize the RAM Serial Driver by calling the following function (which does NOT return an error) {----------------------------------------------------------------------} function InitModem; {: OSErr} {Initializes the modem for operation} var HS : SerShk; Result : OSErr; begin Result := noErr; {Init to NO error} Result := RAMSDOpen(sPortA); Result := SerReset(-7, baud1200 + noParity + stop10 + data8); Result := SerReset(-6, baud1200 + noParity + stop10 + data8); Result := SerSetBuf(-6, @LargeModemBuffer, SizeOf(LargeModemBuffer)); {Use a large buffer allocated in the Globals unit on stack} HS.fxOn := 0; HS.fInX := 1; {Turn ON XON/XOFF flow control OF host data} HS.xOn := chr(17); HS.xoff := chr(19); HS.fCTS := 0; HS.errs := 0; HS.evts := 0; Result := SerHShake(-6, HS); Result := SerHShake(-7, HS); InitModem := Result; {Function return value} end; {InitModem function} {----------------------------------------------------------------------} I now expect the Driver to utilize CTRL/Q and CTRL/S (XON-XOFF) flow control on input (to the Mac) received from the host). I now get SOME of the characters that have been received and supposedly placed into LargeModemBuffer by {----------------------------------------------------------------------} VAR theChars : StringPtr; CharsInModem : LongInt; err := SerStatus(-6, SerialErrors); {Get input buffer state} if SerialErrors.cumErrs <> 0 then {Test for errors...} begin SysBeep(1); Writeln; Writeln('***SerialErrors = ', ord(SerialErrors.cumErrs)); end; err := SerGetBuf(-6, CharsInModem); {How many characters are there to get?} if err <> noErr then SysBeep(1); if CharsInModem > 0 then {If we DID find there were some to get...} begin New(theChars); {We need a buffer} err := FSRead(-6, CharsInModem, pointer(theChars)); {Get them} if err <> noErr then SysBeep(1); BlockMove(pointer(ord(@CharsInModem) + 3), @RawText, Longint(1)); {Put Length byte into String} BlockMove(pointer(theChars), pointer(ord(@RawText) + 1), size(CharsInModem)); {Put text into String} RawText := concat(RemainderText, RawText); {Add in any text that was after CR from last loop} {----------------------------------------------------------------------} after which I have whatever data has been received to date in RawText. Now, I go off and do some lengthy processing, expecting that the Driver will, in the background, collect whatever characters come over the port and put them into LargeModemBuffer, using XON/XOFF to keep the host from causing a HARDWARE overrun in the SCC chip, and knowing that it is NOT POSSIBLE for more than 2000 characters (the size of LargeModemBuffer) to come in while I'm gone (there isn't enough time!), which would generate a SOFTWARE OVERRUN. Well, at 1200 baud, 99% of the time all is well, things get received as expected, and I don't get a beep from SerStatus routine (which checks for various errors in the Serial driver). HOWEVER, when I boost things to 2400 baud, I get quite a few beeps there, and the error returned is SerialErrors.cumErrs = 1 (SOFTWARE OVERRUN)!!!!!!!! How is this possible? Am I expecting something inappropriate? Also, is the Serial driver smart enough to STOP writing characters beyond the end of LargeModemBuffer just in case it DOES get overrun? Something is fishy here, (and from experience I suspect I've missed some "truth"), but I can't seem to pin down what's going wrong. Any ideas? Thanks in advance, Jeff Harrow