DIRECTORY BufferDefs USING [OisBuffer], Checksums USING [ComputeChecksum], CommunicationInternal USING [], CommUtilDefs USING [thisIsAnAlto], PrincOpsUtils USING [BITAND, BITNOT, BITOR, BITSHIFT], PrincOps USING [zADD, zDADD, zEXCH, zJ2, zJNE3, zLIN1, zLI0, zPUSH], OISCPTypes USING [BufferBody]; ChecksumsImpl: PROGRAM IMPORTS Checksums, PrincOpsUtils EXPORTS CommunicationInternal, Checksums SHARES BufferDefs = BEGIN OPEN Checksums; SetChecksum: PUBLIC PROCEDURE [b: BufferDefs.OisBuffer] = BEGIN b.ois.checksum _ IF CommUtilDefs.thisIsAnAlto THEN SlowlyComputeChecksum[ 0, (b.ois.pktLength + 1)/2 - 1, @b.ois.pktLength] ELSE ComputeChecksum[0, (b.ois.pktLength + 1)/2 - 1, @b.ois.pktLength]; END; TestChecksum: PUBLIC PROCEDURE [b: BufferDefs.OisBuffer] RETURNS [BOOLEAN] = BEGIN cs: CARDINAL _ 0; IF b.ois.checksum = 177777B THEN RETURN[TRUE]; cs _ IF CommUtilDefs.thisIsAnAlto THEN SlowlyComputeChecksum[ cs, (b.ois.pktLength + 1)/2 - 1, @b.ois.pktLength] ELSE ComputeChecksum[cs, (b.ois.pktLength + 1)/2 - 1, @b.ois.pktLength]; RETURN[b.ois.checksum = cs]; END; SlowlyComputeChecksum: PUBLIC PROCEDURE [ cs: CARDINAL, nWords: CARDINAL, p: LONG POINTER] RETURNS [CARDINAL] = BEGIN t: CARDINAL; THROUGH [0..nWords) DO 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; zz: PRIVATE POINTER TO OISCPTypes.BufferBody = NIL; transportControlOffset: CARDINAL = LOOPHOLE[@zz.transCntlAndPktTp, CARDINAL] - LOOPHOLE[zz, CARDINAL]; IncrOisTransportControlAndUpdateChecksum: PUBLIC PROCEDURE [ b: BufferDefs.OisBuffer] = BEGIN oldVal: WORD _ LOOPHOLE[b.ois.transCntlAndPktTp, CARDINAL]; resisdual: INTEGER; b.ois.transCntlAndPktTp.transportControl.hopCount _ b.ois.transCntlAndPktTp.transportControl.hopCount + 1; IF b.ois.checksum = 177777B THEN RETURN; resisdual _ PrincOpsUtils.BITAND[ (b.ois.pktLength + 1)/2 - transportControlOffset, 17B]; b.ois.checksum _ OnesAdd[ b.ois.checksum, LeftCycle[ OnesSub[LOOPHOLE[b.ois.transCntlAndPktTp, CARDINAL], oldVal], resisdual]]; END; -- UpdateChecksum LeftCycle: PROCEDURE [val: CARDINAL, dist: INTEGER] RETURNS [CARDINAL] = INLINE BEGIN OPEN PrincOpsUtils; RETURN[BITOR[BITSHIFT[val, dist], BITSHIFT[val, dist - 16]]]; END; OnesSub: PROCEDURE [a, b: CARDINAL] RETURNS [CARDINAL] = INLINE BEGIN RETURN[OnesAdd[a, PrincOpsUtils.BITNOT[b]]]; END; OnesAdd: PROCEDURE [a, b: CARDINAL] RETURNS [c: CARDINAL] = MACHINE CODE BEGIN PrincOps.zLI0; PrincOps.zEXCH; PrincOps.zLI0; PrincOps.zDADD; PrincOps.zADD; PrincOps.zLIN1; PrincOps.zJNE3; PrincOps.zLI0; PrincOps.zJ2; PrincOps.zPUSH; END; END. -- ChecksumsImpl ŠChecksumsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. HGM March 5, 1981 3:47 PM BLyon January 16, 1981 9:54 AM These procedures sets the checksum field of the Ois Packet. These procedures checks the checksum field of the Ois Packet, and returns TRUE or FALSE. The buffer is always a system buffer This procedure updates the checksum field of the Ois Packet after it increments the oisTransportControl. Beware: Making this work on a real Alto is quite tricky. If you get it wrong, it will do things like store 0 in the word the new checksum points at. c _ a + b; IF c