mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 15:26:35 +08:00
add: compress fpga images during compile, uncompress at run time
This commit is contained in:
parent
e61530408c
commit
add4d47046
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,6 +12,7 @@
|
|||
*.bin
|
||||
*.dll
|
||||
*.moc.cpp
|
||||
*.gz
|
||||
*.exe
|
||||
proxmark
|
||||
proxmark3
|
||||
|
|
1
Makefile
1
Makefile
|
@ -1,6 +1,5 @@
|
|||
include common/Makefile.common
|
||||
|
||||
GZIP=gzip
|
||||
FLASH_PORT=/dev/ttyACM0
|
||||
|
||||
all clean: %: bootrom/% armsrc/% client/% recovery/%
|
||||
|
|
|
@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
|
|||
|
||||
#remove one of the following defines and comment out the relevant line
|
||||
#in the next section to remove that particular feature from compilation
|
||||
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -fno-strict-aliasing -ffunction-sections -fdata-sections
|
||||
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE -DZ_SOLO -fno-strict-aliasing -ffunction-sections -fdata-sections
|
||||
#-DWITH_LCD
|
||||
|
||||
#SRC_LCD = fonts.c LCD.c
|
||||
|
@ -31,7 +31,11 @@ THUMBSRC = start.c \
|
|||
string.c \
|
||||
usb_cdc.c \
|
||||
cmd.c \
|
||||
inflate.c
|
||||
inflate.c \
|
||||
zutil.c \
|
||||
adler32.c \
|
||||
inftrees.c \
|
||||
inffast.c
|
||||
|
||||
# These are to be compiled in ARM mode
|
||||
ARMSRC = fpgaloader.c \
|
||||
|
@ -57,11 +61,14 @@ OBJS = $(OBJDIR)/osimage.s19
|
|||
|
||||
all: $(OBJS)
|
||||
|
||||
$(OBJDIR)/fpga_lf.o: fpga_lf.bit
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_lf_bit_start=_binary_fpga_lf_bit_start --redefine-sym _binary____fpga_fpga_lf_bit_end=_binary_fpga_lf_bit_end --prefix-sections=fpga_lf_bit $^ $@
|
||||
$(OBJDIR)/fpga_lf.o: $(OBJDIR)/fpga_lf.bit.gz
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary_obj_fpga_lf_bit_gz_start=_binary_fpga_lf_bit_start --redefine-sym _binary_obj_fpga_lf_bit_gz_end=_binary_fpga_lf_bit_end --prefix-sections=fpga_lf_bit $^ $@
|
||||
|
||||
$(OBJDIR)/fpga_hf.o: fpga_hf.bit
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary____fpga_fpga_hf_bit_start=_binary_fpga_hf_bit_start --redefine-sym _binary____fpga_fpga_hf_bit_end=_binary_fpga_hf_bit_end --prefix-sections=fpga_hf_bit $^ $@
|
||||
$(OBJDIR)/fpga_hf.o: $(OBJDIR)/fpga_hf.bit.gz
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --redefine-sym _binary_obj_fpga_hf_bit_gz_start=_binary_fpga_hf_bit_start --redefine-sym _binary_obj_fpga_hf_bit_gz_end=_binary_fpga_hf_bit_end --prefix-sections=fpga_hf_bit $^ $@
|
||||
|
||||
$(OBJDIR)/%.bit.gz: %.bit
|
||||
$(GZIP) --best -c $^ >$@
|
||||
|
||||
$(OBJDIR)/fullimage.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_lf.o $(OBJDIR)/fpga_hf.o $(THUMBOBJ) $(ARMOBJ)
|
||||
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
|
||||
|
@ -82,6 +89,7 @@ clean:
|
|||
$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
|
||||
$(DELETE) $(OBJDIR)$(PATHSEP)*.map
|
||||
$(DELETE) $(OBJDIR)$(PATHSEP)*.d
|
||||
$(DELETE) $(OBJDIR)$(PATHSEP)*.gz
|
||||
$(DELETE) version.c
|
||||
|
||||
.PHONY: all clean help
|
||||
|
|
179
armsrc/adler32.c
Normal file
179
armsrc/adler32.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2011 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
#define local static
|
||||
|
||||
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||
|
||||
#define BASE 65521 /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||
try it both ways to see which is faster */
|
||||
#ifdef NO_DIVIDE
|
||||
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||
(thank you to John Reiser for pointing this out) */
|
||||
# define CHOP(a) \
|
||||
do { \
|
||||
unsigned long tmp = a >> 16; \
|
||||
a &= 0xffffUL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
} while (0)
|
||||
# define MOD28(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
CHOP(a); \
|
||||
MOD28(a); \
|
||||
} while (0)
|
||||
# define MOD63(a) \
|
||||
do { /* this assumes a is not negative */ \
|
||||
z_off64_t tmp = a >> 32; \
|
||||
a &= 0xffffffffL; \
|
||||
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
tmp = a >> 16; \
|
||||
a &= 0xffffL; \
|
||||
a += (tmp << 4) - tmp; \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD28(a) a %= BASE
|
||||
# define MOD63(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD28(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
local uLong adler32_combine_(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||
if (len2 < 0)
|
||||
return 0xffffffffUL;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
MOD63(len2); /* assumes len2 >= 0 */
|
||||
rem = (unsigned)len2;
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum1 >= BASE) sum1 -= BASE;
|
||||
if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
|
||||
if (sum2 >= BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
||||
|
||||
uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off64_t len2;
|
||||
{
|
||||
return adler32_combine_(adler1, adler2, len2);
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
#include "mifare.h"
|
||||
#include "../common/crc32.h"
|
||||
#include "BigBuf.h"
|
||||
#include "fpgaloader.h"
|
||||
|
||||
extern const uint8_t OddByteParity[256];
|
||||
extern int rsamples; // = 0;
|
||||
|
@ -50,60 +51,6 @@ void ListenReaderField(int limit);
|
|||
extern int ToSendMax;
|
||||
extern uint8_t ToSend[];
|
||||
|
||||
/// fpga.h
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||
void FpgaWriteConfWord(uint8_t v);
|
||||
void FpgaDownloadAndGo(int bitstream_version);
|
||||
int FpgaGatherBitstreamVersion();
|
||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len);
|
||||
void FpgaSetupSsc(void);
|
||||
void SetupSpi(int mode);
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
void SetAdcMuxFor(uint32_t whichGpio);
|
||||
|
||||
// Definitions for the FPGA commands.
|
||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
||||
// Definitions for the FPGA configuration word.
|
||||
// LF
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||
// HF
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
||||
// BOTH
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||
// Options for LF_ADC
|
||||
#define FPGA_LF_ADC_READER_FIELD (1<<0)
|
||||
// Options for LF_EDGE_DETECT
|
||||
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
||||
// Options for the HF reader, tx to tag
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||
// Options for the HF reader, correlating against rx from tag
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||
// Options for the HF simulated tag, how to modulate
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5//101
|
||||
|
||||
// Options for ISO14443A
|
||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||
|
||||
/// lfops.h
|
||||
extern uint8_t decimation;
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -9,10 +9,18 @@
|
|||
// Routines to load the FPGA image, and then to configure the FPGA's major
|
||||
// mode once it is configured.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "fpgaloader.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "BigBuf.h"
|
||||
#include "zlib.h"
|
||||
|
||||
extern void Dbprintf(const char *fmt, ...);
|
||||
|
||||
// remember which version of the bitstream we have already downloaded to the FPGA
|
||||
static int downloaded_bitstream = FPGA_BITSTREAM_ERR;
|
||||
|
@ -23,9 +31,8 @@ extern uint8_t _binary_fpga_hf_bit_start, _binary_fpga_hf_bit_end;
|
|||
static uint8_t *fpga_image_ptr = NULL;
|
||||
|
||||
static const uint8_t _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
|
||||
static const uint8_t _gzip_header[] = {0x1f, 0x8b, 0x08}; // including compression method 0x08 (deflate)
|
||||
#define GZIP_HEADER_SIZE sizeof(_gzip_header)
|
||||
#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(_bitparse_fixed_header)
|
||||
#define OUTPUT_BUFFER_LEN 80
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up the Serial Peripheral Interface as master
|
||||
|
@ -164,15 +171,86 @@ bool FpgaSetupSscDma(uint8_t *buf, int len)
|
|||
}
|
||||
|
||||
|
||||
void reset_fpga_stream(uint8_t *image_start)
|
||||
uint8_t get_from_fpga_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
||||
{
|
||||
fpga_image_ptr = image_start;
|
||||
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
fpga_image_ptr = output_buffer;
|
||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
||||
// if (res != Z_OK && res != Z_STREAM_END) {
|
||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
||||
// }
|
||||
}
|
||||
|
||||
Dbprintf("get_from_fpga_stream() returns %02x", *fpga_image_ptr);
|
||||
return *fpga_image_ptr++;
|
||||
}
|
||||
|
||||
|
||||
uint8_t get_from_fpga_stream(void)
|
||||
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
return *fpga_image_ptr++;
|
||||
Dbprintf("zlib requested %d bytes", items*size);
|
||||
return BigBuf_malloc(items*size);
|
||||
}
|
||||
|
||||
|
||||
static void fpga_inflate_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
Dbprintf("zlib wants to free memory");
|
||||
BigBuf_free_keep_EM();
|
||||
}
|
||||
|
||||
|
||||
void init_fpga_inflate(z_streamp compressed_fpga_stream, uint8_t *fpga_image_start, uint32_t fpga_image_size, uint8_t *output_buffer)
|
||||
{
|
||||
// initialize z_stream structure for inflate:
|
||||
compressed_fpga_stream->next_in = fpga_image_start;
|
||||
compressed_fpga_stream->avail_in = fpga_image_size;
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
||||
|
||||
// initialize inflate to automatically detect header:
|
||||
int res = inflateInit2(compressed_fpga_stream, 15+32);
|
||||
|
||||
fpga_image_ptr = output_buffer;
|
||||
|
||||
Dbprintf("InflateInit returned %d", res);
|
||||
Dbprintf("fpga_image_ptr pointing at %02x %02x %02x %02x", fpga_image_ptr[0], fpga_image_ptr[1], fpga_image_ptr[2], fpga_image_ptr[3]);
|
||||
Dbprintf("zstream->next_in pointing at %02x %02x %02x %02x", compressed_fpga_stream->next_in[0], compressed_fpga_stream->next_in[1], compressed_fpga_stream->next_in[2], compressed_fpga_stream->next_in[3]);
|
||||
}
|
||||
|
||||
|
||||
bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
||||
{
|
||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||
uint8_t *fpga_image_start;
|
||||
uint32_t fpga_image_size;
|
||||
|
||||
if (bitstream_version == FPGA_BITSTREAM_LF) {
|
||||
fpga_image_start = &_binary_fpga_lf_bit_start;
|
||||
fpga_image_size = (uint32_t)&_binary_fpga_lf_bit_end - (uint32_t)&_binary_fpga_lf_bit_start;
|
||||
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
|
||||
fpga_image_start = &_binary_fpga_hf_bit_start;
|
||||
fpga_image_size = (uint32_t)&_binary_fpga_hf_bit_end - (uint32_t)&_binary_fpga_hf_bit_start;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
init_fpga_inflate(compressed_fpga_stream, fpga_image_start, fpga_image_size, output_buffer);
|
||||
|
||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
|
||||
header[i] = get_from_fpga_stream(compressed_fpga_stream, output_buffer);
|
||||
}
|
||||
|
||||
// Check for a valid .bit file (starts with _bitparse_fixed_header)
|
||||
if(memcmp(_bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,8 +268,11 @@ static void DownloadFPGA_byte(unsigned char w)
|
|||
}
|
||||
|
||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
||||
static void DownloadFPGA(int FpgaImageLen)
|
||||
static void DownloadFPGA(int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
||||
{
|
||||
Dbprintf("Would have loaded FPGA");
|
||||
return;
|
||||
|
||||
int i=0;
|
||||
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
||||
|
@ -244,7 +325,7 @@ static void DownloadFPGA(int FpgaImageLen)
|
|||
}
|
||||
|
||||
while(FpgaImageLen-->0) {
|
||||
DownloadFPGA_byte(get_from_fpga_stream());
|
||||
DownloadFPGA_byte(get_from_fpga_stream(compressed_fpga_stream, output_buffer));
|
||||
}
|
||||
|
||||
// continue to clock FPGA until ready signal goes high
|
||||
|
@ -269,13 +350,13 @@ static void DownloadFPGA(int FpgaImageLen)
|
|||
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
|
||||
* length.
|
||||
*/
|
||||
int bitparse_find_section(char section_name, unsigned int *section_length)
|
||||
int bitparse_find_section(char section_name, unsigned int *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
|
||||
{
|
||||
int result = 0;
|
||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||
uint16_t numbytes = 0;
|
||||
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||
char current_name = get_from_fpga_stream();
|
||||
char current_name = get_from_fpga_stream(compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
unsigned int current_length = 0;
|
||||
if(current_name < 'a' || current_name > 'e') {
|
||||
|
@ -286,12 +367,12 @@ int bitparse_find_section(char section_name, unsigned int *section_length)
|
|||
switch(current_name) {
|
||||
case 'e':
|
||||
/* Four byte length field */
|
||||
current_length += get_from_fpga_stream() << 24;
|
||||
current_length += get_from_fpga_stream() << 16;
|
||||
current_length += get_from_fpga_stream(compressed_fpga_stream, output_buffer) << 24;
|
||||
current_length += get_from_fpga_stream(compressed_fpga_stream, output_buffer) << 16;
|
||||
numbytes += 2;
|
||||
default: /* Fall through, two byte length field */
|
||||
current_length += get_from_fpga_stream() << 8;
|
||||
current_length += get_from_fpga_stream() << 0;
|
||||
current_length += get_from_fpga_stream(compressed_fpga_stream, output_buffer) << 8;
|
||||
current_length += get_from_fpga_stream(compressed_fpga_stream, output_buffer) << 0;
|
||||
numbytes += 2;
|
||||
}
|
||||
|
||||
|
@ -308,7 +389,7 @@ int bitparse_find_section(char section_name, unsigned int *section_length)
|
|||
}
|
||||
|
||||
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
|
||||
get_from_fpga_stream();
|
||||
get_from_fpga_stream(compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
}
|
||||
}
|
||||
|
@ -316,11 +397,6 @@ int bitparse_find_section(char section_name, unsigned int *section_length)
|
|||
return result;
|
||||
}
|
||||
|
||||
void init_fpga_inflate(void)
|
||||
{
|
||||
// initialize zlib for inflate
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find out which FPGA image format is stored in flash, then call DownloadFPGA
|
||||
|
@ -328,71 +404,42 @@ void init_fpga_inflate(void)
|
|||
//-----------------------------------------------------------------------------
|
||||
void FpgaDownloadAndGo(int bitstream_version)
|
||||
{
|
||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||
z_stream compressed_fpga_stream;
|
||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN];
|
||||
|
||||
// check whether or not the bitstream is already loaded
|
||||
if (downloaded_bitstream == bitstream_version)
|
||||
return;
|
||||
|
||||
if (bitstream_version == FPGA_BITSTREAM_LF) {
|
||||
reset_fpga_stream(&_binary_fpga_lf_bit_start);
|
||||
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
|
||||
reset_fpga_stream(&_binary_fpga_hf_bit_start);
|
||||
} else
|
||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
|
||||
return;
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < GZIP_HEADER_SIZE; i++) {
|
||||
header[i] = get_from_fpga_stream();
|
||||
}
|
||||
|
||||
// Check for compressed new flash image format (starts with gzip header)
|
||||
if(memcmp(_gzip_header, header, GZIP_HEADER_SIZE) == 0) {
|
||||
init_fpga_inflate();
|
||||
}
|
||||
|
||||
for (; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
|
||||
header[i] = get_from_fpga_stream();
|
||||
}
|
||||
|
||||
// Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
|
||||
if(memcmp(_bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
|
||||
unsigned int bitstream_length;
|
||||
if(bitparse_find_section('e', &bitstream_length)) {
|
||||
DownloadFPGA(bitstream_length);
|
||||
if(bitparse_find_section('e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||
DownloadFPGA(bitstream_length, &compressed_fpga_stream, output_buffer);
|
||||
downloaded_bitstream = bitstream_version;
|
||||
return; /* All done */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FpgaGatherBitstreamVersion()
|
||||
{
|
||||
return downloaded_bitstream;
|
||||
}
|
||||
|
||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
||||
{
|
||||
unsigned int fpga_info_len;
|
||||
char tempstr[40];
|
||||
z_stream compressed_fpga_stream;
|
||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN];
|
||||
|
||||
dst[0] = '\0';
|
||||
|
||||
if (bitstream_version == FPGA_BITSTREAM_LF) {
|
||||
reset_fpga_stream(&_binary_fpga_lf_bit_start);
|
||||
} else if (bitstream_version == FPGA_BITSTREAM_HF) {
|
||||
reset_fpga_stream(&_binary_fpga_hf_bit_start);
|
||||
} else
|
||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
|
||||
return;
|
||||
|
||||
|
||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
|
||||
get_from_fpga_stream();
|
||||
}
|
||||
|
||||
if(bitparse_find_section('a', &fpga_info_len)) {
|
||||
if(bitparse_find_section('a', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
char c = (char)get_from_fpga_stream(&compressed_fpga_stream, output_buffer);
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
|
@ -403,30 +450,30 @@ void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
|||
strncat(dst, "HF ", len-1);
|
||||
}
|
||||
strncat(dst, "FPGA image built", len-1);
|
||||
if(bitparse_find_section('b', &fpga_info_len)) {
|
||||
if(bitparse_find_section('b', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
||||
strncat(dst, " for ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
char c = (char)get_from_fpga_stream(&compressed_fpga_stream, output_buffer);
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
strncat(dst, tempstr, len-1);
|
||||
}
|
||||
if(bitparse_find_section('c', &fpga_info_len)) {
|
||||
if(bitparse_find_section('c', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
||||
strncat(dst, " on ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
char c = (char)get_from_fpga_stream(&compressed_fpga_stream, output_buffer);
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
}
|
||||
strncat(dst, tempstr, len-1);
|
||||
}
|
||||
if(bitparse_find_section('d', &fpga_info_len)) {
|
||||
if(bitparse_find_section('d', &fpga_info_len, &compressed_fpga_stream, output_buffer)) {
|
||||
strncat(dst, " at ", len-1);
|
||||
for (uint16_t i = 0; i < fpga_info_len; i++) {
|
||||
char c = (char)get_from_fpga_stream();
|
||||
char c = (char)get_from_fpga_stream(&compressed_fpga_stream, output_buffer);
|
||||
if (i < sizeof(tempstr)) {
|
||||
tempstr[i] = c;
|
||||
}
|
||||
|
@ -435,6 +482,7 @@ void FpgaGatherVersion(int bitstream_version, char *dst, int len)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Send a 16 bit command/data pair to the FPGA.
|
||||
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
|
||||
|
|
64
armsrc/fpgaloader.h
Normal file
64
armsrc/fpgaloader.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, April 2006
|
||||
// iZsh <izsh at fail0verflow.com>, 2014
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Routines to load the FPGA image, and then to configure the FPGA's major
|
||||
// mode once it is configured.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||
void FpgaWriteConfWord(uint8_t v);
|
||||
void FpgaDownloadAndGo(int bitstream_version);
|
||||
void FpgaGatherVersion(int bitstream_version, char *dst, int len);
|
||||
void FpgaSetupSsc(void);
|
||||
void SetupSpi(int mode);
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
void SetAdcMuxFor(uint32_t whichGpio);
|
||||
|
||||
// Definitions for the FPGA commands.
|
||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
||||
// Definitions for the FPGA configuration word.
|
||||
// LF
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||
// HF
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
||||
// BOTH
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||
// Options for LF_ADC
|
||||
#define FPGA_LF_ADC_READER_FIELD (1<<0)
|
||||
// Options for LF_EDGE_DETECT
|
||||
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
||||
// Options for the HF reader, tx to tag
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||
// Options for the HF reader, correlating against rx from tag
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||
// Options for the HF simulated tag, how to modulate
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5//101
|
||||
|
||||
// Options for ISO14443A
|
||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
340
armsrc/inffast.c
Normal file
340
armsrc/inffast.c
Normal file
|
@ -0,0 +1,340 @@
|
|||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2008, 2010, 2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
|
||||
#ifndef ASMINF
|
||||
|
||||
/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||
Based on testing to date,
|
||||
Pre-increment preferred for:
|
||||
- PowerPC G3 (Adler)
|
||||
- MIPS R5000 (Randers-Pehrson)
|
||||
Post-increment preferred for:
|
||||
- none
|
||||
No measurable difference:
|
||||
- Pentium III (Anderson)
|
||||
- M68060 (Nikl)
|
||||
*/
|
||||
#ifdef POSTINC
|
||||
# define OFF 0
|
||||
# define PUP(a) *(a)++
|
||||
#else
|
||||
# define OFF 1
|
||||
# define PUP(a) *++(a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
literal and match bytes until either not enough input or output is
|
||||
available, an end-of-block is encountered, or a data error is encountered.
|
||||
When large enough input and output buffers are supplied to inflate(), for
|
||||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||||
inflate execution time is spent in this routine.
|
||||
|
||||
Entry assumptions:
|
||||
|
||||
state->mode == LEN
|
||||
strm->avail_in >= 6
|
||||
strm->avail_out >= 258
|
||||
start >= strm->avail_out
|
||||
state->bits < 8
|
||||
|
||||
On return, state->mode is one of:
|
||||
|
||||
LEN -- ran out of enough output space or enough available input
|
||||
TYPE -- reached end of block code, inflate() to interpret next block
|
||||
BAD -- error in block data
|
||||
|
||||
Notes:
|
||||
|
||||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||||
Therefore if strm->avail_in >= 6, then there is enough input to avoid
|
||||
checking for available input while decoding.
|
||||
|
||||
- The maximum bytes that a single length/distance pair can output is 258
|
||||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void ZLIB_INTERNAL inflate_fast(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
z_const unsigned char FAR *in; /* local strm->next_in */
|
||||
z_const unsigned char FAR *last; /* have enough input while in < last */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned wnext; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
code const FAR *lcode; /* local strm->lencode */
|
||||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code here; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char FAR *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
in = strm->next_in - OFF;
|
||||
last = in + (strm->avail_in - 5);
|
||||
out = strm->next_out - OFF;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - 257);
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
wnext = state->wnext;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", here.val));
|
||||
PUP(out) = (unsigned char)(here.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
here = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(here.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(here.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(here.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
if (state->sane) {
|
||||
strm->msg =
|
||||
(char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
|
||||
if (len <= op - whave) {
|
||||
do {
|
||||
PUP(out) = 0;
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
len -= op - whave;
|
||||
do {
|
||||
PUP(out) = 0;
|
||||
} while (--op > whave);
|
||||
if (op == 0) {
|
||||
from = out - dist;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--len);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
from = window - OFF;
|
||||
if (wnext == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (wnext < op) { /* wrap around window */
|
||||
from += wsize + wnext - op;
|
||||
op -= wnext;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = window - OFF;
|
||||
if (wnext < len) { /* some from start of window */
|
||||
op = wnext;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += wnext - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
else {
|
||||
from = out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
here = dcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
here = lcode[here.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in + OFF;
|
||||
strm->next_out = out + OFF;
|
||||
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||
strm->avail_out = (unsigned)(out < end ?
|
||||
257 + (end - out) : 257 - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
|
||||
- Using bit fields for code structure
|
||||
- Different op definition to avoid & for extra bits (do & for table bits)
|
||||
- Three separate decoding do-loops for direct, window, and wnext == 0
|
||||
- Special case for distance > 1 copies to do overlapped load and store copy
|
||||
- Explicit branch predictions (based on measured branch probabilities)
|
||||
- Deferring match copy and interspersed it with decoding subsequent codes
|
||||
- Swapping literal/length else
|
||||
- Swapping window/direct else
|
||||
- Larger unrolled copy loops (three is about right)
|
||||
- Moving len -= 3 statement into middle of loop
|
||||
*/
|
||||
|
||||
#endif /* !ASMINF */
|
302
armsrc/inftrees.c
Normal file
302
armsrc/inftrees.c
Normal file
|
@ -0,0 +1,302 @@
|
|||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2013 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
include such an acknowledgment, I would appreciate that you keep this
|
||||
copyright string in the executable of your product.
|
||||
*/
|
||||
|
||||
/*
|
||||
Build a set of tables to decode the provided canonical Huffman code.
|
||||
The code lengths are lens[0..codes-1]. The result starts at *table,
|
||||
whose indices are 0..2^bits-1. work is a writable array of at least
|
||||
lens shorts, which is used as a work area. type is the type of code
|
||||
to be generated, CODES, LENS, or DISTS. On return, zero is success,
|
||||
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
|
||||
on return points to the next available entry's address. bits is the
|
||||
requested root table index bits, and on return it is the actual root
|
||||
table index bits. It will differ if the request is greater than the
|
||||
longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work)
|
||||
{
|
||||
unsigned len; /* a code's length in bits */
|
||||
unsigned sym; /* index of code symbols */
|
||||
unsigned min, max; /* minimum and maximum code lengths */
|
||||
unsigned root; /* number of index bits for root table */
|
||||
unsigned curr; /* number of index bits for current table */
|
||||
unsigned drop; /* code bits to drop for sub-table */
|
||||
int left; /* number of prefix codes available */
|
||||
unsigned used; /* code entries in table used */
|
||||
unsigned huff; /* Huffman code */
|
||||
unsigned incr; /* for incrementing code, index */
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code here; /* table entry for duplication */
|
||||
code FAR *next; /* next available space in table */
|
||||
const unsigned short FAR *base; /* base value table to use */
|
||||
const unsigned short FAR *extra; /* extra bits table to use */
|
||||
int end; /* use base and extra for symbol > end */
|
||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577, 0, 0};
|
||||
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64};
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++)
|
||||
count[len] = 0;
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
count[lens[sym]]++;
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = *bits;
|
||||
for (max = MAXBITS; max >= 1; max--)
|
||||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)1;
|
||||
here.val = (unsigned short)0;
|
||||
*(*table)++ = here; /* make a table to force an error */
|
||||
*(*table)++ = here;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min < max; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) return -1; /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type == CODES || max != 1))
|
||||
return -1; /* incomplete set */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++)
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked for LENS and DIST tables against
|
||||
the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
|
||||
the initial root table size constants. See the comments in inftrees.h
|
||||
for more information.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base -= 257;
|
||||
extra = lext;
|
||||
extra -= 257;
|
||||
end = 256;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = *table; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = (unsigned)(-1); /* trigger new sub-table when len > root */
|
||||
used = 1U << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
here.op = (unsigned char)0;
|
||||
here.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
here.op = (unsigned char)(extra[work[sym]]);
|
||||
here.val = base[work[sym]];
|
||||
}
|
||||
else {
|
||||
here.op = (unsigned char)(32 + 64); /* end of block */
|
||||
here.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1U << (len - drop);
|
||||
fill = 1U << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = here;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) == 0) {
|
||||
if (len == max) break;
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) != low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop == 0)
|
||||
drop = root;
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = (int)(1 << curr);
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) break;
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if ((type == LENS && used > ENOUGH_LENS) ||
|
||||
(type == DISTS && used > ENOUGH_DISTS))
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
(*table)[low].op = (unsigned char)curr;
|
||||
(*table)[low].bits = (unsigned char)root;
|
||||
(*table)[low].val = (unsigned short)(next - *table);
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||
at most one remaining entry, since if the code is incomplete, the
|
||||
maximum code length that was allowed to get this far is one bit) */
|
||||
if (huff != 0) {
|
||||
here.op = (unsigned char)64; /* invalid code marker */
|
||||
here.bits = (unsigned char)(len - drop);
|
||||
here.val = (unsigned short)0;
|
||||
next[huff] = here;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
*table += used;
|
||||
*bits = root;
|
||||
return 0;
|
||||
}
|
324
armsrc/zutil.c
Normal file
324
armsrc/zutil.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
#ifndef Z_SOLO
|
||||
# include "gzguts.h"
|
||||
#endif
|
||||
|
||||
#ifndef NO_DUMMY_DECL
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
z_const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
"file error", /* Z_ERRNO (-1) */
|
||||
"stream error", /* Z_STREAM_ERROR (-2) */
|
||||
"data error", /* Z_DATA_ERROR (-3) */
|
||||
"insufficient memory", /* Z_MEM_ERROR (-4) */
|
||||
"buffer error", /* Z_BUF_ERROR (-5) */
|
||||
"incompatible version",/* Z_VERSION_ERROR (-6) */
|
||||
""};
|
||||
|
||||
|
||||
const char * ZEXPORT zlibVersion()
|
||||
{
|
||||
return ZLIB_VERSION;
|
||||
}
|
||||
|
||||
uLong ZEXPORT zlibCompileFlags()
|
||||
{
|
||||
uLong flags;
|
||||
|
||||
flags = 0;
|
||||
switch ((int)(sizeof(uInt))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1; break;
|
||||
case 8: flags += 2; break;
|
||||
default: flags += 3;
|
||||
}
|
||||
switch ((int)(sizeof(uLong))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 2; break;
|
||||
case 8: flags += 2 << 2; break;
|
||||
default: flags += 3 << 2;
|
||||
}
|
||||
switch ((int)(sizeof(voidpf))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 4; break;
|
||||
case 8: flags += 2 << 4; break;
|
||||
default: flags += 3 << 4;
|
||||
}
|
||||
switch ((int)(sizeof(z_off_t))) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 6; break;
|
||||
case 8: flags += 2 << 6; break;
|
||||
default: flags += 3 << 6;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
#ifdef BUILDFIXED
|
||||
flags += 1 << 12;
|
||||
#endif
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
flags += 1 << 13;
|
||||
#endif
|
||||
#ifdef NO_GZCOMPRESS
|
||||
flags += 1L << 16;
|
||||
#endif
|
||||
#ifdef NO_GZIP
|
||||
flags += 1L << 17;
|
||||
#endif
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
flags += 1L << 20;
|
||||
#endif
|
||||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||
# ifdef NO_vsnprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_vsprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
flags += 1L << 24;
|
||||
# ifdef NO_snprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_sprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_snprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
# ifndef verbose
|
||||
# define verbose 0
|
||||
# endif
|
||||
int ZLIB_INTERNAL z_verbose = verbose;
|
||||
|
||||
void ZLIB_INTERNAL z_error (m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* exported to allow conversion of error code to string for compress() and
|
||||
* uncompress()
|
||||
*/
|
||||
const char * ZEXPORT zError(err)
|
||||
int err;
|
||||
{
|
||||
return ERR_MSG(err);
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used.
|
||||
*/
|
||||
int errno = 0;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MEMCPY
|
||||
|
||||
void ZLIB_INTERNAL zmemcpy(dest, source, len)
|
||||
Bytef* dest;
|
||||
const Bytef* source;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = *source++; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
|
||||
int ZLIB_INTERNAL zmemcmp(s1, s2, len)
|
||||
const Bytef* s1;
|
||||
const Bytef* s2;
|
||||
uInt len;
|
||||
{
|
||||
uInt j;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zmemzero(dest, len)
|
||||
Bytef* dest;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = 0; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef Z_SOLO
|
||||
|
||||
#ifdef SYS16BIT
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* Turbo C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
|
||||
* and farmalloc(64K) returns a pointer with an offset of 8, so we
|
||||
* must fix the pointer. Warning: the pointer must be put back to its
|
||||
* original form in order to free it, use zcfree().
|
||||
*/
|
||||
|
||||
#define MAX_PTR 10
|
||||
/* 10*64K = 640K */
|
||||
|
||||
local int next_ptr = 0;
|
||||
|
||||
typedef struct ptr_table_s {
|
||||
voidpf org_ptr;
|
||||
voidpf new_ptr;
|
||||
} ptr_table;
|
||||
|
||||
local ptr_table table[MAX_PTR];
|
||||
/* This table is used to remember the original form of pointers
|
||||
* to large buffers (64K). Such pointers are normalized with a zero offset.
|
||||
* Since MSDOS is not a preemptive multitasking OS, this table is not
|
||||
* protected from concurrent access. This hack doesn't work anyway on
|
||||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf = opaque; /* just to make some compilers happy */
|
||||
ulg bsize = (ulg)items*size;
|
||||
|
||||
/* If we allocate less than 65520 bytes, we assume that farmalloc
|
||||
* will return a usable pointer which doesn't have to be normalized.
|
||||
*/
|
||||
if (bsize < 65520L) {
|
||||
buf = farmalloc(bsize);
|
||||
if (*(ush*)&buf != 0) return buf;
|
||||
} else {
|
||||
buf = farmalloc(bsize + 16L);
|
||||
}
|
||||
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
|
||||
table[next_ptr].org_ptr = buf;
|
||||
|
||||
/* Normalize the pointer to seg:0 */
|
||||
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
|
||||
*(ush*)&buf = 0;
|
||||
table[next_ptr++].new_ptr = buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
if (*(ush*)&ptr != 0) { /* object < 64K */
|
||||
farfree(ptr);
|
||||
return;
|
||||
}
|
||||
/* Find the original pointer */
|
||||
for (n = 0; n < next_ptr; n++) {
|
||||
if (ptr != table[n].new_ptr) continue;
|
||||
|
||||
farfree(table[n].org_ptr);
|
||||
while (++n < next_ptr) {
|
||||
table[n-1] = table[n];
|
||||
}
|
||||
next_ptr--;
|
||||
return;
|
||||
}
|
||||
ptr = opaque; /* just to make some compilers happy */
|
||||
Assert(0, "zcfree: ptr not found");
|
||||
}
|
||||
|
||||
#endif /* __TURBOC__ */
|
||||
|
||||
|
||||
#ifdef M_I86
|
||||
/* Microsoft C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
|
||||
# define _halloc halloc
|
||||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
_hfree(ptr);
|
||||
}
|
||||
|
||||
#endif /* M_I86 */
|
||||
|
||||
#endif /* SYS16BIT */
|
||||
|
||||
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef STDC
|
||||
extern voidp malloc OF((uInt size));
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
{
|
||||
if (opaque) items += size - size; /* make compiler happy */
|
||||
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
|
||||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
free(ptr);
|
||||
if (opaque) return; /* make compiler happy */
|
||||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
|
||||
#endif /* !Z_SOLO */
|
|
@ -25,6 +25,7 @@ CC = $(CROSS)gcc
|
|||
AS = $(CROSS)as
|
||||
LD = $(CROSS)ld
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
GZIP=gzip
|
||||
|
||||
OBJDIR = obj
|
||||
|
||||
|
|
Loading…
Reference in a new issue