-- BrucePacket.mesa
-- last edited by Barth, October 23, 1981 3:06 PM
-- last edited by Brotz, December 24, 1981 4:01 PM
-- last edited by Chi Yung Fu, September 1, 1983 11:27 AM

DIRECTORY
BruceDefs,
InlineDefs,
PupStream,
Stream;

BrucePacket: PROGRAM
IMPORTS InlineDefs, PupStream, Stream
EXPORTS BruceDefs =
BEGIN

CommFailure: PUBLIC ERROR = CODE;

Synch:BruceDefs.Byte = 26B; -- 16 synch
loadAck:BruceDefs.Byte = 203B; -- 83 Operation Load Acknowledge
sequencerAck:BruceDefs.Byte = 206B; -- 86 Sequencer Command Acknowledge
requestBuffer:BruceDefs.Byte = 302B; -- C2 Request Long Packet (Buffer)
bufferA:BruceDefs.Byte = 12B; -- 0A operation buffer number
storeOperation:BruceDefs.Byte = 303B; -- C3 Long Operation Transfer
sequencer:BruceDefs.Byte = 306B; -- C6 Sequencer Command
ACK:BruceDefs.Byte = 252B; -- AA acknowledge value
alarm: BruceDefs.Byte = 1B; -- 01 Acknowledge Alarm
abort: BruceDefs.Byte = 2B; -- 02 Abort Cycle
start: BruceDefs.Byte = 3B; -- 03 Start Cycle
reset: BruceDefs.Byte = 4B; -- 04 Reset DDC ** No Response **

Buffer: TYPE = PACKED ARRAY BufferIndex OF MACHINE DEPENDENT RECORD[
lower(0:8..15):BruceDefs.Byte,
upper(0:0..7):BruceDefs.Byte];
BufferIndex: TYPE = [1..404];
BufferPtr: TYPE = POINTER TO Buffer;
tubeHandle: Stream.Handle;
tubeAddress: PupStream.PupAddress;
connectionOpen: BOOLEAN ← FALSE;
currentTube: BruceDefs.TubeNumber;

Initialize: PUBLIC PROCEDURE=
BEGIN
connectString: STRING ← "Octopus+200030"L;
PupStream.PupPackageMake[];
PupStream.GetPupAddress[@tubeAddress,connectString
! PupStream.PupNameTrouble => ERROR CommFailure];
END; -- of Initialize

Terminate: PUBLIC PROCEDURE=
BEGIN
ENABLE BEGIN
PupStream.StreamClosing => ERROR CommFailure;
Stream.TimeOut => ERROR CommFailure;
END;
IF connectionOpen THEN BEGIN
Stream.Delete[tubeHandle ! PupStream.StreamClosing => ERROR CommFailure];
connectionOpen ← FALSE;
END;
PupStream.PupPackageDestroy[];
END; -- of Terminate

DownLoad: PUBLIC PROCEDURE [tube:BruceDefs.TubeNumber,
brp:BruceDefs.RecipePtr]=
BEGIN
ENABLE BEGIN
PupStream.StreamClosing => ERROR CommFailure;
Stream.TimeOut => ERROR CommFailure;
END;
bp:BufferPtr ← LOOPHOLE[brp];
check:CARDINAL ← 0;
OpenConnection[tube];
PutHeader[storeOperation,1];
FOR i:BufferIndex IN BufferIndex DO
check ← check+bp[i].lower+bp[i].upper;
Stream.PutByte[tubeHandle, bp[i].lower];
Stream.PutByte[tubeHandle, bp[i].upper];
ENDLOOP;
Stream.PutByte[tubeHandle, check];
SendItNow[];
CheckResponse[loadAck,1,ACK];
END; -- of DownLoad

UpLoad: PUBLIC PROCEDURE [tube:BruceDefs.TubeNumber,
brp:BruceDefs.RecipePtr]=
BEGIN
ENABLE BEGIN
PupStream.StreamClosing => ERROR CommFailure;
Stream.TimeOut => ERROR CommFailure;
END;
bp:BufferPtr ← LOOPHOLE[brp];
check:CARDINAL ← 0;
OpenConnection[tube];
PutHeader[requestBuffer, bufferA];
SendItNow[];
CheckResponse[bufferA, (LAST[BufferIndex]*2) MOD 256,
(LAST[BufferIndex]*2) / 256];
FOR i:BufferIndex IN BufferIndex DO
bp[i].lower ← Stream.GetByte[tubeHandle];
bp[i].upper ← Stream.GetByte[tubeHandle];
check ← check+bp[i].lower+bp[i].upper;
ENDLOOP;
IF InlineDefs.BITAND[check,377B]#Stream.GetByte[tubeHandle] THEN
ERROR CommFailure;
END; -- of UpLoad

Command: PUBLIC PROCEDURE [tube:BruceDefs.TubeNumber,
command:BruceDefs.CommandType]=
BEGIN
ENABLE BEGIN
PupStream.StreamClosing => ERROR CommFailure;
Stream.TimeOut => ERROR CommFailure;
END;
c:BruceDefs.Byte ← SELECT command FROM
AckAlarm => alarm,
Abort => abort,
Start => start,
ENDCASE => reset;
OpenConnection[tube];
PutHeader[sequencer,c];
SendItNow[];
IF command#Reset THEN CheckResponse[sequencerAck,c,ACK];
END; -- of Command

OpenConnection: PROCEDURE [tube:BruceDefs.TubeNumber]=
BEGIN
IF connectionOpen AND currentTube=tube THEN RETURN;
IF connectionOpen THEN Stream.Delete[tubeHandle];
tubeAddress.socket.b ← InlineDefs.BITAND[177770B,tubeAddress.socket.b] +
(tube-1);
tubeHandle ← PupStream.PupByteStreamCreate[remote:tubeAddress,
ticks: PupStream.SecondsToTocks[30]];
connectionOpen ← TRUE;
currentTube ← tube;
END; -- of Command

CheckResponse: PROCEDURE [c:BruceDefs.Byte, a1:BruceDefs.Byte,
a2:BruceDefs.Byte]=
BEGIN
IF Stream.GetByte[tubeHandle]#Synch THEN ERROR CommFailure;
IF Stream.GetByte[tubeHandle]#Synch THEN ERROR CommFailure;
IF Stream.GetByte[tubeHandle]#c THEN ERROR CommFailure;
IF Stream.GetByte[tubeHandle]#a1 THEN ERROR CommFailure;
IF Stream.GetByte[tubeHandle]#a2 THEN ERROR CommFailure;
IF Stream.GetByte[tubeHandle]#LOOPHOLE[(Synch+Synch+c+a1+a2) MOD 256]
THEN ERROR CommFailure;
END; -- of CheckResponse

PutHeader: PROCEDURE[c:BruceDefs.Byte, a1:BruceDefs.Byte ← 0,
a2:BruceDefs.Byte ← 0]=
BEGIN
Stream.PutByte[tubeHandle,26B];
Stream.PutByte[tubeHandle,26B];
Stream.PutByte[tubeHandle,c];
Stream.PutByte[tubeHandle,a1];
Stream.PutByte[tubeHandle,a2];
Stream.PutByte[tubeHandle,LOOPHOLE[(26B+26B+c+a1+a2) MOD 256]];
END; -- of PutHeader

SendItNow: PROCEDURE=
BEGIN
Stream.SendNow[tubeHandle];
END; -- of SendItNow

END.