1 /*
2  * $Id: crc32.c,v 1.1.1.1 2002/03/28 00:02:10 andrew_belov Exp $
3  * ---------------------------------------------------------------------------
4  * This file contains CRC32 calculation routines.
5  *
6  */
7 
8 #include "arj.h"
9 
10 DEBUGHDR(__FILE__)                      /* Debug information block */
11 
12 #define CRCPOLY          0xEDB88320L    /* CRC32 polynomial */
13 #define UPDATE_CRC(r, c) crc32tab[((unsigned char)(r)^(unsigned char)(c))&0xFF]^(r>>CHAR_BIT)
14 
15 unsigned long crc32term;
16 #ifdef ASM8086
17  unsigned short crc32tab_lo[256];
18  unsigned short crc32tab_hi[256];
19  static unsigned short xbp;
20 #else
21  unsigned long crc32tab[256];
22 #endif
23 
24 /* CRC32 initialization */
25 
build_crc32_table()26 void build_crc32_table()
27 {
28  #ifdef ASM8086
29   asm{
30                 push    si
31                 push    di
32                 xor     di, di
33                 jmp     short lt_0
34   }
35 loop_ch:
36   asm{
37                 mov     dx, di
38                 xor     ax, ax
39                 mov     si, 8
40                 or      si, si
41                 jmp     short lt_1
42   }
43 loop_term:
44   asm{
45                 test    dx, 1
46                 jz      lt_next
47                 shr     ax, 1
48                 rcr     dx, 1
49                 xor     dx, 8320h
50                 xor     ax, 0EDB8h
51                 jmp     short lt_next_c
52   }
53 lt_next:
54   asm{
55                 shr     ax, 1
56                 rcr     dx, 1
57   }
58 lt_next_c:
59   asm{
60                 dec     si
61   }
62 lt_1:
63   asm{
64                 jg      loop_term
65                 mov     bx, di
66                 shl     bx, 1
67                 mov     word ptr crc32tab_lo[bx], dx
68                 mov     word ptr crc32tab_hi[bx], ax
69                 inc     di
70   }
71 lt_0:
72   asm{
73                 cmp     di, 0FFh
74                 jbe     loop_ch
75                 pop     di
76                 pop     si
77   }
78  #else
79   unsigned int i, j;
80   unsigned long r;
81 
82   for(i=0; i<=UCHAR_MAX; i++)
83   {
84    r=i;
85    for(j=CHAR_BIT; j>0; j--)
86    {
87     if(r&1)
88      r=(r>>1)^CRCPOLY;
89     else
90      r>>=1;
91    }
92    crc32tab[i]=r;
93   }
94  #endif
95 }
96 
97 /* Calculates CRC32 for a given block */
98 
crc32_for_block(char * block,unsigned int b_size)99 void crc32_for_block(char *block, unsigned int b_size)
100 {
101  #ifdef ASM8086
102   asm{
103                 push    si
104                 push    di
105                 cld
106                 mov     word ptr xbp, bp
107                 mov     bx, offset crc32tab_lo
108                 mov     cl, 4
109                 shr     bx, cl
110                 mov     cx, word ptr crc32term[0]
111                 mov     dx, word ptr crc32term[2]
112                 mov     si, block
113                 mov     di, b_size
114                 push    ds
115                 mov     ax, ds
116                 mov     es, ax
117                 add     ax, bx
118                 xor     bx, bx
119                 mov     bp, di
120                 and     di, 3
121                 push    di
122                 shr     bp, 1
123                 shr     bp, 1
124                 jz      lt_shloop
125   }
126 lt_accterm:
127 #if COMPILER==BCC
128   asm{
129 		db	26h, 0ADh
130   }
131 #else
132   asm{
133                 lods    word ptr es:[si]
134   }
135 #endif
136   asm{
137                 mov     bl, cl
138                 xor     bl, al
139                 mov     cl, ch
140                 mov     ch, dl
141                 mov     dl, dh
142                 mov     dh, bh
143                 mov     di, bx
144                 shl     di, 1
145                 xor     cx, crc32tab_lo[di]
146                 xor     dx, crc32tab_hi[di]
147                 mov     bl, cl
148                 xor     bl, ah
149                 mov     cl, ch
150                 mov     ch, dl
151                 mov     dl, dh
152                 mov     dh, bh
153                 mov     di, bx
154                 shl     di, 1
155                 xor     cx, crc32tab_lo[di]
156                 xor     dx, crc32tab_hi[di]
157   }
158 #if COMPILER==BCC
159   asm{
160 		db	26h, 0ADh
161   }
162 #else
163   asm{
164                 lods    word ptr es:[si]
165   }
166 #endif
167   asm{
168                 mov     bl, cl
169                 xor     bl, al
170                 mov     cl, ch
171                 mov     ch, dl
172                 mov     dl, dh
173                 mov     dh, bh
174                 mov     di, bx
175                 shl     di, 1
176                 xor     cx, crc32tab_lo[di]
177                 xor     dx, crc32tab_hi[di]
178                 mov     bl, cl
179                 xor     bl, ah
180                 mov     cl, ch
181                 mov     ch, dl
182                 mov     dl, dh
183                 mov     dh, bh
184                 mov     di, bx
185                 shl     di, 1
186                 xor     cx, crc32tab_lo[di]
187                 xor     dx, crc32tab_hi[di]
188                 dec     bp
189                 jnz     lt_accterm
190   }
191 lt_shloop:
192   asm{
193                 pop     bp
194                 or      bp, bp
195                 jz      lt_exit
196   }
197 lt_shift:
198 #if COMPILER==BCC
199   asm{
200 		db	26h, 0ACh
201   }
202 #else
203   asm{
204                 lods    byte ptr es:[si]
205   }
206 #endif
207   asm{
208                 mov     bl, cl
209                 xor     bl, al
210                 mov     cl, ch
211                 mov     ch, dl
212                 mov     dl, dh
213                 mov     dh, bh
214                 mov     di, bx
215                 shl     di, 1
216                 xor     cx, crc32tab_lo[di]
217                 xor     dx, crc32tab_hi[di]
218                 dec     bp
219                 jnz     lt_shift
220   }
221 lt_exit:
222   asm{
223                 pop     ds
224                 mov     word ptr crc32term[0], cx
225                 mov     word ptr crc32term[2], dx
226                 pop     di
227                 pop     si
228                 mov     bp, word ptr xbp
229   }
230  #else
231   while(b_size--)
232    crc32term=UPDATE_CRC(crc32term, *block++);
233  #endif
234 }
235 
236 #if SFX_LEVEL>=ARJSFX||defined(REARJ)||defined(REGISTER)||defined(ARJUTIL)
237 
238 /* Calculates CRC32 for a given ASCIIz string */
239 
crc32_for_string(char * sptr)240 void crc32_for_string(char *sptr)
241 {
242  #ifdef ASM8086
243   asm{
244                 push    si
245                 push    di
246                 cld
247                 xor     bx, bx
248                 mov     si, sptr
249                 mov     cx, word ptr crc32term[0]
250                 mov     dx, word ptr crc32term[2]
251                 jmp     short str_nchar
252   }
253 stracc:
254   asm{
255                 mov     bl, cl
256                 xor     bl, al
257                 mov     cl, ch
258                 mov     ch, dl
259                 mov     dl, dh
260                 mov     dh, bh
261                 mov     di, bx
262                 shl     di, 1
263                 xor     cx, word ptr crc32tab_lo[di]
264                 xor     dx, word ptr crc32tab_hi[di]
265   }
266 str_nchar:
267   asm{
268                 lodsb
269                 or      al, al
270                 jnz     stracc
271                 mov     word ptr crc32term[0], cx
272                 mov     word ptr crc32term[2], dx
273                 pop     di
274                 pop     si
275   }
276  #else
277   while(*sptr!='\0')
278    crc32term=UPDATE_CRC(crc32term, (unsigned char)(*sptr++));
279  #endif
280 }
281 
282 /* Evaluates CRC32 based on character and term given */
283 
crc32_for_char(unsigned long crc32_term,unsigned char newc)284 unsigned long crc32_for_char(unsigned long crc32_term, unsigned char newc)
285 {
286  #ifdef ASM8086
287   asm{
288                 mov     ax, word ptr crc32_term
289                 mov     dx, word ptr crc32_term+2
290                 mov     bl, al
291                 mov     al, ah
292                 mov     ah, dl
293                 mov     dl, dh
294                 mov     dh, 0
295                 xor     bl, newc
296                 mov     bh, 0
297                 shl     bx, 1
298                 xor     ax, word ptr crc32tab_lo[bx]
299                 xor     dx, word ptr crc32tab_hi[bx]
300   }
301  #else
302   return(UPDATE_CRC(crc32_term, newc));
303  #endif
304 }
305 
306 #endif
307 
308