Checksum.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Forrest, October 4, 1980 2:03 PM
Russ Atkinson (RRA) January 29, 1985 0:37:17 am PST
Doug Wyatt, February 26, 1985 2:50:29 pm PST
DIRECTORY
PrincOps USING [aCHKSUM, zADD, zDADD, zDUP, zEXCH, zINC, zLI0, zMISC];
Checksum: DEFINITIONS
= BEGIN
ComputeChecksum: PROC [
cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER]
RETURNS
[checksum: CARDINAL]
= MACHINE CODE { PrincOps.zMISC, PrincOps.aCHKSUM; };
... produces a checksum for nWords starting at p. Start with initial value cs (useful if forming a single checksum for discontinuous areas of memory).
ComputeChecksumSoftware is provided as documentation.
ComputeChecksumSoftware: PRIVATE PROC [
cs: CARDINAL ← 0, nWords: CARDINAL, p: LONG POINTER]
RETURNS
[checksum: CARDINAL]
= INLINE {
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];
};
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 {
Push: PROC [CARDINAL] = MACHINE CODE { };
Pop: PROC RETURNS [CARDINAL] = MACHINE CODE { };
TOS: PROC RETURNS [CARDINAL] = MACHINE CODE { PrincOps.zDUP; };
IncTOS: PROC = MACHINE CODE { PrincOps.zINC; };
OnesAddAndLeftRotate: PROC [
--cs: CARDINAL,--zero: CARDINAL ← 0, wd: CARDINAL, zero1: CARDINAL ← 0]
--RETURNS [cs: CARDINAL]-- = MACHINE CODE
{
PrincOps.zDADD;
PrincOps.zADD; -- cs ← (cs ONESADD wd)
PrincOps.zDUP;
PrincOps.zLI0;
PrincOps.zEXCH;
PrincOps.zLI0; -- Long[cs], Long[cs]
PrincOps.zDADD;
PrincOps.zADD; -- Rotate via long add to self, merging carry
};
--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.