KPURCELL@LIVERPOOL.AC.UK (09/21/90)
Below is the text of a program that we wrote to find out why a piece of code
written by a consultant wouldn't correctly control the serial port. We have
since written some code to do the same stuff (that works :-) using the serial
manager.
Firstly, the
open(Q1, 'modem:');
THINK Pascal considers the printer port as write-only and the modem port as
read-write (this is mentioned in the Language Reference 9.5 on page 321-322).
But when you open the modem: port for I/O, the I/O actually
happens on the PRINTER port for I/O. Opening the printer: won't allow reading
that port (hey, the printer is a write-only device, right) but the written
output comes out of the physical MODEM port.
The upshot of this is:
1. We can't use Appletalk, if we want to do serial I/O.
2. We are very confused why the ports in the program don't correspond to
the right miniDINs on the mac.
A secondary problem is that when you send a CR (CHAR(ORD(13))) out of the port
the device actually sends a CR/LF pair. On reading a CR/LF the port returns
a space for the CR character and a ORD(13) for the LF.
Final problem. We tried a loopback (output of a port goes to input of a
port) and write and read almost simultaneously then it seems to drop
characters, whereas a routine using the Serial Drivers and FSRead/FSWrite
has no problems.
So the final question is: is this a known bug or, perhaps more likely, are we
doing something really stupid? Take a look at the code below. I have RTFM but
couldn't find anything relevant.
Does it have anything to do with mixing Pascal TEXT I/O and the Serial Driver
routines? (sinking feeling :-)
This started as a quick "oh we'll do it this way to save some time" hack,
but we've ended up doing it properly (with the drivers and the File Manager) in
the end after wasting a couple of days chasing the problem.
Thanks for any assistance,
Kevin
Kevin Purcell | kpurcell@liverpool.ac.uk
Surface Science, |
Liverpool University | Programming the Macintosh is easy if you understand
Liverpool L69 3BX | how the Mac works and hard if you don't. -- Dan Allen
------------------------ program follows ------------------------------
{Lest it destroy my credibility I *didn't* write this! -kgp}
program bull;
var
Event, h, i: integer;
q1: text;
p: char;
l: longint;
SerAshk: SerShk;
SerASta: SerStaRec;
evnt: eventrecord;
Done: boolean;
GrowLimit, DragLimit: rect;
FirstClick: longint;
window, txw, drw: WindowPtr;
pnt: point;
stn: str255;
procedure HandleKey;
var
ch: char;
j: integer;
begin
Evnt.Message := BitAnd(Evnt.Message, $FF);
ch := Chr(Evnt.Message);
setport(drw);
GetPen(pnt);
write(q1, ch);
writedraw(ch);
end;
procedure HandleMouse;
var
part: integer;
newSize: longint;
begin
part := FindWindow(Evnt.Where, window);
if window = nil then
exit(handleMouse);
if window <> FrontWindow then
SelectWindow(window);
case part of
InGrow:
begin
newSize := GrowWindow(Window, Evnt.Where, GrowLimit);
if newSize <> 0 then
SizeWindow(Window, LoWord(newsize), HiWord(newsize), TRUE);
end;
indrag:
if TickCount > (FirstClick + GetDblTime) then
begin
FirstClick := TickCount;
DragWindow(window, Evnt.where, DragLimit);
end;
ingoaway:
done := true;
otherwise
end
end;
begin
Done := false;
SetRect(GrowLimit, 80, 80, 512, 322);
SetRect(DragLimit, 50, 20, 512, 250);
FirstClick := 0;
showdrawing;
getport(drw);
showtext;
getport(txw);
moveto(0, 12);
open(Q1, 'modem:');
for i := -20 to 0 do
if SerGetBuf(i, l) = 0 then
leave;
if i >= 0 then
Writeln('find failed');
if SerReset(i, $4c0a) <> 0 then
writeln('speed failed');
with SerAshk do
begin
fxon := 0;
finx := 0;
errs := $70;
fcts := 1;
end;
writeln(SerHshake(i, SerAshk));
writeln(SerStatus(i, SerASta));
writeln(SerASta.ctshold);
writeln('ref:=', i : 4, ' ', l : 4, ' bytes in buffer');
WRITE(Q1, 'CD/0/', CHR(13), 'X');
WRITE(Q1, 'AB/', CHR(13), 'X');
repeat
systemtask;
if GetNextEvent(EveryEvent, Evnt) then
case Evnt.What of
KeyDown, AutoKey:
HandleKey;
MouseDown:
HandleMouse;
otherwise
end;
if SerGetBuf(i, l) = 0 then
if l > 0 then
begin
read(q1, p);
setport(txw);
selectwindow(txw);
GetPen(pnt);
if ORD(P) = 10 then
WRITELN
else
WRITE(P);
end;
until done;
close(q1);
end.