; Not copyrighted by Paul Kienitz, 18 Jun 94.
;
; Return an updated 32 bit CRC value, given the old value and a block of data.
; This substitutes for the following lines at the top of flush() in file_io.c
; in UnZip, or a similar loop in updcrc() in util.c in Zip:
;
;    register ulg crcval = crc32val;
;    register ulg n = size;
;    register uch *p=rawbuf;
;    while (n--)
;        crcval = crc_32_tab[((uch)crcval ^ (*p++)) & 0xff] ^ (crcval >> 8);
;    crc32val = crcval;
;
; Those lines are replace with this call:
;
;    crc32val = CalcCRC(crc_32_tab, crc32val, rawbuf, size);
;
; We have here the CalcCRC() code for Amiga.  Define REGARGS if you can cause
; your compiler to put the four args in the registers A0, D0, A1, D1.  I'm not
; sure, but I think you should define ATSIGN when using the SAS/C assembler.
; I wrote this because I found that, at least with the Aztec compiler, this loop
; was occupying about a quarter of the CPU time with UnZip -t commands.

	xdef	_CalcCRC

temp		equr	d2

crc_table	equr	a0	array of unsigned long
crcval		equr	d0	unsigned long initial value
rawbuf		equr	a1	array of unsigned char
rawbufsize	equr	d1	unsigned long (count of bytes in rawbuf)


	IFD	REGARGS
	  IFD	ATSIGN
	  xdef	@CalcCRC
@CalcCRC:
	  ELSE
_CalcCRC:			; args already in registers as named above
	  ENDC
	ELSE	; !REGARGS
_CalcCRC:
	move.l	4(sp),crc_table
	move.l	8(sp),crcval
	move.l	12(sp),rawbuf
	move.l	16(sp),rawbufsize
	ENDC

	move.l	temp,-(sp)
loop:
	subq.l	#1,rawbufsize
	blt.s	done			; we treat it as signed
	moveq	#0,temp
	move.b	(rawbuf)+,temp
	eor.b	crcval,temp
	lsl.w	#2,temp
	move.l	0(crc_table,temp.w),temp
	lsr.l	#8,crcval
	eor.l	temp,crcval
	bra.s	loop
done:
;;;	move.l	crcval,d0		; crcval already is d0
	move.l	(sp)+,temp
	rts
