mirror of
https://github.com/cc65/cc65.git
synced 2024-11-18 15:05:14 +00:00
86 lines
1.4 KiB
ArmAsm
86 lines
1.4 KiB
ArmAsm
|
;
|
||
|
; Piotr Fusik, 18.11.2001
|
||
|
;
|
||
|
; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf,
|
||
|
; unsigned len);
|
||
|
;
|
||
|
|
||
|
.export _adler32
|
||
|
|
||
|
.import incsp2, incsp4, popax, 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 popax
|
||
|
sta ptr1
|
||
|
stx ptr1+1
|
||
|
; 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
|
||
|
lda #1
|
||
|
; ignore adler
|
||
|
jmp incsp4
|