mirror of
https://github.com/cc65/cc65.git
synced 2024-11-01 11:04:34 +00:00
86 lines
1.9 KiB
ArmAsm
86 lines
1.9 KiB
ArmAsm
;
|
|
; 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
|
|
bcc @L6
|
|
inx ; ldx #0
|
|
@L5: sbc #<BASE ; C flag is set
|
|
clc
|
|
@L6: sta tmp1
|
|
; s2 += s1; if (s2 >= 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
|
|
bcc @L8
|
|
@L7: lda sreg
|
|
sbc #<BASE ; C flag is set
|
|
sta sreg
|
|
lda sreg+1
|
|
sbc #>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
|