-- File: PupChecksums.mesa, Last Edit: HGM October 15, 1980 7:37 PM
DIRECTORY
PrincOps USING [aCHKSUM, zMISC, zPOP, zADD, zDADD, zEXCH, zDUP, zLI0],
AltoRam USING [PupChecksum],
PupRouterDefs USING [Checksum],
CommUtilDefs USING [thisIsAnAlto],
BufferDefs USING [PupBuffer];
PupChecksums: PROGRAM IMPORTS AltoRam EXPORTS PupRouterDefs =
BEGIN
checksum: PUBLIC PupRouterDefs.Checksum ←
IF CommUtilDefs.thisIsAnAlto THEN software ELSE princOps;
ShortenData: PROCEDURE [LONG POINTER] RETURNS [POINTER] = MACHINE CODE
BEGIN PrincOps.zPOP; END;
ComputeD0Checksum: PROCEDURE [cs: CARDINAL, nWords: CARDINAL, p: LONG POINTER]
RETURNS [CARDINAL] = MACHINE CODE
BEGIN PrincOps.zMISC, PrincOps.aCHKSUM; END;
OnesComplementAddAndCycle: PROCEDURE [a, b: LONG UNSPECIFIED]
RETURNS [UNSPECIFIED] = MACHINE CODE
BEGIN
PrincOps.zDADD;
PrincOps.zADD; -- Ones add if a+b are in CARDINAL range
PrincOps.zDUP;
PrincOps.zLI0;
PrincOps.zEXCH;
PrincOps.zLI0; -- Make LONG again
PrincOps.zDADD;
PrincOps.zADD;
END;
SetPupChecksum: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] =
BEGIN
size: CARDINAL ← (b.pupLength - 1)/2;
checksumLoc: LONG POINTER ← @b.pupLength + size;
cs: CARDINAL;
SELECT checksum FROM
princOps =>
BEGIN checksumLoc^ ← ComputeD0Checksum[0, size, @b.pupLength]; END;
alto =>
BEGIN
where: POINTER ← ShortenData[@b.pupLength];
checksumLoc^ ← AltoRam.PupChecksum[0, where, size];
END;
none => BEGIN checksumLoc^ ← 177777B; END;
software =>
BEGIN
p: LONG POINTER TO ARRAY [0..0) OF WORD = LOOPHOLE[@b.pupLength];
cs ← 0;
FOR i: CARDINAL IN [0..size) DO
cs ← OnesComplementAddAndCycle[p[i], cs]; ENDLOOP;
IF cs = 177777B THEN cs ← 0;
checksumLoc^ ← cs;
END;
ENDCASE => NULL;
END;
TestPupChecksum: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] RETURNS [BOOLEAN] =
BEGIN
size: CARDINAL ← ((LOOPHOLE[b.pupLength - 1, CARDINAL])/2);
checksumLoc: LONG POINTER ← @b.pupLength + size;
cs: CARDINAL;
IF checksumLoc^ = 177777B THEN RETURN[TRUE];
SELECT checksum FROM
princOps =>
BEGIN
-- BEWARE: The stack must be empty. Dont try RETURN[xx^=PupChecksum[xxx]];
cs ← ComputeD0Checksum[0, size, @b.pupLength];
END;
alto =>
BEGIN
where: POINTER ← ShortenData[@b.pupLength];
-- BEWARE: The stack must be empty. Dont try RETURN[xx^=PupChecksum[xxx]];
cs ← AltoRam.PupChecksum[0, where, size];
END;
none => BEGIN RETURN[TRUE]; END;
software =>
BEGIN
p: LONG POINTER TO ARRAY [0..0) OF WORD = LOOPHOLE[@b.pupLength];
cs ← 0;
FOR i: CARDINAL IN [0..size) DO
cs ← OnesComplementAddAndCycle[p[i], cs]; ENDLOOP;
IF cs = 177777B THEN cs ← 0;
END;
ENDCASE => NULL;
RETURN[checksumLoc^ = cs];
END;
END.