diff options
Diffstat (limited to 'human68k/crc_68.s')
-rw-r--r-- | human68k/crc_68.s | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/human68k/crc_68.s b/human68k/crc_68.s new file mode 100644 index 0000000..9ce78d8 --- /dev/null +++ b/human68k/crc_68.s @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. +; +; 1999/09/23: for Human68k: Modified by Shimazaki Ryo. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table reg a0 array of unsigned long +crcval reg d0 unsigned long initial value +textbuf reg a1 array of unsigned char +textbufsize reg d1 unsigned long (count of bytes in textbuf) +btemp reg d2 +ltemp reg d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + + + quad +_crc32: + move.l 8(sp),d0 + bne.s valid +;;;;; moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + movea.l d0,crc_table + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + + ifdef NO_UNROLLED_LOOPS + + if CPU==68000 + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + + else +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + endif + + ELSE ; !NO_UNROLLED_LOOPS + + if CPU==68000 + moveq #7,btemp + and textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + + else +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 + quad +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + moveq #7,textbufsize + and.l (sp)+,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + endif + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts |