-- 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.