;       SCCSID = @(#)cas.asm	6.1 90/11/18
;	SCCSID = @(#)cas.asm      13.2 90/01/25
;***	cas.asm - compute aligned checksum

ifdef MEDIUM_MODEL
.model	medium, pascal

.code	_TEXT
else
.model	small, pascal

.code
endif

;**	cas - compute aligned checksum
;
;	Compute a checksum on an object that is word aligned.
;
;	ENTRY	(pch) = pointer to array of bytes to be checksummed
;		(cch) = length of array
;	EXIT	(dx:ax) = checksum


PUBLIC	CAS
CAS	proc	uses ds si, pch:dword, cch:word

	sub	bx,bx
	mov	dx,bx
	mov	cx,cch
	lds	si,pch

;	(dx:bx) = running checksum
;	(cx) = number of bytes remaining
;	(ds:si) = pointer to next bytes to checksum

cas1:	sub	cx,2			; (cx) = number of bytes after this word
	jb	cas2			; less than a word left, go check single byte

	lodsw				; (ax) = word from data

	add	bx,ax
	adc	dx,1			; (dx:bx) += ax

	shl	bx,1
	rcl	dx,1
	adc	bx,0			; Rotate (dx:bx) left one bit

	jmp	cas1			; go back for more bytes


;	(cx) = number of bytes to read - 2
;	(dx:bx) = running checksum so far
;	(ds:si) = pointer to potential last byte
cas2:	add	cx,2
	jz	cas3			; no more bytes, go return checksum
	lodsb				; get last byte
	add	bx,ax			; include it in checksum


;	(dx:bx) = checksum

cas3:	mov	ax,bx			; (dx:ax) = checksum

	ret
CAS	endp

end
