<<>> <> <> <> <> <> <> <> <> DIRECTORY Basics, Basics16; Checksum: CEDAR DEFINITIONS IMPORTS Basics ~ BEGIN bitsPerHalfWord: NAT ~ Basics16.bitsPerWord; bytesPerHalfWord: NAT ~ Basics16.bytesPerWord; ComputeChecksum: PROC [ cs: CARD16 ¬ 0, nHalfWords: CARDINAL, p: POINTER, offset: CARDINAL ¬ 0] RETURNS [checksum: CARD16]; <<... produces a checksum for nHalfWords starting at offset halfwords from p. Start with initial value cs (useful if forming a single checksum for discontinuous areas of memory). Note that since these checksums must be backward compatible they are 16 bit checksums computed over an integral number of 16 bit halfwords, even on a 32 bit machine.>> <<>> <> ComputeChecksumINLINE: PROC[ cs: CARD16 ¬ 0, nHalfWords: CARDINAL, p: POINTER, offset: CARDINAL ¬ 0] RETURNS [checksum: CARD16] = INLINE { RETURN[ComputeChecksumSoftware[cs, nHalfWords, p, offset]] }; <> <<>> <> <> <<>> ComputeChecksumSoftware: PROC [ cs: CARD16 ¬ 0, nHalfWords: CARDINAL, p: POINTER, offset: CARDINAL] RETURNS [checksum: CARD16] = TRUSTED INLINE { phw: POINTER TO Basics16.RawWords ¬ LOOPHOLE[p]; FOR i: CARDINAL IN [offset..nHalfWords+offset) DO t: CARD32; w: CARD32 = phw[i]; <> t ¬ cs + w; t ¬ Basics.LowHalf[t] + Basics.HighHalf[t]; t ¬ 2*t; cs ¬ Basics.LowHalf[t] + Basics.HighHalf[t]; ENDLOOP; IF cs = 177777B THEN cs ¬ 0; RETURN[cs]; }; END.