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