; ; 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