-- File: PupChecksums.mesa, Last Edit: HGM October 15, 1980 7:37 PM DIRECTORY MiscAlpha USING [aCHKSUM], Mopcodes USING [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 Mopcodes.zPOP; END; ComputeD0Checksum: PROCEDURE [cs: CARDINAL, nWords: CARDINAL, p: LONG POINTER] RETURNS [CARDINAL] = MACHINE CODE BEGIN Mopcodes.zMISC, MiscAlpha.aCHKSUM; END; OnesComplementAddAndCycle: PROCEDURE [a, b: LONG UNSPECIFIED] RETURNS [UNSPECIFIED] = MACHINE CODE BEGIN Mopcodes.zDADD; Mopcodes.zADD; -- Ones add if a+b are in CARDINAL range Mopcodes.zDUP; Mopcodes.zLI0; Mopcodes.zEXCH; Mopcodes.zLI0; -- Make LONG again Mopcodes.zDADD; Mopcodes.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.