On Tue, 9 Jan 2001, Scott Dattalo wrote:
{Quote hidden}>
>
> On Tue, 9 Jan 2001, William Chops Westfield wrote:
>
> <snip>
> > /*
> > * bytestream-based ip checksum. Given a series of bytes, calculate an
> > * ip checksum using only 8bit math.
> > * ipsum_reset resets/initializes the checksum
> > * ipsum_running adds in each byte as appropriate, leaving the result in
> > * bytes ipcksum_h and ipcksum_l
> > * While this may look like C, it's supposed to translate somewhat trivially
> > * to assembler/machine code for any particular processor...
> > */
> > byte8 ipcksum_h, /* ip checksum high byte */
> > ipcksum_l, /* ip checksum low bytes */
> > ipcksum_b; /* running byte count (one byte's worth. */
> > /* Note that this wraps for long data, */
> > /* but we only use the low bit to check */
> > /* for odd/even bytes */
> > ipsum_reset()
> > {
> > ipcksum_h = 0;
> > ipcksum_l = 0;
> > ipcksum_b = 0;
> > }
> >
> > ipsum_running (byte8 b)
> > {
> > ++ipcksum_b; /* Increment count */
> > if (ipcksum_b & 1) { /* a high byte ? */
> > ipcksum_h += b; /* Add byte to high checksum */
> > if (CARRYFLAG) { /* If this resulted in a carry */
> > ipcksum_l += 1; /* add the carry into low sum */
> > if (CARRYFLAG) { /* and perhaps continue to propagate */
> > ipcksum_h += 1; /* that into the bottom of high byte */
> > /* (note that if A+B generates carry, */
> > /* then (A+B)+1 will never generate */
> > /* an additional carry. I hope.) */
> > }
> > }
> > } else { /* do the low byte */
> > ipcksum_l += b; /* Add byte to high checksum */
> > if (CARRYFLAG) { /* If this resulted in a carry */
> > ipcksum_h += 1; /* add the carry into low sum */
> > if (CARRYFLAG) { /* and perhaps continue to propagate */
> > ipcksum_l += 1; /* that into the bottom of high byte */
> > }
> > }
> > }
> > }
>
> Well, here's an implementation of ipsum_running:
>
>
> ; enter with "b" in W
>
> ipsum_running:
>
> incf ipcksum_b,f
> btfsc ipcksum_b,0
> goto l1
>
> addwf ipcksum_h,f
> rlf known_zero,w
> addwf ipcksum_l,f
> rlf known_zero,w
> addwf ipcksum_h,f
> return
>
> l1:
> addwf ipcksum_l,f
> rlf known_zero,w
> addwf ipcksum_h,f
> rlf known_zero,w
> addwf ipcksum_l,f
> return
And here's another version without the known_zero trick.
; enter with "b" in W
ipsum_running:
incf ipcksum_b,f
btfsc ipcksum_b,0
goto l1
addwf ipcksum_h,f
skpnz
incf ipcksum_l,f
skpnz
incf ipcksum_h,f
return
l1:
addwf ipcksum_l,f
skpnz
incf ipcksum_h,f
skpnz
incf ipcksum_l,f
return
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.