summaryrefslogtreecommitdiff
path: root/human68k/crc_68.s
diff options
context:
space:
mode:
Diffstat (limited to 'human68k/crc_68.s')
-rw-r--r--human68k/crc_68.s144
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