;
; 2001-11-18, Piotr Fusik
; 2018-05-20, Christian Kruger
;
; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf,
; unsigned len);
;
.export _adler32
.import incsp2, incsp4, popptr1, popeax
.importzp sreg, ptr1, ptr2, tmp1
BASE = 65521 ; largest prime smaller than 65536
_adler32:
; ptr2 = (len & 0xff) == 0 ? len : len + 0x100;
tay
beq @L1
inx
@L1: sta ptr2
stx ptr2+1
; ptr1 = buf
jsr popptr1
; if (buf == NULL) return 1L;
ora ptr1+1
beq @L0
; s1 = adler & 0xFFFF; s2 = adler >> 16;
jsr popeax
; if (len == 0) return adler;
ldy ptr2
bne @L2
ldy ptr2+1
beq @RET
@L2: ldy #0
; s1 += *ptr++; if (s1 >= BASE) s1 -= BASE;
@L3: clc
adc (ptr1),y
bcc @L4
inx
beq @L5 ; C flag is set
@L4: cpx #>BASE
bcc @L6
cmp #= BASE) s2 -= BASE;
adc sreg ; C flag is clear
sta sreg
txa
adc sreg+1
sta sreg+1
bcs @L7
cmp #>BASE
bcc @L8
lda sreg
cmp #BASE
sta sreg+1
@L8: lda tmp1
iny
bne @L9
inc ptr1+1
@L9: dec ptr2
bne @L3
dec ptr2+1
bne @L3
; return (s2 << 16) | s1;
@RET: rts
; return 1L
@L0: sta sreg
sta sreg+1
tax ; (popptr1 doesn't set .X)
lda #1
; ignore adler
jmp incsp4