-- Checksum.mesa (last edited on: October 4, 1980 2:03 PM by: Forrest) DIRECTORY MiscAlpha USING [aCHKSUM], Mopcodes USING [zADD, zDADD, zDUP, zEXCH, zINC, zLI0, zMISC]; Checksum: DEFINITIONS = BEGIN -- Produce checksum for nWords starting at p. Start with initial value cs (useful if forming a single checksum for discontinuous areas of memory). ComputeChecksum: PROC [cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = MACHINE CODE BEGIN Mopcodes.zMISC, MiscAlpha.aCHKSUM; END; -- ComputeChecksumSoftware is provided as documentation. ComputeChecksumSoftware: PRIVATE PROC [ cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = INLINE BEGIN THROUGH [0..nWords) DO t: CARDINAL; -- cs ← ((cs ONESADD p↑) LEFTROTATE 1) IF cs > (t ← cs + p↑) THEN cs ← t + 1 ELSE cs ← t; IF cs >= 100000B THEN cs ← cs*2 + 1 ELSE cs ← cs*2; p ← p + 1; ENDLOOP; IF cs = 177777B THEN cs ← 0; RETURN[cs]; END; -- ComputeChecksumProc is provided as an aid to processors required to compute checksum as part of their unimplemented instruction trap. ComputeChecksumProc: PRIVATE PROC [ cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER] RETURNS [checksum: CARDINAL] = INLINE BEGIN Push: PROC [CARDINAL] = MACHINE CODE BEGIN END; Pop: PROC RETURNS [CARDINAL] = MACHINE CODE BEGIN END; TOS: PROC RETURNS [CARDINAL] = MACHINE CODE BEGIN Mopcodes.zDUP; END; IncTOS: PROC = MACHINE CODE BEGIN Mopcodes.zINC; END; OnesAddAndLeftRotate: PROC [ --cs: CARDINAL,--zero: CARDINAL ← 0, wd: CARDINAL, zero1: CARDINAL ← 0] --RETURNS [cs: CARDINAL]-- = MACHINE CODE BEGIN Mopcodes.zDADD; Mopcodes.zADD; -- cs ← (cs ONESADD wd) Mopcodes.zDUP; Mopcodes.zLI0; Mopcodes.zEXCH; Mopcodes.zLI0; -- Long[cs], Long[cs] Mopcodes.zDADD; Mopcodes.zADD; -- Rotate via long add to self, merging carry END; --TOS←-- Push[cs]; -- leave cs on the stack throughout the procedure THROUGH [0..nWords) DO --TOS←-- OnesAddAndLeftRotate[--cs: TOS,-- wd: p↑]; p ← p + 1 ENDLOOP; IF TOS[] = 177777B THEN IncTOS[]; RETURN[Pop[--TOS--]]; END; END....