1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-22 12:30:41 +00:00

Update from Piotr

git-svn-id: svn://svn.cc65.org/cc65/trunk@1124 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-11-18 20:05:57 +00:00
parent 2de4a26251
commit f2967f26fc
5 changed files with 1100 additions and 690 deletions

View File

@ -1,53 +1,172 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* zlib.h */ /* zlib.h */
/* */ /* */
/* Decompression routines for the 'deflate' format */ /* Decompression routines for the 'deflate' format */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 2000-2001 Piotr Fusik */ /* (C) 2000-2001 Piotr Fusik <fox@scene.pl> */
/* a.k.a. Fox/Taquart */ /* */
/* EMail: fox@scene.pl */ /* This file is based on the zlib.h from 'zlib' general purpose compression */
/* */ /* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* Jean-loup Gailly Mark Adler */
/* warranty. In no event will the authors be held liable for any damages */ /* jloup@gzip.org madler@alumni.caltech.edu */
/* arising from the use of this software. */ /* */
/* */ /* This software is provided 'as-is', without any expressed or implied */
/* Permission is granted to anyone to use this software for any purpose, */ /* warranty. In no event will the authors be held liable for any damages */
/* including commercial applications, and to alter it and redistribute it */ /* arising from the use of this software. */
/* freely, subject to the following restrictions: */ /* */
/* */ /* Permission is granted to anyone to use this software for any purpose, */
/* 1. The origin of this software must not be misrepresented; you must not */ /* including commercial applications, and to alter it and redistribute it */
/* claim that you wrote the original software. If you use this software */ /* freely, subject to the following restrictions: */
/* in a product, an acknowledgment in the product documentation would be */ /* */
/* appreciated but is not required. */ /* 1. The origin of this software must not be misrepresented; you must not */
/* 2. Altered source versions must be plainly marked as such, and must not */ /* claim that you wrote the original software. If you use this software */
/* be misrepresented as being the original software. */ /* in a product, an acknowledgment in the product documentation would be */
/* 3. This notice may not be removed or altered from any source */ /* appreciated but is not required. */
/* distribution. */ /* 2. Altered source versions must be plainly marked as such, and must not */
/* */ /* be misrepresented as being the original software. */
/*****************************************************************************/ /* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef _ZLIB_H
#define _ZLIB_H
#ifndef _ZLIB_H
#define _ZLIB_H
void* inflatemem (void* dest, void* src);
/* Read the deflate compressed data starting from src and store #define Z_OK 0
* the uncompressed data starting from dest. #define Z_DATA_ERROR (-3)
* Return pointer to a byte after the decompressed data. That is, the result /* Return codes for uncompress() */
* minus dest is the size of the decompressed data.
*/ #define Z_DEFLATED 8
/* The deflate compression method (the only one supported) */
#define Z_NULL 0
/* end of zlib.h */
#endif
unsigned __fastcall__ inflatemem (char* dest, const char* source);
/*
Decompresses the source buffer into the destination buffer.
Returns the size of the uncompressed data (number of bytes written starting
from dest).
This function expects data in the DEFLATE format, described in RFC
(Request for Comments) 1951 in the file
ftp://ds.internic.net/rfc/rfc1951.txt.
This function does not exist in the original zlib. Its implementation
using original zlib might be following:
unsigned inflatemem (char* dest, const char* source)
{
z_stream stream;
stream.next_in = (Bytef*) source;
stream.avail_in = 65535;
stream.next_out = dest;
stream.avail_out = 65535;
stream.zalloc = (alloc_func) 0;
stream.zfree = (free_func) 0;
inflateInit2(&stream, -MAX_WBITS);
inflate(&stream, Z_FINISH);
inflateEnd(&stream);
return stream.total_out;
}
*/
int uncompress (char* dest, unsigned* destLen,
const char* source, unsigned sourceLen);
/*
Original zlib description:
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
Implementation notes:
This function expects data in the ZLIB format, described in RFC 1950
in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is
essentially the DEFLATE format plus a very small header and Adler-32
checksum.
Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.
*/
unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns
the required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
much faster. Usage example:
unsigned long adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
Implementation notes:
This function isn't actually much faster than crc32(), but it is smaller
and does not use any lookup tables.
*/
unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running crc with the bytes buf[0..len-1] and return the updated
crc. If buf is NULL, this function returns the required initial value
for the crc. Pre- and post-conditioning (one's complement) is performed
within this function so it shouldn't be done by the application.
Usage example:
unsigned long crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
Implementation notes:
This function uses statically allocated 1 KB lookup table. The table is
initialised before it is used for the first time (that is, if buffer is
NULL or length is zero, then the lookup table isn't initialised).
*/
/* end of zlib.h */
#endif

85
libsrc/zlib/adler32.s Normal file
View File

@ -0,0 +1,85 @@
;
; Piotr Fusik, 18.11.2001
;
; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf,
; unsigned len);
;
.export _adler32
.import incsp2, incsp4, popax, popeax
.importzp sreg, ptr1, ptr2, tmp1
BASE = 65521 ; largest prime smaller than 65536
_adler32:
; ptr2 = (len & 0xff) == 0 ? len : len + 0x100;
tay
beq @L1
inx
@L1: sta ptr2
stx ptr2+1
; ptr1 = buf
jsr popax
sta ptr1
stx ptr1+1
; if (buf == NULL) return 1L;
ora ptr1+1
beq @L0
; s1 = adler & 0xFFFF; s2 = adler >> 16;
jsr popeax
; if (len == 0) return adler;
ldy ptr2
bne @L2
ldy ptr2+1
beq @RET
@L2: ldy #0
; s1 += *ptr++; if (s1 >= BASE) s1 -= BASE;
@L3: clc
adc (ptr1),y
bcc @L4
inx
beq @L5 ; C flag is set
@L4: cpx #>BASE
bcc @L6
cmp #<BASE
bcc @L6
inx ; ldx #0
@L5: sbc #<BASE ; C flag is set
clc
@L6: sta tmp1
; s2 += s1; if (s2 >= BASE) s2 -= BASE;
adc sreg ; C flag is clear
sta sreg
txa
adc sreg+1
sta sreg+1
bcs @L7
cmp #>BASE
bcc @L8
lda sreg
cmp #<BASE
bcc @L8
@L7: lda sreg
sbc #<BASE ; C flag is set
sta sreg
lda sreg+1
sbc #>BASE
sta sreg+1
@L8: lda tmp1
iny
bne @L9
inc ptr1+1
@L9: dec ptr2
bne @L3
dec ptr2+1
bne @L3
; return (s2 << 16) | s1;
@RET: rts
; return 1L
@L0: sta sreg
sta sreg+1
lda #1
; ignore adler
jmp incsp4

134
libsrc/zlib/crc32.s Normal file
View File

@ -0,0 +1,134 @@
;
; Piotr Fusik, 14.11.2001
;
; unsigned long __fastcall__ crc32 (unsigned long crc, unsigned char* buf,
; unsigned len);
;
.export _crc32
.import compleax, incsp2, incsp4, popax, popeax
.importzp sreg, ptr1, ptr2, tmp1, tmp2
POLYNOMIAL = $EDB88320
make_table:
ldx #0
@L1: lda #0
sta tmp2
sta sreg
sta sreg+1
ldy #8
txa
@L2: sta tmp1
lsr a
bcc @L3
lda sreg+1
lsr a
eor #(POLYNOMIAL>>24)&$FF
sta sreg+1
lda sreg
ror a
eor #(POLYNOMIAL>>16)&$FF
sta sreg
lda tmp2
ror a
eor #(POLYNOMIAL>>8)&$FF
sta tmp2
lda tmp1
ror a
eor #POLYNOMIAL&$FF
bcs @L4 ; branch always
@L3: rol a
lsr sreg+1
ror sreg
ror tmp2
ror a
@L4: dey
bne @L2
sta table_0,x
lda tmp2
sta table_1,x
lda sreg
sta table_2,x
lda sreg+1
sta table_3,x
inx
bne @L1
inc table_initialised
RET:
rts
_crc32:
; ptr2 = (len & 0xff) == 0 ? len : len + 0x100;
tay
beq @L1
inx
@L1: sta ptr2
stx ptr2+1
; ptr1 = buf
jsr popax
sta ptr1
stx ptr1+1
; if (buf == NULL) return 0;
ora ptr1+1
beq @L0
; if (!tables_initialised) make_tables();
lda table_initialised
bne @dont_make
jsr make_table
@dont_make:
; eax = crc
jsr popeax
; if (len == 0) return crc;
ldy ptr2
bne @L2
ldy ptr2+1
beq RET
@L2:
; eax = ~crc
jsr compleax
stx tmp2
ldy #0
; crc = (crc >> 8) ^ table[(crc & 0xff) ^ *p++];
@L3: eor (ptr1),y
tax
lda table_0,x
eor tmp2
sta tmp1
lda table_1,x
eor sreg
sta tmp2
lda table_2,x
eor sreg+1
sta sreg
lda table_3,x
sta sreg+1
lda tmp1
iny
bne @L4
inc ptr1+1
@L4: dec ptr2
bne @L3
dec ptr2+1
bne @L3
ldx tmp2
jmp compleax
; return 0L
@L0: sta sreg
sta sreg+1
; ignore crc
jmp incsp4
.data
table_initialised:
.byte 0
.bss
table_0: .res 256
table_1: .res 256
table_2: .res 256
table_3: .res 256

File diff suppressed because it is too large Load Diff

36
libsrc/zlib/uncompress.c Normal file
View File

@ -0,0 +1,36 @@
/*
* uncompress.c
*
* Piotr Fusik, 18.11.2001
*/
#include <zlib.h>
int uncompress (char* dest, unsigned* destLen,
const char* source, unsigned sourceLen)
{
unsigned len;
unsigned char* ptr;
unsigned long csum;
/* source[0]: Compression method and flags
bits 0 to 3: Compression method (must be Z_DEFLATED)
bits 4 to 7: Compression info (must be <= 7)
source[1]: Flags
bits 0 to 4: Check bits
bit 5: Preset dictionary (not supported, sorry)
bits 6 to 7: Compression level
*/
if ((source[0] & 0x8f) != Z_DEFLATED || source[1] & 0x20)
return Z_DATA_ERROR;
if ((((unsigned) source[0] << 8) | (unsigned char) source[1]) % 31)
return Z_DATA_ERROR;
*destLen = len = inflatemem(dest, source + 2);
ptr = (unsigned char*) source + sourceLen - 4;
csum = adler32(adler32(0L, Z_NULL, 0), dest, len);
if ((unsigned char) csum != ptr[3]
|| (unsigned char) (csum >> 8) != ptr[2]
|| (unsigned char) (csum >> 16) != ptr[1]
|| (unsigned char) (csum >> 24) != ptr[0])
return Z_DATA_ERROR;
return Z_OK;
}