       NAME CheckSum
      
; This will calculate the checksum of
; a string of bytes.  It will form
; a word result.  This is a long call
; 
; MakeCheckSum : PROCEDURE (pBuf, length) WORD;
;   DCL pBuf PTR;
;   DCL length WORD;
;   END;

       PUBLIC MakeCheckSum
      
CGROUP GROUP CODE

; constants

len    EQU 6    ; length parameter
pBuf   EQU 8    ; pBuf parameter 

; len = 4 and pBuf = 8 in COMPACT

evnn   EQU 0    ; length is evnn
odd    EQU 1    ; length is odd

CODE   SEGMENT BYTE PUBLIC 'CODE'
       ASSUME  CS:CODE
       
MakeCheckSum PROC FAR

       PUSH BP
       MOV BP,SP
       
       MOV CX,WORD PTR [BP+len]    ; get length
       MOV AX,0                    ; init sum
       
       JCXZ Done                   ; done if length = 0
       
       LES BX,DWORD PTR [BP+pBuf]  ; get pointer
       MOV DL,evnn                 ; assume evnn
       SHR CX,1                    ; cx := cx/2
       JNC EvenLength
       MOV DL,odd
              
EvenLength:
       JCXZ CheckOdd               ; done if length = 1
                     
CheckLoop:
       ADD AX,WORD PTR ES:[BX]     ; subtotal
       INC BX
       INC BX                      ; bump pointer
       LOOP CheckLoop


CheckOdd:
       AND DL,DL                   ; is dl = 0 ?
       JZ  Done
       
       MOV DL,BYTE PTR ES:[BX]     ; if odd then add in
       MOV DH,0                    ; last byte
       ADD AX,DX

Done:  POP BP
       RET 6                       ; 6 bytes of parameters
       
MakeCheckSum ENDP 

CODE   ENDS

       END
