**
** $VER: CRC32.a (24.1.95) by Flavio Stanchina
** Adapted from comp.compression FAQ
**
** Changed to do one-byte-at-a-time CRC
** Don't complement CRC for simplicity
**
** For your mental sanity, don't try to learn about CRC's from this code.
** Ask me for the C version of these routines instead.
**

	INCLUDE	"CRC32.i"

	SECTION	text,code

***** Build auxiliary table for parallel byte-at-a-time CRC-32. *****
; VOID CRC32_init(VOID)

	XDEF	@CRC32_init

@CRC32_init:
	movem.l	D2-D3,-(A7)
	lea	_CRC32_table,A0	; load table pointer
	move.l	#CRC32_POLY,D1	; load poly once and for all
	 moveq.l	#0,D2
loop_1	 move.l	D2,D0
	 ror.l	#8,D0
	  moveq.l	#8,D3
loop_2	  add.l	D0,D0
	  bcc.s	test_2
	  eor.l	D1,D0
test_2	  subq.l	#1,D3
	  bgt.s	loop_2
	 move.l	D0,(A0)+
test_1	 addq.l	#1,D2
	 tst.b	D2		; cmp.l #256,D2
	 bne.s	loop_1		; blt.s loop_1
	movem.l	(A7)+,D2-D3
	rts

***** Calculate CRC-32 on a byte stream. *****
; ULONG CRC32_stream(UBYTE c, ULONG crc)

	XDEF	@CRC32_stream

@CRC32_stream:
	lea	_CRC32_table,A1
	rol.l	#8,D1		; will yield crc >> 24 and crc << 8
	move.l	D1,A0		; save for later

	eor.b	D1,D0		; (crc >> 24) ^ c
	moveq	#0,D1
	move.b	D0,D1
	lsl.w	#2,D1		; multiply by 4
	add.w	D1,A1
	move.l	(A1),D0		; crc32_table[(crc >> 24) ^ c]

	move.l	A0,D1
	clr.b	D1		; crc << 8

	eor.l	D1,D0		; EOR together
	rts

***** Calculate CRC-32 on a block of bytes. *****
; ULONG CRC32_block (UBYTE *buf, ULONG len)
; ULONG CRC32_blocks(UBYTE *buf, ULONG len, ULONG crc)
; NOTE: this function can't complement the returned CRC, so none does for coherency.

	XDEF	@CRC32_block
	XDEF	@CRC32_blocks

@CRC32_block:
;;;	moveq.l	#CRC32_INITIAL,D1	; preload shift register, per CRC-32 spec
	moveq.l	#-1,D1		; preload shift register, per CRC-32 spec

@CRC32_blocks:
	movem.l	D2-D3,-(A7)

	lea	_CRC32_table,A1

loop_bs	 moveq.l	#0,D3
	 rol.l	#8,D1
	 move.b	D1,D3		; (crc >> 24) & 0x000000FF
	 clr.b	D1		; (crc <<  8) & 0xFFFFFF00

	 move.b	(A0)+,D2
	 eor.b	D2,D3
	 lsl.w	#2,D3
	 move.l	0(A1,D3.w),D2
	 eor.l	D2,D1

	 subq.l	#1,D0		; while(--len)
	 bne.s	loop_bs

;;;	not.l	D1		; transmit complement, per CRC-32 spec
	move.l	D1,D0

	movem.l	(A7)+,D2-D3
	rts

	SECTION	__MERGED,BSS

_CRC32_table:
	ds.l	256

	END
