mempkt.asm


.cseg
;+
; **-pmem_chksum-pcode memory checksummer.
;
; inputs:
;   r10 = buffer address
;   r12 = byte count
;   chkacc = checksum accumulator
;
; outputs:
;   chkacc updated
;-

#if defined(LOG_MEM_CHKSUM)
.macro log_chk_byte
    rol r0 ; save carry
    rcall do_space
    rcall do_hexb
    ror r0
.endmacro
#else
.macro log_chk_byte
.endmacro
#endif
    
pmem_chksum: pcode_routine   2
    movw y,r10
#if defined(LOG_MEM_CHKSUM)
    hexy
    space
#endif
    shrw r12                    ; compute word count
    rol r10                     ; save "odd byte count" bit in r10:0
    clc                         ; make sure initial checksum carry == 0
    ldsw r16,chkacc             ; get accumulator
    mov r0,r12l
    or r0,r12h
    breq words_done             ; no words, just a byte (maybe)
mem_next:
    ld i0,y+                    ; low byte
log_chk_byte
    adc r16l,i0                 ; add it
    ld i0,y+                    ; high byte
log_chk_byte
    adc r16h,i0                 ; add high byte
    dec r12l
    brne mem_next
    dec r12h
    brpl mem_next
words_done:
    clr i0
    clr r0
    sbrc r10,0                  ; skip if byte count was even
    ld i0,y+                    ; get remaining byte
    adc r16l,i0                 ; add to low byte
    adc r16h,r0                 ; carry to high byte
    adc r16l,r0
    adc r16h,r0
    stsw chkacc,r16
    com r16
    com r17
#if defined(LOG_MEM_CHKSUM)
    putchar '='
    ldsw y,chkacc
    hexy
    crlf
#endif
    or r16,r17
    rjmp set_pcode_flags

Back