annotate zlib/crc32.c @ 1925:039553703c20

Don't apply address and cd register changes to the 'live' registers until pending flag is cleared, but do preserve the upper address bits in the latch. Fixes regression in Overdrive 2 while preserving fix to Mona in 344 bytes
author Michael Pavone <pavone@retrodev.com>
date Mon, 13 Apr 2020 20:43:25 -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 }