annotate zlib/crc32.c @ 1998:0740d90812ee

Enter debugger when a VDP data port read would cause a CPU lockup
author Mike Pavone <pavone@retrodev.com>
date Sun, 28 Jun 2020 22:53:52 -0700
parents 00d788dac91a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1530
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
1 /* crc32.c -- compute the CRC-32 of a data stream
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 * For conditions of distribution and use, see copyright notice in zlib.h
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 *
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 * tables for updating the shift register in one step with three exclusive-ors
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 * instead of four steps with four exclusive-ors. This results in about a
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 /* @(#) $Id$ */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 /*
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
16 protection on the static variables used to control the first-use generation
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
17 of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 first call get_crc_table() to initialize the tables before allowing more than
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
19 one thread to use crc32().
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
20
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 #ifdef MAKECRCH
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 # include <stdio.h>
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 # ifndef DYNAMIC_CRC_TABLE
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
27 # define DYNAMIC_CRC_TABLE
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 # endif /* !DYNAMIC_CRC_TABLE */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
29 #endif /* MAKECRCH */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
31 #include "zutil.h" /* for STDC and FAR definitions */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
33 /* Definitions for doing the crc four data bytes at a time. */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
34 #if !defined(NOBYFOUR) && defined(Z_U4)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 # define BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 #endif
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 #ifdef BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 local unsigned long crc32_little OF((unsigned long,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 const unsigned char FAR *, z_size_t));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 local unsigned long crc32_big OF((unsigned long,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 const unsigned char FAR *, z_size_t));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 # define TBLS 8
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 #else
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 # define TBLS 1
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 #endif /* BYFOUR */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 /* Local functions for crc concatenation */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 local unsigned long gf2_matrix_times OF((unsigned long *mat,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 unsigned long vec));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
51 local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
52
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 #ifdef DYNAMIC_CRC_TABLE
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 local volatile int crc_table_empty = 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 local z_crc_t FAR crc_table[TBLS][256];
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 local void make_crc_table OF((void));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 #ifdef MAKECRCH
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 local void write_table OF((FILE *, const z_crc_t FAR *));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 #endif /* MAKECRCH */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 /*
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 Polynomials over GF(2) are represented in binary, one bit per coefficient,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 with the lowest powers in the most significant bit. Then adding polynomials
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 is just exclusive-or, and multiplying a polynomial by x is a right shift by
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 one. If we call the above polynomial p, and represent a byte as the
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 polynomial q, also with the lowest power in the most significant bit (so the
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 where a mod b means the remainder after dividing a by b.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 This calculation is done using the shift-register method of multiplying and
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 taking the remainder. The register is initialized to zero, and for each
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 incoming bit, x^32 is added mod p to the register if the bit is a one (where
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 x (which is shifting right by one and adding x^32 mod p if the bit shifted
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79 out is a one). We start with the highest power (least significant bit) of
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 q and repeat for all eight bits of q.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 The first table is simply the CRC of all possible eight bit values. This is
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 all the information needed to generate CRCs on data a byte at a time for all
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
84 combinations of CRC register values and incoming bytes. The remaining tables
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
85 allow for word-at-a-time CRC calculation for both big-endian and little-
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 endian machines, where a word is four bytes.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
88 local void make_crc_table()
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 z_crc_t c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 int n, k;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 z_crc_t poly; /* polynomial exclusive-or pattern */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 /* terms of polynomial defining this crc (except x^32): */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 static volatile int first = 1; /* flag to limit concurrent making */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
95 static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 /* See if another task is already doing this (not thread-safe, but better
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98 than nothing -- significantly reduces duration of vulnerability in
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 case the advice about DYNAMIC_CRC_TABLE is ignored) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100 if (first) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 first = 0;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 /* make exclusive-or pattern from polynomial (0xedb88320UL) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 poly = 0;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106 poly |= (z_crc_t)1 << (31 - p[n]);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 /* generate a crc for every 8-bit value */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109 for (n = 0; n < 256; n++) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110 c = (z_crc_t)n;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 for (k = 0; k < 8; k++)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 crc_table[0][n] = c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 #ifdef BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 /* generate crc for each value followed by one, two, and three zeros,
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 and then the byte reversal of those as well as the first table */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119 for (n = 0; n < 256; n++) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 c = crc_table[0][n];
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121 crc_table[4][n] = ZSWAP32(c);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122 for (k = 1; k < 4; k++) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 c = crc_table[0][c & 0xff] ^ (c >> 8);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124 crc_table[k][n] = c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
125 crc_table[k + 4][n] = ZSWAP32(c);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 #endif /* BYFOUR */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 crc_table_empty = 0;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
132 else { /* not first */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
133 /* wait for the other guy to finish (not efficient, but rare) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 while (crc_table_empty)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 ;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 #ifdef MAKECRCH
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139 /* write out CRC tables to crc32.h */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 FILE *out;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 out = fopen("crc32.h", "w");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144 if (out == NULL) return;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
145 fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
146 fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 fprintf(out, "local const z_crc_t FAR ");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 write_table(out, crc_table[0]);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 # ifdef BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 fprintf(out, "#ifdef BYFOUR\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152 for (k = 1; k < 8; k++) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153 fprintf(out, " },\n {\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 write_table(out, crc_table[k]);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 fprintf(out, "#endif\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 # endif /* BYFOUR */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 fprintf(out, " }\n};\n");
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 fclose(out);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 #endif /* MAKECRCH */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
163
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
164 #ifdef MAKECRCH
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 local void write_table(out, table)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 FILE *out;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 const z_crc_t FAR *table;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
169 int n;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
170
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 for (n = 0; n < 256; n++)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
173 (unsigned long)(table[n]),
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
174 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
175 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
176 #endif /* MAKECRCH */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
177
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
178 #else /* !DYNAMIC_CRC_TABLE */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
179 /* ========================================================================
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
180 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
181 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
182 #include "crc32.h"
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
183 #endif /* DYNAMIC_CRC_TABLE */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
184
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
185 /* =========================================================================
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
186 * This function can be used by asm versions of crc32()
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
187 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
188 const z_crc_t FAR * ZEXPORT get_crc_table()
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
189 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
190 #ifdef DYNAMIC_CRC_TABLE
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
191 if (crc_table_empty)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
192 make_crc_table();
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
193 #endif /* DYNAMIC_CRC_TABLE */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
194 return (const z_crc_t FAR *)crc_table;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
195 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
196
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
197 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
198 #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
199 #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
200
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
201 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
202 unsigned long ZEXPORT crc32_z(crc, buf, len)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
203 unsigned long crc;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
204 const unsigned char FAR *buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
205 z_size_t len;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
206 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
207 if (buf == Z_NULL) return 0UL;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
208
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
209 #ifdef DYNAMIC_CRC_TABLE
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
210 if (crc_table_empty)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
211 make_crc_table();
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
212 #endif /* DYNAMIC_CRC_TABLE */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
213
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
214 #ifdef BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
215 if (sizeof(void *) == sizeof(ptrdiff_t)) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
216 z_crc_t endian;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
217
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
218 endian = 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
219 if (*((unsigned char *)(&endian)))
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
220 return crc32_little(crc, buf, len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
221 else
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
222 return crc32_big(crc, buf, len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
223 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
224 #endif /* BYFOUR */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
225 crc = crc ^ 0xffffffffUL;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
226 while (len >= 8) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
227 DO8;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
228 len -= 8;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
229 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
230 if (len) do {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
231 DO1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
232 } while (--len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
233 return crc ^ 0xffffffffUL;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
234 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
235
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
236 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
237 unsigned long ZEXPORT crc32(crc, buf, len)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
238 unsigned long crc;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
239 const unsigned char FAR *buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
240 uInt len;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
241 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
242 return crc32_z(crc, buf, len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
243 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
244
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
245 #ifdef BYFOUR
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
246
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
247 /*
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
248 This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
249 integer pointer type. This violates the strict aliasing rule, where a
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
250 compiler can assume, for optimization purposes, that two pointers to
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
251 fundamentally different types won't ever point to the same memory. This can
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
252 manifest as a problem only if one of the pointers is written to. This code
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
253 only reads from those pointers. So long as this code remains isolated in
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
254 this compilation unit, there won't be a problem. For this reason, this code
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
255 should not be copied and pasted into a compilation unit in which other code
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
256 writes to the buffer that is passed to these routines.
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
257 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
258
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
259 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
260 #define DOLIT4 c ^= *buf4++; \
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
261 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
262 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
263 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
264
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
265 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
266 local unsigned long crc32_little(crc, buf, len)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
267 unsigned long crc;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
268 const unsigned char FAR *buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
269 z_size_t len;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
270 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
271 register z_crc_t c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
272 register const z_crc_t FAR *buf4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
273
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
274 c = (z_crc_t)crc;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
275 c = ~c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
276 while (len && ((ptrdiff_t)buf & 3)) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
277 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
278 len--;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
279 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
280
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
281 buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
282 while (len >= 32) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
283 DOLIT32;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
284 len -= 32;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
285 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
286 while (len >= 4) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
287 DOLIT4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
288 len -= 4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
289 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
290 buf = (const unsigned char FAR *)buf4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
291
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
292 if (len) do {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
293 c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
294 } while (--len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
295 c = ~c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
296 return (unsigned long)c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
297 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
298
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
299 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
300 #define DOBIG4 c ^= *buf4++; \
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
301 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
302 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
303 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
304
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
305 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
306 local unsigned long crc32_big(crc, buf, len)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
307 unsigned long crc;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
308 const unsigned char FAR *buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
309 z_size_t len;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
310 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
311 register z_crc_t c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
312 register const z_crc_t FAR *buf4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
313
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
314 c = ZSWAP32((z_crc_t)crc);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
315 c = ~c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
316 while (len && ((ptrdiff_t)buf & 3)) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
317 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
318 len--;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
319 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
320
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
321 buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
322 while (len >= 32) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
323 DOBIG32;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
324 len -= 32;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
325 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
326 while (len >= 4) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
327 DOBIG4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
328 len -= 4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
329 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
330 buf = (const unsigned char FAR *)buf4;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
331
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
332 if (len) do {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
333 c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
334 } while (--len);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
335 c = ~c;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
336 return (unsigned long)(ZSWAP32(c));
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
337 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
338
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
339 #endif /* BYFOUR */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
340
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
341 #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
342
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
343 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
344 local unsigned long gf2_matrix_times(mat, vec)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
345 unsigned long *mat;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
346 unsigned long vec;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
347 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
348 unsigned long sum;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
349
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
350 sum = 0;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
351 while (vec) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
352 if (vec & 1)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
353 sum ^= *mat;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
354 vec >>= 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
355 mat++;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
356 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
357 return sum;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
358 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
359
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
360 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
361 local void gf2_matrix_square(square, mat)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
362 unsigned long *square;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
363 unsigned long *mat;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
364 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
365 int n;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
366
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
367 for (n = 0; n < GF2_DIM; n++)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
368 square[n] = gf2_matrix_times(mat, mat[n]);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
369 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
370
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
371 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
372 local uLong crc32_combine_(crc1, crc2, len2)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
373 uLong crc1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
374 uLong crc2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
375 z_off64_t len2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
376 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
377 int n;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
378 unsigned long row;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
379 unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
380 unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
381
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
382 /* degenerate case (also disallow negative lengths) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
383 if (len2 <= 0)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
384 return crc1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
385
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
386 /* put operator for one zero bit in odd */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
387 odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
388 row = 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
389 for (n = 1; n < GF2_DIM; n++) {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
390 odd[n] = row;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
391 row <<= 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
392 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
393
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
394 /* put operator for two zero bits in even */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
395 gf2_matrix_square(even, odd);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
396
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
397 /* put operator for four zero bits in odd */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
398 gf2_matrix_square(odd, even);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
399
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
400 /* apply len2 zeros to crc1 (first square will put the operator for one
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
401 zero byte, eight zero bits, in even) */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
402 do {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
403 /* apply zeros operator for this bit of len2 */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
404 gf2_matrix_square(even, odd);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
405 if (len2 & 1)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
406 crc1 = gf2_matrix_times(even, crc1);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
407 len2 >>= 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
408
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
409 /* if no more bits set, then done */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
410 if (len2 == 0)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
411 break;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
412
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
413 /* another iteration of the loop with odd and even swapped */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
414 gf2_matrix_square(odd, even);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
415 if (len2 & 1)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
416 crc1 = gf2_matrix_times(odd, crc1);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
417 len2 >>= 1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
418
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
419 /* if no more bits set, then done */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
420 } while (len2 != 0);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
421
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
422 /* return combined crc */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
423 crc1 ^= crc2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
424 return crc1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
425 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
426
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
427 /* ========================================================================= */
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
428 uLong ZEXPORT crc32_combine(crc1, crc2, len2)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
429 uLong crc1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
430 uLong crc2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
431 z_off_t len2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
432 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
433 return crc32_combine_(crc1, crc2, len2);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
434 }
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
435
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
436 uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
437 uLong crc1;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
438 uLong crc2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
439 z_off64_t len2;
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
440 {
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
441 return crc32_combine_(crc1, crc2, len2);
00d788dac91a Added support for reading gzipped ROMs
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
442 }