File: adler32.s

package info (click to toggle)
cc65 2.19-2
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,268 kB
  • sloc: ansic: 117,151; asm: 66,339; pascal: 4,248; makefile: 1,009; perl: 607
file content (85 lines) | stat: -rw-r--r-- 1,987 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
;
; 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