1;===========================================================================
2; Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
3;
4; See the accompanying file LICENSE, version 2000-Apr-09 or later
5; (the contents of which are also included in zip.h) for terms of use.
6; If, for some reason, all these files are missing, the Info-ZIP license
7; also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8;===========================================================================
9; crc_68 created by Paul Kienitz, last modified 04 Jan 96.
10;
11; Return an updated 32 bit CRC value, given the old value and a block of data.
12; The CRC table used to compute the value is gotten by calling get_crc_table().
13; This replaces the older updcrc() function used in Zip and fUnZip.  The
14; prototype of the function is:
15;
16;    ulg crc32(ulg crcval, uch *text, extent textlen);
17;
18; On the Amiga, type extent is always unsigned long, not unsigned int, because
19; int can be short or long at whim, but size_t is long.
20;
21; If using this source on a non-Amiga 680x0 system, note that we treat
22; a0/a1/d0/d1 as scratch registers not preserved across function calls.
23; We do not bother to support registerized arguments for crc32() -- the
24; textlen parm is usually large enough so that savings outside the loop
25; are pointless.
26;
27; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more
28; efficient on certain machines with dinky instruction caches ('020?), or for
29; processing short strings.  If loops are unrolled, the textlen parm must be
30; less than 512K; if not unrolled, it must be less than 64K.
31
32        xdef    _crc32          ; (ulg val, uch *buf, extent bufsize)
33
34DO_CRC0 MACRO
35        moveq  #0,ltemp
36        move.b (textbuf)+,ltemp
37        eor.b  crcval,ltemp
38        lsl.w  #2,ltemp
39        move.l (crc_table,ltemp.w),ltemp
40        lsr.l  #8,crcval
41        eor.l  ltemp,crcval
42        ENDM
43
44        machine mc68020
45
46DO_CRC2 MACRO
47        move.b (textbuf)+,btemp
48        eor.b  crcval,btemp
49        lsr.l  #8,crcval
50        move.l (crc_table,btemp.w*4),ltemp
51        eor.l  ltemp,crcval
52        ENDM
53
54crc_table       equr    a0      array of unsigned long
55crcval          equr    d0      unsigned long initial value
56textbuf         equr    a1      array of unsigned char
57textbufsize     equr    d1      unsigned long (count of bytes in textbuf)
58btemp           equr    d2
59ltemp           equr    d3
60
61
62        xref    _get_crc_table  ; ulg *get_crc_table(void)
63
64        NOLIST
65        INCLUDE 'exec/execbase.i'
66        LIST
67        xref    _SysBase        ; struct ExecBase *
68
69
70_crc32:
71        move.l  8(sp),d0
72        bne.s   valid
73         moveq  #0,d0
74         rts
75valid:  movem.l btemp/ltemp,-(sp)
76        jsr     _get_crc_table
77        move.l  d0,ltemp
78        move.l  12(sp),crcval
79        move.l  16(sp),textbuf
80        move.l  20(sp),textbufsize
81        not.l   crcval
82        move.l  _SysBase,crc_table
83        move.w  AttnFlags(crc_table),btemp
84        move.l  ltemp,crc_table
85        btst    #AFB_68020,btemp
86        bne     twenty
87
88    IFD     NO_UNROLLED_LOOPS
89
90        bra.s   decr
91loop:    DO_CRC0
92decr:    dbra   textbufsize,loop
93        bra.s   done
94
95twenty: moveq   #0,btemp
96        bra.s   decr2
97loop2:   DO_CRC2
98decr2:   dbra   textbufsize,loop2
99
100    ELSE    ; !NO_UNROLLED_LOOPS
101
102        move.l  textbufsize,btemp
103        lsr.l   #3,textbufsize
104        bra     decr8
105loop8:   DO_CRC0
106         DO_CRC0
107         DO_CRC0
108         DO_CRC0
109         DO_CRC0
110         DO_CRC0
111         DO_CRC0
112         DO_CRC0
113decr8:   dbra   textbufsize,loop8
114        and.w   #7,btemp
115        bra.s   decr1
116loop1:   DO_CRC0
117decr1:   dbra   btemp,loop1
118        bra     done
119
120twenty: moveq   #0,btemp
121        move.l  textbufsize,-(sp)
122        lsr.l   #3,textbufsize
123        bra     decr82
124loop82:  DO_CRC2
125         DO_CRC2
126         DO_CRC2
127         DO_CRC2
128         DO_CRC2
129         DO_CRC2
130         DO_CRC2
131         DO_CRC2
132decr82:  dbra   textbufsize,loop82
133        move.l  (sp)+,textbufsize
134        and.w   #7,textbufsize
135        bra.s   decr12
136loop12:  DO_CRC2
137decr12:  dbra   textbufsize,loop12
138
139    ENDC    ; ?NO_UNROLLED_LOOPS
140
141done:   movem.l (sp)+,btemp/ltemp
142        not.l   crcval
143;;;;;   move.l  crcval,d0               ; crcval already is d0
144        rts
145