Path: utzoo!attcan!uunet!portal!cup.portal.com!chrisj
From: chrisj@cup.portal.com
Newsgroups: comp.sys.mac.programmer
Subject: Re: Serial Ports
Message-ID: <9450@cup.portal.com>
Date: 25 Sep 88 23:21:58 GMT
References: <746@paris.ics.uci.edu>
Organization: The Portal System (TM)
Lines: 52
XPortal-User-Id: 1.1001.2041

W.r.t. Message-ID: <746@paris.ics.uci.edu>, here are a few thoughts on
Greg Finnegan's (finnegan@bonnie.ics.uci.edu) problem of driving a serial
output device which requires prompt attention to its deassertion of CTS:

Consider the following possible sequence of events:

Byte 0 has been transmitted completely to your device.  The output data
register (o.d.r.) of the Serial Communications Chip (SCC) became empty,
so the driver deposited byte 1 into it, and returned from your second
FSWrite.  Byte 1 is now on its way through the SCC's shift register, the
cable, and the printer's receiving hardware, to the printer.

You return to the top of the FOR loop, find that ctsHold is still 0, and
issue another FSWrite, for byte number 2.  While byte 1 is on its way out,
the serial driver loops until two conditions are true simultaneously: the
o.d.r. must be empty, and CTS must be true.  While the driver is busy-
waiting for this condition, the device decides that it doesn't want any
more characters for a while, so it makes CTS false, and the change of state
propagates along the cable to your Mac (taking non-zero time which depends
on the cable's length and transmission characteristics (capacitance etc),
but is probably much less than the time to send a byte out through the SCC).

Your Mac will now stay in that loop in the serial driver until the device
once again asserts CTS.

====

I suggest the following:

1.  Trust the serial driver NOT to send out characters while CTS is
false: don't try to second-guess the system software unless you KNOW
it's buggy.  (I assume that you call SerHShake to enable hardware
handshaking.)

2.  If you want to get control back after the write even if it does
not complete promptly, use the Asynch option of the low-level call,
PBWrite (@myParamBlk, TRUE), then loop until either the write operation
completes (myParamBlk.ioResult <> 1), or serSta.ctsHold becomes non-0,
whichever happens first.

Since you exit the procedure if the device drops CTS, myParamBlk must NOT
be a local variable of the procedure:  it must stay around until either
1) the operation completes, or 2) you issue a PBKillIO.  Don't change the
contents of the buffer pointed to by myParamBlk.ioBuffer, either.

You could even do a single asynchronous PBWrite for many bytes, and
put a check for either the completion of the write or the deassertion
of CTS, whichever comes first, into your event loop.

Christopher Jewell  chrisj@cup.portal.com  sun!cup.portal.com!chrisj
"I figure the people who close zoos at night know what they're doing."
                        Mike Royko (on night baseball at Wrigley Field)