File: crc32.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 (132 lines) | stat: -rw-r--r-- 2,886 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;
; 2001-11-14, Piotr Fusik
; 2018-05-20, Christian Kruger
;
; unsigned long __fastcall__ crc32 (unsigned long crc, unsigned char* buf,
;                                   unsigned len);
;

        .export _crc32

        .import         compleax, incsp2, incsp4, popptr1, popeax
        .importzp       sreg, ptr1, ptr2, tmp1, tmp2

POLYNOMIAL      =       $EDB88320

make_table:
        ldx     #0
@L1:    lda     #0
        sta     tmp2
        sta     sreg
        sta     sreg+1
        ldy     #8
        txa
@L2:    sta     tmp1
        lsr     a
        bcc     @L3
        lda     sreg+1
        lsr     a
        eor     #(POLYNOMIAL>>24)&$FF
        sta     sreg+1
        lda     sreg
        ror     a
        eor     #(POLYNOMIAL>>16)&$FF
        sta     sreg
        lda     tmp2
        ror     a
        eor     #(POLYNOMIAL>>8)&$FF
        sta     tmp2
        lda     tmp1
        ror     a
        eor     #POLYNOMIAL&$FF
        bcs     @L4     ; branch always
@L3:    rol     a
        lsr     sreg+1
        ror     sreg
        ror     tmp2
        ror     a
@L4:    dey
        bne     @L2
        sta     table_0,x
        lda     tmp2
        sta     table_1,x
        lda     sreg
        sta     table_2,x
        lda     sreg+1
        sta     table_3,x
        inx
        bne     @L1
        inc     table_initialised
RET:
        rts

_crc32:
; 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 0;
        ora     ptr1+1
        beq     @L0
; if (!tables_initialised) make_tables();
        lda     table_initialised
        bne     @dont_make
        jsr     make_table
@dont_make:
; eax = crc
        jsr     popeax
; if (len == 0) return crc;
        ldy     ptr2
        bne     @L2
        ldy     ptr2+1
        beq     RET
@L2:
; eax = ~crc
        jsr     compleax
        stx     tmp2
        ldy     #0
; crc = (crc >> 8) ^ table[(crc & 0xff) ^ *p++];
@L3:    eor     (ptr1),y
        tax
        lda     table_0,x
        eor     tmp2
        sta     tmp1
        lda     table_1,x
        eor     sreg
        sta     tmp2
        lda     table_2,x
        eor     sreg+1
        sta     sreg
        lda     table_3,x
        sta     sreg+1
        lda     tmp1
        iny
        bne     @L4
        inc     ptr1+1
@L4:    dec     ptr2
        bne     @L3
        dec     ptr2+1
        bne     @L3
        ldx     tmp2
        jmp     compleax

; return 0L
@L0:    sta     sreg
        sta     sreg+1
        tax             ; (popptr1 doesn't set .X)
; ignore crc
        jmp     incsp4

                .data
table_initialised:
                .byte   0

                .bss
table_0:        .res    256
table_1:        .res    256
table_2:        .res    256
table_3:        .res    256