]> git.sur5r.net Git - cc65/commitdiff
Update from Piotr
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 18 Nov 2001 20:05:57 +0000 (20:05 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 18 Nov 2001 20:05:57 +0000 (20:05 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1124 b7a2c559-68d2-44c3-8de9-860c34a00d81

include/zlib.h
libsrc/zlib/adler32.s [new file with mode: 0644]
libsrc/zlib/crc32.s [new file with mode: 0644]
libsrc/zlib/inflatemem.s
libsrc/zlib/uncompress.c [new file with mode: 0644]

index e7a1453072209ff6fe99c3b55f875a69140ec947..9bc5dcb270a583b18728947222d1788b2c7c7154 100644 (file)
-/*****************************************************************************/
-/*                                                                           */
-/*                                 zlib.h                                   */
-/*                                                                           */
-/*              Decompression routines for the 'deflate' format              */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 2000-2001 Piotr Fusik                                                 */
-/*               a.k.a. Fox/Taquart                                          */
-/* EMail:        fox@scene.pl                                                */
-/*                                                                           */
-/*                                                                           */
-/* This software is provided 'as-is', without any expressed or implied       */
-/* warranty.  In no event will the authors be held liable for any damages    */
-/* arising from the use of this software.                                    */
-/*                                                                           */
-/* Permission is granted to anyone to use this software for any purpose,     */
-/* including commercial applications, and to alter it and redistribute it    */
-/* freely, subject to the following restrictions:                            */
-/*                                                                           */
-/* 1. The origin of this software must not be misrepresented; you must not   */
-/*    claim that you wrote the original software. If you use this software   */
-/*    in a product, an acknowledgment in the product documentation would be  */
-/*    appreciated but is not required.                                       */
-/* 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
-
-
-
-void* inflatemem (void* dest, void* src);
-/* Read the deflate compressed data starting from src and store
- * the uncompressed data starting from dest.
- * Return pointer to a byte after the decompressed data. That is, the result
- * minus dest is the size of the decompressed data.
- */
-
-
-
-/* end of zlib.h */
-#endif
-
-
-
+/*****************************************************************************/\r
+/*                                                                           */\r
+/*                                  zlib.h                                   */\r
+/*                                                                           */\r
+/*              Decompression routines for the 'deflate' format              */\r
+/*                                                                           */\r
+/*                                                                           */\r
+/*                                                                           */\r
+/* (C) 2000-2001 Piotr Fusik <fox@scene.pl>                                  */\r
+/*                                                                           */\r
+/* This file is based on the zlib.h from 'zlib' general purpose compression  */\r
+/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler.    */\r
+/*                                                                           */\r
+/*  Jean-loup Gailly        Mark Adler                                       */\r
+/*  jloup@gzip.org          madler@alumni.caltech.edu                        */\r
+/*                                                                           */\r
+/* This software is provided 'as-is', without any expressed or implied       */\r
+/* warranty.  In no event will the authors be held liable for any damages    */\r
+/* arising from the use of this software.                                    */\r
+/*                                                                           */\r
+/* Permission is granted to anyone to use this software for any purpose,     */\r
+/* including commercial applications, and to alter it and redistribute it    */\r
+/* freely, subject to the following restrictions:                            */\r
+/*                                                                           */\r
+/* 1. The origin of this software must not be misrepresented; you must not   */\r
+/*    claim that you wrote the original software. If you use this software   */\r
+/*    in a product, an acknowledgment in the product documentation would be  */\r
+/*    appreciated but is not required.                                       */\r
+/* 2. Altered source versions must be plainly marked as such, and must not   */\r
+/*    be misrepresented as being the original software.                      */\r
+/* 3. This notice may not be removed or altered from any source              */\r
+/*    distribution.                                                          */\r
+/*                                                                           */\r
+/*****************************************************************************/\r
+\r
+\r
+\r
+#ifndef _ZLIB_H\r
+#define _ZLIB_H\r
+\r
+#define Z_OK         0\r
+#define Z_DATA_ERROR (-3)\r
+/* Return codes for uncompress() */\r
+\r
+#define Z_DEFLATED   8\r
+/* The deflate compression method (the only one supported) */\r
+\r
+#define Z_NULL       0\r
+\r
+\r
+unsigned __fastcall__ inflatemem (char* dest, const char* source);\r
+/*\r
+     Decompresses the source buffer into the destination buffer.\r
+   Returns the size of the uncompressed data (number of bytes written starting\r
+   from dest).\r
+\r
+     This function expects data in the DEFLATE format, described in RFC\r
+   (Request for Comments) 1951 in the file\r
+   ftp://ds.internic.net/rfc/rfc1951.txt.\r
+\r
+     This function does not exist in the original zlib. Its implementation\r
+   using original zlib might be following:\r
+\r
+   unsigned inflatemem (char* dest, const char* source)\r
+   {\r
+     z_stream stream;\r
+\r
+     stream.next_in = (Bytef*) source;\r
+     stream.avail_in = 65535;\r
+\r
+     stream.next_out = dest;\r
+     stream.avail_out = 65535;\r
+\r
+     stream.zalloc = (alloc_func) 0;\r
+     stream.zfree = (free_func) 0;\r
+\r
+     inflateInit2(&stream, -MAX_WBITS);\r
+     inflate(&stream, Z_FINISH);\r
+     inflateEnd(&stream);\r
+\r
+     return stream.total_out;\r
+   }\r
+*/\r
+\r
+\r
+int uncompress (char* dest, unsigned* destLen,\r
+                const char* source, unsigned sourceLen);\r
+/*\r
+   Original zlib description:\r
+\r
+     Decompresses the source buffer into the destination buffer.  sourceLen is\r
+   the byte length of the source buffer. Upon entry, destLen is the total\r
+   size of the destination buffer, which must be large enough to hold the\r
+   entire uncompressed data. (The size of the uncompressed data must have\r
+   been saved previously by the compressor and transmitted to the decompressor\r
+   by some mechanism outside the scope of this compression library.)\r
+   Upon exit, destLen is the actual size of the compressed buffer.\r
+     This function can be used to decompress a whole file at once if the\r
+   input file is mmap'ed.\r
+\r
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not\r
+   enough memory, Z_BUF_ERROR if there was not enough room in the output\r
+   buffer, or Z_DATA_ERROR if the input data was corrupted.\r
+\r
+   Implementation notes:\r
+\r
+     This function expects data in the ZLIB format, described in RFC 1950\r
+   in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is\r
+   essentially the DEFLATE format plus a very small header and Adler-32\r
+   checksum.\r
+\r
+     Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.\r
+*/\r
+\r
+\r
+unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,\r
+                                    unsigned len);\r
+\r
+/*\r
+   Original zlib description:\r
+\r
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and\r
+   return the updated checksum. If buf is NULL, this function returns\r
+   the required initial value for the checksum.\r
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed\r
+   much faster. Usage example:\r
+\r
+     unsigned long adler = adler32(0L, Z_NULL, 0);\r
+\r
+     while (read_buffer(buffer, length) != EOF) {\r
+       adler = adler32(adler, buffer, length);\r
+     }\r
+     if (adler != original_adler) error();\r
+\r
+   Implementation notes:\r
+\r
+     This function isn't actually much faster than crc32(), but it is smaller\r
+   and does not use any lookup tables.\r
+*/\r
+\r
+\r
+unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,\r
+                                  unsigned len);\r
+/*\r
+   Original zlib description:\r
+\r
+     Update a running crc with the bytes buf[0..len-1] and return the updated\r
+   crc. If buf is NULL, this function returns the required initial value\r
+   for the crc. Pre- and post-conditioning (one's complement) is performed\r
+   within this function so it shouldn't be done by the application.\r
+   Usage example:\r
+\r
+     unsigned long crc = crc32(0L, Z_NULL, 0);\r
+\r
+     while (read_buffer(buffer, length) != EOF) {\r
+       crc = crc32(crc, buffer, length);\r
+     }\r
+     if (crc != original_crc) error();\r
+\r
+   Implementation notes:\r
+\r
+     This function uses statically allocated 1 KB lookup table. The table is\r
+   initialised before it is used for the first time (that is, if buffer is\r
+   NULL or length is zero, then the lookup table isn't initialised).\r
+*/\r
+\r
+\r
+/* end of zlib.h */\r
+#endif\r
+\r
+\r
+\r
diff --git a/libsrc/zlib/adler32.s b/libsrc/zlib/adler32.s
new file mode 100644 (file)
index 0000000..bebfdc9
--- /dev/null
@@ -0,0 +1,85 @@
+;\r
+; Piotr Fusik, 18.11.2001\r
+;\r
+; unsigned long __fastcall__ adler32 (unsigned long adler, unsigned char* buf,\r
+;                                     unsigned len);\r
+;\r
+\r
+       .export _adler32\r
+\r
+       .import         incsp2, incsp4, popax, popeax\r
+       .importzp       sreg, ptr1, ptr2, tmp1\r
+\r
+BASE   =       65521   ; largest prime smaller than 65536\r
+\r
+_adler32:\r
+; ptr2 = (len & 0xff) == 0 ? len : len + 0x100;\r
+       tay\r
+       beq     @L1\r
+       inx\r
+@L1:   sta     ptr2\r
+       stx     ptr2+1\r
+; ptr1 = buf\r
+       jsr     popax\r
+       sta     ptr1\r
+       stx     ptr1+1\r
+; if (buf == NULL) return 1L;\r
+       ora     ptr1+1\r
+       beq     @L0\r
+; s1 = adler & 0xFFFF; s2 = adler >> 16;\r
+       jsr     popeax\r
+; if (len == 0) return adler;\r
+       ldy     ptr2\r
+       bne     @L2\r
+       ldy     ptr2+1\r
+       beq     @RET\r
+@L2:   ldy     #0\r
+; s1 += *ptr++; if (s1 >= BASE) s1 -= BASE;\r
+@L3:   clc\r
+       adc     (ptr1),y\r
+       bcc     @L4\r
+       inx\r
+       beq     @L5     ; C flag is set\r
+@L4:   cpx     #>BASE\r
+       bcc     @L6\r
+       cmp     #<BASE\r
+       bcc     @L6\r
+       inx             ; ldx #0\r
+@L5:   sbc     #<BASE  ; C flag is set\r
+       clc\r
+@L6:   sta     tmp1\r
+; s2 += s1; if (s2 >= BASE) s2 -= BASE;\r
+       adc     sreg    ; C flag is clear\r
+       sta     sreg\r
+       txa\r
+       adc     sreg+1\r
+       sta     sreg+1\r
+       bcs     @L7\r
+       cmp     #>BASE\r
+       bcc     @L8\r
+       lda     sreg\r
+       cmp     #<BASE\r
+       bcc     @L8\r
+@L7:   lda     sreg\r
+       sbc     #<BASE  ; C flag is set\r
+       sta     sreg\r
+       lda     sreg+1\r
+       sbc     #>BASE\r
+       sta     sreg+1\r
+@L8:   lda     tmp1\r
+       iny\r
+       bne     @L9\r
+       inc     ptr1+1\r
+@L9:   dec     ptr2\r
+       bne     @L3\r
+       dec     ptr2+1\r
+       bne     @L3\r
+; return (s2 << 16) | s1;\r
+@RET:  rts\r
+\r
+; return 1L\r
+@L0:   sta     sreg\r
+       sta     sreg+1\r
+       lda     #1\r
+; ignore adler\r
+       jmp     incsp4\r
diff --git a/libsrc/zlib/crc32.s b/libsrc/zlib/crc32.s
new file mode 100644 (file)
index 0000000..d47e92f
--- /dev/null
@@ -0,0 +1,134 @@
+;\r
+; Piotr Fusik, 14.11.2001\r
+;\r
+; unsigned long __fastcall__ crc32 (unsigned long crc, unsigned char* buf,\r
+;                                   unsigned len);\r
+;\r
+\r
+       .export _crc32\r
+\r
+       .import         compleax, incsp2, incsp4, popax, popeax\r
+       .importzp       sreg, ptr1, ptr2, tmp1, tmp2\r
+\r
+POLYNOMIAL     =       $EDB88320\r
+\r
+make_table:\r
+       ldx     #0\r
+@L1:   lda     #0\r
+       sta     tmp2\r
+       sta     sreg\r
+       sta     sreg+1\r
+       ldy     #8\r
+       txa\r
+@L2:   sta     tmp1\r
+       lsr     a\r
+       bcc     @L3\r
+       lda     sreg+1\r
+       lsr     a\r
+       eor     #(POLYNOMIAL>>24)&$FF\r
+       sta     sreg+1\r
+       lda     sreg\r
+       ror     a\r
+       eor     #(POLYNOMIAL>>16)&$FF\r
+       sta     sreg\r
+       lda     tmp2\r
+       ror     a\r
+       eor     #(POLYNOMIAL>>8)&$FF\r
+       sta     tmp2\r
+       lda     tmp1\r
+       ror     a\r
+       eor     #POLYNOMIAL&$FF\r
+       bcs     @L4     ; branch always\r
+@L3:   rol     a\r
+       lsr     sreg+1\r
+       ror     sreg\r
+       ror     tmp2\r
+       ror     a\r
+@L4:   dey\r
+       bne     @L2\r
+       sta     table_0,x\r
+       lda     tmp2\r
+       sta     table_1,x\r
+       lda     sreg\r
+       sta     table_2,x\r
+       lda     sreg+1\r
+       sta     table_3,x\r
+       inx\r
+       bne     @L1\r
+       inc     table_initialised\r
+RET:\r
+       rts\r
+\r
+_crc32:\r
+; ptr2 = (len & 0xff) == 0 ? len : len + 0x100;\r
+       tay\r
+       beq     @L1\r
+       inx\r
+@L1:   sta     ptr2\r
+       stx     ptr2+1\r
+; ptr1 = buf\r
+       jsr     popax\r
+       sta     ptr1\r
+       stx     ptr1+1\r
+; if (buf == NULL) return 0;\r
+       ora     ptr1+1\r
+       beq     @L0\r
+; if (!tables_initialised) make_tables();\r
+       lda     table_initialised\r
+       bne     @dont_make\r
+       jsr     make_table\r
+@dont_make:\r
+; eax = crc\r
+       jsr     popeax\r
+; if (len == 0) return crc;\r
+       ldy     ptr2\r
+       bne     @L2\r
+       ldy     ptr2+1\r
+       beq     RET\r
+@L2:\r
+; eax = ~crc\r
+       jsr     compleax\r
+       stx     tmp2\r
+       ldy     #0\r
+; crc = (crc >> 8) ^ table[(crc & 0xff) ^ *p++];\r
+@L3:   eor     (ptr1),y\r
+       tax\r
+       lda     table_0,x\r
+       eor     tmp2\r
+       sta     tmp1\r
+       lda     table_1,x\r
+       eor     sreg\r
+       sta     tmp2\r
+       lda     table_2,x\r
+       eor     sreg+1\r
+       sta     sreg\r
+       lda     table_3,x\r
+       sta     sreg+1\r
+       lda     tmp1\r
+       iny\r
+       bne     @L4\r
+       inc     ptr1+1\r
+@L4:   dec     ptr2\r
+       bne     @L3\r
+       dec     ptr2+1\r
+       bne     @L3\r
+       ldx     tmp2\r
+       jmp     compleax\r
+\r
+; return 0L\r
+@L0:   sta     sreg\r
+       sta     sreg+1\r
+; ignore crc\r
+       jmp     incsp4\r
+\r
+               .data\r
+table_initialised:\r
+               .byte   0\r
+\r
+               .bss\r
+table_0:       .res    256\r
+table_1:       .res    256\r
+table_2:       .res    256\r
+table_3:       .res    256\r
+\r
+\r
index 6c2959084a1858fbb96b0a54feddfb2afeb66684..de444ef7ddb5a19c01a25d5138699b404cd0ecad 100644 (file)
-;
-; Piotr Fusik, 11.11.2001
-;
-; void* inflatemem (void* dest, void* src);
-;
-
-       .export         _inflatemem
-
-       .import         popax
-       .importzp       sreg, ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4
-
-; --------------------------------------------------------------------------
-;
-; Constants
-;
-
-; Maximum length of a Huffman code
-MAX_BITS      =        15
-; Index in bitsCount, bitsPointer_l and bitsPointer_h for literal tree
-LITERAL_TREE  =        0
-; Index in bitsCount, bitsPointer_l and bitsPointer_h for distance tree
-DISTANCE_TREE =        MAX_BITS
-; Size of each of bitsCount, bitsPointer_l and bitsPointer_h
-TREES_SIZE    =        2*MAX_BITS+1
-
-; --------------------------------------------------------------------------
-;
-; Page zero
-;
-
-; Pointer to compressed data
-inputPointer  =        ptr1    ; 2 bytes
-; Pointer to uncompressed data
-outputPointer =        ptr2    ; 2 bytes
-; Buffer for getBit
-getBitHold    =        tmp1    ; 1 byte
-; Local variables. Variables from different routines use same memory.
-cnt           =        tmp2    ; 1 byte
-tmp           =        sreg    ; 1 byte
-ptr           =        sreg    ; 2 bytes
-len           =        ptr3    ; 2 bytes
-nl            =        tmp3    ; 1 byte
-nd            =        tmp4    ; 1 byte
-src           =        ptr4    ; 2 bytes
-dest          =        ptr4    ; 2 bytes
-
-; --------------------------------------------------------------------------
-;
-; Code
-;
-
-_inflatemem:
-
-; Get inputPointer and outputPointer from stack
-       jsr     popax
-       sta     inputPointer
-       stx     inputPointer+1
-       jsr     popax
-       sta     outputPointer
-       stx     outputPointer+1
-
-       ldy     #1
-       sty     getBitHold
-; Get a bit of EOF and two bits of block type
-inflatemem_1:
-       ldx     #3
-       lda     #0
-       jsr     getBits
-       lsr     a
-       tax
-; X contains block type, C contains EOF flag
-; Save EOF flag
-       php
-; Go to the routine decompressing this block
-       jsr     callExtr
-       plp
-       bcc     inflatemem_1
-       lda     outputPointer
-       ldx     outputPointer+1
-       rts
-
-; --------------------------------------------------------------------------
-; Go to the routine decompressing block type X
-
-callExtr:
-       lda     extr_h,x
-       pha
-       lda     extr_l,x
-       pha
-       rts
-
-; --------------------------------------------------------------------------
-; Decompress 'stored' data block
-
-inflateCopyBlock:
-; Ignore bits until byte boundary
-       ldy     #1
-       sty     getBitHold
-; Get 16-bit length
-       ldx     #inputPointer
-       lda     (0,x)
-       sta     len
-       lda     (inputPointer),y
-       sta     len+1
-; Skip length and one's compliment length
-       lda     #4
-       clc
-       adc     inputPointer
-       sta     inputPointer
-       bcc     moveBlock
-       inc     inputPointer+1
-; fall into moveBlock
-
-; --------------------------------------------------------------------------
-; Copy block of length len from (0,x) to output
-
-moveBlock:
-       ldy     len
-       beq     moveBlock_1
-       ldy     #0
-       inc     len+1
-moveBlock_1:
-       lda     (0,x)
-       sta     (outputPointer),y
-       inc     0,x
-       bne     moveBlock_2
-       inc     1,x
-moveBlock_2:
-       inc     outputPointer
-       bne     moveBlock_3
-       inc     outputPointer+1
-moveBlock_3:
-       dec     len
-       bne     moveBlock_1
-       dec     len+1
-       bne     moveBlock_1
-       rts
-
-; --------------------------------------------------------------------------
-; Decompress Huffman-coded data block with default Huffman trees:
-; literalCodeLength:  144 times 8, 112 times 9
-; endCodeLength:      24 times 7, 6 times 8
-; distanceCodeLength: 30 times 5, 2 times 8
-;                     (2 last codes from literal tree are not used)
-
-inflateFixedBlock:
-       ldx     #159
-       stx     distanceCodeLength+32
-       lda     #8
-inflateFixedBlock_1:
-       sta     literalCodeLength-1,x
-       sta     literalCodeLength+159-1,x
-       dex
-       bne     inflateFixedBlock_1
-       ldx     #112
-       lda     #9
-inflateFixedBlock_2:
-       sta     literalCodeLength+144-1,x
-       dex
-       bne     inflateFixedBlock_2
-       ldx     #24
-       lda     #7
-inflateFixedBlock_3:
-       sta     endCodeLength-1,x
-       dex
-       bne     inflateFixedBlock_3
-       ldx     #30
-       lda     #5+DISTANCE_TREE
-inflateFixedBlock_4:
-       sta     distanceCodeLength-1,x
-       dex
-       bne     inflateFixedBlock_4
-       jmp     inflateCodes
-
-; --------------------------------------------------------------------------
-; Decompress Huffman-coded data block, reading Huffman trees first
-
-inflateDynamicBlock:
-; numberOfLiteralCodes = getBits(5) + 257;
-       ldx     #5
-       lda     #<(lengthCodeLength-1)
-       jsr     getBits
-       sta     nl
-; numberOfDistanceCodes = getBits(5) + 1;
-       ldx     #5
-       lda     #1
-       jsr     getBits
-       sta     nd
-       clc
-       adc     nl
-       sta     nl
-; numberOfTemporaryCodes = getBits(4) + 4;
-       lda     #4
-       tax
-       jsr     getBits
-       sta     cnt
-; Clear lengths of temporary codes (there're 19 temp codes max),
-; clear literalCodeLength-1 (it may be used by temporary code 16)
-; and leave #0 in Y
-       ldy     #20
-       lda     #0
-inflateDynamicBlock_1:
-       sta     literalCodeLength-2,y
-       dey
-       bne     inflateDynamicBlock_1
-; Get lengths of temporary codes in order stored in bll
-inflateDynamicBlock_2:
-       ldx     #3
-       lda     #0
-       jsr     getBits ; does not change Y
-       ldx     bll,y
-       sta     literalCodeLength,x
-       iny
-       cpy     cnt
-       bcc     inflateDynamicBlock_2
-       ror     literalCodeLength+19    ; C flag is set, so it will set b7
-; Build tree for temporary codes
-       jsr     buildHuffmanTree
-
-; Use temporary codes to get lengths for literal and distance codes
-; dest is target-1, so we can access last written byte by (dest,0)
-       lda     #<(literalCodeLength-1)
-       sta     dest
-       lda     #>(literalCodeLength-1)
-       sta     dest+1
-inflateDynamicBlock_3:
-       jsr     fetchLiteralCode
-; Temporary code 0..15: put this length
-       ldy     #1
-       cmp     #16
-       bcc     inflateDynamicBlock_6
-       bne     inflateDynamicBlock_4
-; Temporary code 16: repeat last length 3..6 times
-       ldx     #2
-       lda     #3
-       jsr     getBits
-       tay
-       lda     (dest,x)        ; X == 0
-       bpl     inflateDynamicBlock_6   ; branch always
-inflateDynamicBlock_4:
-       lsr     a
-; Temporary code 17: put zero length 3..10 times
-       lda     #3
-       tax
-       bcs     inflateDynamicBlock_5
-; Temporary code 18: put zero length 11..138 times
-       ldx     #7
-       lda     #11
-inflateDynamicBlock_5:
-       jsr     getBits
-       tay
-       lda     #0
-; Write A length Y times
-inflateDynamicBlock_6:
-       sty     cnt
-inflateDynamicBlock_7:
-       sta     (dest),y
-       dey
-       bne     inflateDynamicBlock_7
-       lda     cnt
-       clc
-       adc     dest
-       sta     dest
-       bcc     inflateDynamicBlock_8
-       inc     dest+1
-inflateDynamicBlock_8:
-       cmp     nl
-       bne     inflateDynamicBlock_3
-       ldy     dest+1
-       sbc     #<endCodeLength ; C flag is set
-       bcs     inflateDynamicBlock_11
-       dey
-inflateDynamicBlock_11:
-       cpy     #>endCodeLength
-       bcc     inflateDynamicBlock_3
-; Mark end of distance lengths
-       ldx     nd
-       tay
-       ror     distanceCodeLength,x    ; C flag is set, so it will set b7
-; Move distance lengths to distanceCodeLength table
-inflateDynamicBlock_9:
-       dex
-       lda     endCodeLength,y
-; Mark existing codes (of non-zero length) as distance tree codes
-       beq     inflateDynamicBlock_10
-       pha
-       lda     #0
-       sta     endCodeLength,y
-       pla
-       clc
-       adc     #DISTANCE_TREE
-       sta     distanceCodeLength,x
-inflateDynamicBlock_10:
-       dey
-       txa
-       bne     inflateDynamicBlock_9
-; fall into inflateCodes
-
-; --------------------------------------------------------------------------
-; Decompress data block basing on given Huffman trees
-
-inflateCodes:
-       jsr     buildHuffmanTree
-inflateCodes_1:
-       jsr     fetchLiteralCode
-       bcc     inflateCodes_2
-; Literal code
-       ldy     #0
-       sta     (outputPointer),y
-       inc     outputPointer
-       bne     inflateCodes_1
-       inc     outputPointer+1
-       bcs     inflateCodes_1  ; branch always
-; End of block
-inflateCodes_ret:
-       rts
-inflateCodes_2:
-       beq     inflateCodes_ret
-; Repeat block
-       jsr     getValue
-       sta     len
-       tya
-       jsr     getBits
-       sta     len+1
-       ldx     #DISTANCE_TREE
-       jsr     fetchCode
-       jsr     getValue
-       sta     src
-       tya
-       jsr     getBits
-       sta     src+1
-       lda     outputPointer
-       sec
-       sbc     src
-       sta     src
-       lda     outputPointer+1
-       sbc     src+1
-       sta     src+1
-       ldx     #src
-       jsr     moveBlock
-       beq     inflateCodes_1  ; branch always
-
-; --------------------------------------------------------------------------
-; Build Huffman trees basing on code lengths.
-; Lengths (in bits) are stored in literalCodeLength.
-; A byte with highest bit set marks end of length table.
-
-buildHuffmanTree:
-       lda     #<literalCodeLength
-       sta     buildHuffmanTree_3+1
-       sta     buildHuffmanTree_9+1
-       lda     #>literalCodeLength
-       sta     buildHuffmanTree_3+2
-       sta     buildHuffmanTree_9+2
-; Clear counts
-       ldx     #TREES_SIZE-1
-       lda     #0
-buildHuffmanTree_1:
-       sta     bitsCount,x
-       dex
-       bpl     buildHuffmanTree_1
-       bmi     buildHuffmanTree_3      ; branch always
-; Count number of codes of each length
-buildHuffmanTree_2:
-       inc     bitsCount,x
-       inc     buildHuffmanTree_3+1
-       bne     buildHuffmanTree_3
-       inc     buildHuffmanTree_3+2
-buildHuffmanTree_3:
-       ldx     $ffff   ; patched at runtime
-       bpl     buildHuffmanTree_2
-; Calculate pointer for each length
-       tax             ; ldx #0
-       stx     bitsCount
-       lda     #<sortedCodes
-       ldy     #>sortedCodes
-buildHuffmanTree_4:
-       sta     bitsPointer_l,x
-       tya
-       sta     bitsPointer_h,x
-       lda     bitsCount,x
-       asl     a
-       bcc     buildHuffmanTree_5
-       iny
-       clc
-buildHuffmanTree_5:
-       adc     bitsPointer_l,x
-       bcc     buildHuffmanTree_6
-       iny
-buildHuffmanTree_6:
-       inx
-       cpx     #TREES_SIZE
-       bcc     buildHuffmanTree_4
-       bcs     buildHuffmanTree_9      ; branch always
-; Put codes into their place in sorted table
-buildHuffmanTree_7:
-       beq     buildHuffmanTree_8
-       lda     bitsPointer_l,x
-       sta     ptr
-       clc
-       adc     #2
-       sta     bitsPointer_l,x
-       lda     bitsPointer_h,x
-       sta     ptr+1
-       adc     #0
-       sta     bitsPointer_h,x
-       lda     buildHuffmanTree_9+1
-       sbc     #<(endCodeLength-1)     ; C flag is zero
-       ldy     #1
-       sta     (ptr),y
-       lda     buildHuffmanTree_9+2
-       sbc     #>(endCodeLength-1)
-.ifpc02
-       sta     (ptr)
-.else
-       dey
-       sta     (ptr),y
-.endif
-buildHuffmanTree_8:
-       inc     buildHuffmanTree_9+1
-       bne     buildHuffmanTree_9
-       inc     buildHuffmanTree_9+2
-buildHuffmanTree_9:
-       ldx     $ffff   ; patched at runtime
-       bpl     buildHuffmanTree_7
-       rts
-
-; --------------------------------------------------------------------------
-; Read code basing on literal tree
-
-fetchLiteralCode:
-       ldx     #LITERAL_TREE
-; fall into fetchCode
-
-; --------------------------------------------------------------------------
-; Read code from input stream basing on tree given in X.
-; Return code in A, C is set if non-literal code.
-
-fetchCode:
-       lda     #0
-fetchCode_1:
-       jsr     getBit
-       rol     a
-       cmp     bitsCount+1,x
-       bcc     fetchCode_2
-       sbc     bitsCount+1,x
-       inx
-       bcs     fetchCode_1     ; branch always
-fetchCode_2:
-       ldy     bitsPointer_l,x
-       sty     ptr
-       ldy     bitsPointer_h,x
-       asl     a
-       bcc     fetchCode_3
-       iny
-fetchCode_3:
-       sty     ptr+1
-       tay
-       lda     (ptr),y
-       asl     a
-       iny
-       lda     (ptr),y
-       rts
-
-; --------------------------------------------------------------------------
-; Read low byte of value (length or distance), basing on code A
-
-getValue:
-       tay
-       ldx     lengthExtraBits-1,y
-       lda     lengthCode_l-1,y
-       pha
-       lda     lengthCode_h-1,y
-       tay
-       pla
-; fall into getBits
-
-; --------------------------------------------------------------------------
-; Read X-bit number from input stream and adds it to A.
-; In case of carry, Y is incremented.
-; If X > 8, only 8 bits are read.
-; On return X holds number of unread bits: X = (X > 8 ? X - 8 : 0);
-
-getBits:
-       cpx     #0
-       beq     getBits_ret
-       pha
-       lda     #1
-       sta     tmp
-       pla
-getBits_1:
-       jsr     getBit
-       bcc     getBits_2
-       clc
-       adc     tmp
-       bcc     getBits_2
-       iny
-getBits_2:
-       dex
-       beq     getBits_ret
-       asl     tmp
-       bcc     getBits_1
-getBits_ret:
-       rts
-
-; --------------------------------------------------------------------------
-; Read single bit from input stream, return it in C flag
-
-getBit:
-       lsr     getBitHold
-       bne     getBit_ret
-       pha
-.ifpc02
-       lda     (inputPointer)
-.else
-       tya
-       pha
-       ldy     #0
-       lda     (inputPointer),y
-.endif
-       inc     inputPointer
-       bne     getBit_1
-       inc     inputPointer+1
-getBit_1:
-       ror     a       ; C flag set
-       sta     getBitHold
-.ifpc02
-.else
-       pla
-       tay
-.endif
-       pla
-getBit_ret:
-       rts
-
-; --------------------------------------------------------------------------
-; Addresses of functions extracting different blocks
-extr_l:
-       .byte   <(inflateCopyBlock-1)
-       .byte   <(inflateFixedBlock-1)
-       .byte   <(inflateDynamicBlock-1)
-extr_h:
-       .byte   >(inflateCopyBlock-1)
-       .byte   >(inflateFixedBlock-1)
-       .byte   >(inflateDynamicBlock-1)
-
-; --------------------------------------------------------------------------
-; Order, in which lengths of temporary codes are stored
-bll:
-       .byte   16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
-
-; --------------------------------------------------------------------------
-; Tables for length and distance codes
-; Value is Code + getBits(ExtraBits)
-
-; Base values
-lengthCode_l:
-       .byte   <3,<4,<5,<6,<7,<8,<9,<10
-       .byte   <11,<13,<15,<17,<19,<23,<27,<31
-       .byte   <35,<43,<51,<59,<67,<83,<99,<115
-       .byte   <131,<163,<195,<227,<258
-distanceCode_l:
-       .byte   <1,<2,<3,<4,<5,<7,<9,<13
-       .byte   <17,<25,<33,<49,<65,<97,<129,<193
-       .byte   <257,<385,<513,<769,<1025,<1537,<2049,<3073
-       .byte   <4097,<6145,<8193,<12289,<16385,<24577
-lengthCode_h:
-       .byte   >3,>4,>5,>6,>7,>8,>9,>10
-       .byte   >11,>13,>15,>17,>19,>23,>27,>31
-       .byte   >35,>43,>51,>59,>67,>83,>99,>115
-       .byte   >131,>163,>195,>227,>258
-distanceCode_h:
-       .byte   >1,>2,>3,>4,>5,>7,>9,>13
-       .byte   >17,>25,>33,>49,>65,>97,>129,>193
-       .byte   >257,>385,>513,>769,>1025,>1537,>2049,>3073
-       .byte   >4097,>6145,>8193,>12289,>16385,>24577
-
-; Number of extra bits to read
-lengthExtraBits:
-       .byte   0,0,0,0,0,0,0,0
-       .byte   1,1,1,1,2,2,2,2
-       .byte   3,3,3,3,4,4,4,4
-       .byte   5,5,5,5,0
-distanceExtraBits:
-       .byte   0,0,0,0,1,1,2,2
-       .byte   3,3,4,4,5,5,6,6
-       .byte   7,7,8,8,9,9,10,10
-       .byte   11,11,12,12,13,13
-
-; --------------------------------------------------------------------------
-;
-; Uninitialised data
-;
-
-       .bss
-
-; --------------------------------------------------------------------------
-; Data for building literal tree
-
-       .res    1
-; Length of literal codes
-literalCodeLength:
-       .res    256
-; Length of 'end' code
-endCodeLength:
-       .res    1
-; Length of 'length' codes
-lengthCodeLength:
-       .res    29
-
-; --------------------------------------------------------------------------
-; Data for building distance tree
-
-distanceCodeLength:
-       .res    30
-; For two unused codes in fixed trees and an end flag
-       .res    3
-
-; --------------------------------------------------------------------------
-; Huffman tree structure
-
-; Number of codes of each length
-bitsCount:
-       .res    TREES_SIZE
-
-; Pointer to sorted codes of each length
-bitsPointer_l:
-       .res    TREES_SIZE
-bitsPointer_h:
-       .res    TREES_SIZE
-
-; Sorted codes
-sortedCodes:
-       .res    2*(256+1+29+30+2)
-
-
-
+;\r
+; Piotr Fusik, 18.11.2001\r
+;\r
+; unsigned __fastcall__ inflatemem (char* dest, const char* source);\r
+;\r
+\r
+       .export         _inflatemem\r
+\r
+       .import         incsp2\r
+       .importzp       sp, sreg\r
+       .importzp       ptr1, ptr2, ptr3, ptr4\r
+       .importzp       tmp1, tmp2, tmp3, tmp4\r
+\r
+; --------------------------------------------------------------------------\r
+;\r
+; Constants\r
+;\r
+\r
+; Maximum length of a Huffman code\r
+MAX_BITS      =        15\r
+; Index in bitsCount, bitsPointer_l and bitsPointer_h for literal tree\r
+LITERAL_TREE  =        0\r
+; Index in bitsCount, bitsPointer_l and bitsPointer_h for distance tree\r
+DISTANCE_TREE =        MAX_BITS\r
+; Size of each of bitsCount, bitsPointer_l and bitsPointer_h\r
+TREES_SIZE    =        2*MAX_BITS+1\r
+\r
+; --------------------------------------------------------------------------\r
+;\r
+; Page zero\r
+;\r
+\r
+; Pointer to compressed data\r
+inputPointer  =        ptr1    ; 2 bytes\r
+; Pointer to uncompressed data\r
+outputPointer =        ptr2    ; 2 bytes\r
+; Buffer for getBit\r
+getBitHold    =        tmp1    ; 1 byte\r
+; Local variables. Variables from different routines use same memory.\r
+cnt           =        tmp2    ; 1 byte\r
+tmp           =        sreg    ; 1 byte\r
+ptr           =        sreg    ; 2 bytes\r
+len           =        ptr3    ; 2 bytes\r
+nl            =        tmp3    ; 1 byte\r
+nd            =        tmp4    ; 1 byte\r
+src           =        ptr4    ; 2 bytes\r
+dest          =        ptr4    ; 2 bytes\r
+\r
+; --------------------------------------------------------------------------\r
+;\r
+; Code\r
+;\r
+\r
+_inflatemem:\r
+\r
+; inputPointer = source\r
+       sta     inputPointer\r
+       stx     inputPointer+1\r
+; outputPointer = dest\r
+       ldy     #0\r
+       lda     (sp),y\r
+       sta     outputPointer\r
+       iny\r
+       lda     (sp),y\r
+       sta     outputPointer+1\r
+\r
+;      ldy     #1\r
+       sty     getBitHold\r
+inflatemem_1:\r
+; Get a bit of EOF and two bits of block type\r
+       ldx     #3\r
+       lda     #0\r
+       jsr     getBits\r
+       lsr     a\r
+       tax\r
+; X contains block type, C contains EOF flag\r
+; Save EOF flag\r
+       php\r
+; Go to the routine decompressing this block\r
+       jsr     callExtr\r
+       plp\r
+       bcc     inflatemem_1\r
+; C flag is set!\r
+\r
+; return outputPointer - dest;\r
+       lda     outputPointer\r
+       ldy     #0\r
+       sbc     (sp),y  ; C flag is set\r
+       pha\r
+       iny\r
+       lda     outputPointer+1\r
+       sbc     (sp),y\r
+       tax\r
+       pla\r
+; pop dest\r
+       jmp     incsp2\r
+\r
+; --------------------------------------------------------------------------\r
+; Go to the routine decompressing block type X\r
+\r
+callExtr:\r
+       lda     extr_h,x\r
+       pha\r
+       lda     extr_l,x\r
+       pha\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+; Decompress 'stored' data block\r
+\r
+inflateCopyBlock:\r
+; Ignore bits until byte boundary\r
+       ldy     #1\r
+       sty     getBitHold\r
+; Get 16-bit length\r
+       ldx     #inputPointer\r
+       lda     (0,x)\r
+       sta     len\r
+       lda     (inputPointer),y\r
+       sta     len+1\r
+; Skip length and one's compliment length\r
+       lda     #4\r
+       clc\r
+       adc     inputPointer\r
+       sta     inputPointer\r
+       bcc     moveBlock\r
+       inc     inputPointer+1\r
+; fall into moveBlock\r
+\r
+; --------------------------------------------------------------------------\r
+; Copy block of length len from (0,x) to output\r
+\r
+moveBlock:\r
+       ldy     len\r
+       beq     moveBlock_1\r
+       ldy     #0\r
+       inc     len+1\r
+moveBlock_1:\r
+       lda     (0,x)\r
+       sta     (outputPointer),y\r
+       inc     0,x\r
+       bne     moveBlock_2\r
+       inc     1,x\r
+moveBlock_2:\r
+       inc     outputPointer\r
+       bne     moveBlock_3\r
+       inc     outputPointer+1\r
+moveBlock_3:\r
+       dec     len\r
+       bne     moveBlock_1\r
+       dec     len+1\r
+       bne     moveBlock_1\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+; Decompress Huffman-coded data block with default Huffman trees:\r
+; literalCodeLength:  144 times 8, 112 times 9\r
+; endCodeLength:      24 times 7, 6 times 8\r
+; distanceCodeLength: 30 times 5, 2 times 8\r
+;                     (2 last codes from literal tree are not used)\r
+\r
+inflateFixedBlock:\r
+       ldx     #159\r
+       stx     distanceCodeLength+32\r
+       lda     #8\r
+inflateFixedBlock_1:\r
+       sta     literalCodeLength-1,x\r
+       sta     literalCodeLength+159-1,x\r
+       dex\r
+       bne     inflateFixedBlock_1\r
+       ldx     #112\r
+       lda     #9\r
+inflateFixedBlock_2:\r
+       sta     literalCodeLength+144-1,x\r
+       dex\r
+       bne     inflateFixedBlock_2\r
+       ldx     #24\r
+       lda     #7\r
+inflateFixedBlock_3:\r
+       sta     endCodeLength-1,x\r
+       dex\r
+       bne     inflateFixedBlock_3\r
+       ldx     #30\r
+       lda     #5+DISTANCE_TREE\r
+inflateFixedBlock_4:\r
+       sta     distanceCodeLength-1,x\r
+       dex\r
+       bne     inflateFixedBlock_4\r
+       jmp     inflateCodes\r
+\r
+; --------------------------------------------------------------------------\r
+; Decompress Huffman-coded data block, reading Huffman trees first\r
+\r
+inflateDynamicBlock:\r
+; numberOfLiteralCodes = getBits(5) + 257;\r
+       ldx     #5\r
+       lda     #<(lengthCodeLength-1)\r
+       jsr     getBits\r
+       sta     nl\r
+; numberOfDistanceCodes = getBits(5) + 1;\r
+       ldx     #5\r
+       lda     #1\r
+       jsr     getBits\r
+       sta     nd\r
+       clc\r
+       adc     nl\r
+       sta     nl\r
+; numberOfTemporaryCodes = getBits(4) + 4;\r
+       lda     #4\r
+       tax\r
+       jsr     getBits\r
+       sta     cnt\r
+; Clear lengths of temporary codes (there're 19 temp codes max),\r
+; clear literalCodeLength-1 (it may be used by temporary code 16)\r
+; and leave #0 in Y\r
+       ldy     #20\r
+       lda     #0\r
+inflateDynamicBlock_1:\r
+       sta     literalCodeLength-2,y\r
+       dey\r
+       bne     inflateDynamicBlock_1\r
+; Get lengths of temporary codes in order stored in bll\r
+inflateDynamicBlock_2:\r
+       ldx     #3\r
+       lda     #0\r
+       jsr     getBits ; does not change Y\r
+       ldx     bll,y\r
+       sta     literalCodeLength,x\r
+       iny\r
+       cpy     cnt\r
+       bcc     inflateDynamicBlock_2\r
+       ror     literalCodeLength+19    ; C flag is set, so it will set b7\r
+; Build tree for temporary codes\r
+       jsr     buildHuffmanTree\r
+\r
+; Use temporary codes to get lengths for literal and distance codes\r
+; dest is target-1, so we can access last written byte by (dest,0)\r
+       lda     #<(literalCodeLength-1)\r
+       sta     dest\r
+       lda     #>(literalCodeLength-1)\r
+       sta     dest+1\r
+inflateDynamicBlock_3:\r
+       jsr     fetchLiteralCode\r
+; Temporary code 0..15: put this length\r
+       ldy     #1\r
+       cmp     #16\r
+       bcc     inflateDynamicBlock_6\r
+       bne     inflateDynamicBlock_4\r
+; Temporary code 16: repeat last length 3..6 times\r
+       ldx     #2\r
+       lda     #3\r
+       jsr     getBits\r
+       tay\r
+       lda     (dest,x)        ; X == 0\r
+       bpl     inflateDynamicBlock_6   ; branch always\r
+inflateDynamicBlock_4:\r
+       lsr     a\r
+; Temporary code 17: put zero length 3..10 times\r
+       lda     #3\r
+       tax\r
+       bcs     inflateDynamicBlock_5\r
+; Temporary code 18: put zero length 11..138 times\r
+       ldx     #7\r
+       lda     #11\r
+inflateDynamicBlock_5:\r
+       jsr     getBits\r
+       tay\r
+       lda     #0\r
+; Write A length Y times\r
+inflateDynamicBlock_6:\r
+       sty     cnt\r
+inflateDynamicBlock_7:\r
+       sta     (dest),y\r
+       dey\r
+       bne     inflateDynamicBlock_7\r
+       lda     cnt\r
+       clc\r
+       adc     dest\r
+       sta     dest\r
+       bcc     inflateDynamicBlock_8\r
+       inc     dest+1\r
+inflateDynamicBlock_8:\r
+       cmp     nl\r
+       bne     inflateDynamicBlock_3\r
+       ldy     dest+1\r
+       sbc     #<endCodeLength ; C flag is set\r
+       bcs     inflateDynamicBlock_11\r
+       dey\r
+inflateDynamicBlock_11:\r
+       cpy     #>endCodeLength\r
+       bcc     inflateDynamicBlock_3\r
+; Mark end of distance lengths\r
+       ldx     nd\r
+       tay\r
+       ror     distanceCodeLength,x    ; C flag is set, so it will set b7\r
+; Move distance lengths to distanceCodeLength table\r
+inflateDynamicBlock_9:\r
+       dex\r
+       lda     endCodeLength,y\r
+; Mark existing codes (of non-zero length) as distance tree codes\r
+       beq     inflateDynamicBlock_10\r
+       pha\r
+       lda     #0\r
+       sta     endCodeLength,y\r
+       pla\r
+       clc\r
+       adc     #DISTANCE_TREE\r
+       sta     distanceCodeLength,x\r
+inflateDynamicBlock_10:\r
+       dey\r
+       txa\r
+       bne     inflateDynamicBlock_9\r
+; fall into inflateCodes\r
+\r
+; --------------------------------------------------------------------------\r
+; Decompress data block basing on given Huffman trees\r
+\r
+inflateCodes:\r
+       jsr     buildHuffmanTree\r
+inflateCodes_1:\r
+       jsr     fetchLiteralCode\r
+       bcc     inflateCodes_2\r
+; Literal code\r
+       ldy     #0\r
+       sta     (outputPointer),y\r
+       inc     outputPointer\r
+       bne     inflateCodes_1\r
+       inc     outputPointer+1\r
+       bcs     inflateCodes_1  ; branch always\r
+; End of block\r
+inflateCodes_ret:\r
+       rts\r
+inflateCodes_2:\r
+       beq     inflateCodes_ret\r
+; Repeat block\r
+       jsr     getValue\r
+       sta     len\r
+       tya\r
+       jsr     getBits\r
+       sta     len+1\r
+       ldx     #DISTANCE_TREE\r
+       jsr     fetchCode\r
+       jsr     getValue\r
+       sta     src\r
+       tya\r
+       jsr     getBits\r
+       sta     src+1\r
+       lda     outputPointer\r
+       sec\r
+       sbc     src\r
+       sta     src\r
+       lda     outputPointer+1\r
+       sbc     src+1\r
+       sta     src+1\r
+       ldx     #src\r
+       jsr     moveBlock\r
+       beq     inflateCodes_1  ; branch always\r
+\r
+; --------------------------------------------------------------------------\r
+; Build Huffman trees basing on code lengths.\r
+; Lengths (in bits) are stored in literalCodeLength.\r
+; A byte with highest bit set marks end of length table.\r
+\r
+buildHuffmanTree:\r
+       lda     #<literalCodeLength\r
+       sta     ptr\r
+       sta     src\r
+       lda     #>literalCodeLength\r
+       sta     ptr+1\r
+       sta     src+1\r
+; Clear counts\r
+       ldy     #TREES_SIZE\r
+       lda     #0\r
+buildHuffmanTree_1:\r
+       sta     bitsCount-1,y\r
+       dey\r
+       bne     buildHuffmanTree_1\r
+       beq     buildHuffmanTree_3      ; branch always\r
+; Count number of codes of each length\r
+buildHuffmanTree_2:\r
+       tax\r
+       inc     bitsCount,x\r
+       iny\r
+       bne     buildHuffmanTree_3\r
+       inc     ptr+1\r
+buildHuffmanTree_3:\r
+       lda     (ptr),y\r
+       bpl     buildHuffmanTree_2\r
+; Calculate pointer for each length\r
+       ldx     #0\r
+       stx     bitsCount\r
+       lda     #<sortedCodes\r
+       ldy     #>sortedCodes\r
+buildHuffmanTree_4:\r
+       sta     bitsPointer_l,x\r
+       tya\r
+       sta     bitsPointer_h,x\r
+       lda     bitsCount,x\r
+       asl     a\r
+       bcc     buildHuffmanTree_5\r
+       iny\r
+       clc\r
+buildHuffmanTree_5:\r
+       adc     bitsPointer_l,x\r
+       bcc     buildHuffmanTree_6\r
+       iny\r
+buildHuffmanTree_6:\r
+       inx\r
+       cpx     #TREES_SIZE\r
+       bcc     buildHuffmanTree_4\r
+.ifpc02\r
+       ldy     #1\r
+.else\r
+       ldy     #0\r
+.endif\r
+       bcs     buildHuffmanTree_9      ; branch always\r
+; Put codes into their place in sorted table\r
+buildHuffmanTree_7:\r
+       beq     buildHuffmanTree_8\r
+       tax\r
+       lda     bitsPointer_l,x\r
+       sta     ptr\r
+       clc\r
+       adc     #2\r
+       sta     bitsPointer_l,x\r
+       lda     bitsPointer_h,x\r
+       sta     ptr+1\r
+       adc     #0\r
+       sta     bitsPointer_h,x\r
+       lda     src\r
+       sbc     #<(endCodeLength-1)     ; C flag is zero\r
+.ifpc02\r
+.else\r
+       iny                             ; ldy #1\r
+.endif\r
+       sta     (ptr),y\r
+       lda     src+1\r
+       sbc     #>(endCodeLength-1)\r
+.ifpc02\r
+       sta     (ptr)\r
+.else\r
+       dey                             ; ldy #0\r
+       sta     (ptr),y\r
+.endif\r
+buildHuffmanTree_8:\r
+       inc     src\r
+       bne     buildHuffmanTree_9\r
+       inc     src+1\r
+buildHuffmanTree_9:\r
+.ifpc02\r
+       lda     (src)\r
+.else\r
+       lda     (src),y\r
+.endif\r
+       bpl     buildHuffmanTree_7\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+; Read code basing on literal tree\r
+\r
+fetchLiteralCode:\r
+       ldx     #LITERAL_TREE\r
+; fall into fetchCode\r
+\r
+; --------------------------------------------------------------------------\r
+; Read code from input stream basing on tree given in X.\r
+; Return code in A, C is set if non-literal code.\r
+\r
+fetchCode:\r
+       lda     #0\r
+fetchCode_1:\r
+       jsr     getBit\r
+       rol     a\r
+       cmp     bitsCount+1,x\r
+       bcc     fetchCode_2\r
+       sbc     bitsCount+1,x\r
+       inx\r
+       bcs     fetchCode_1     ; branch always\r
+fetchCode_2:\r
+       ldy     bitsPointer_l,x\r
+       sty     ptr\r
+       ldy     bitsPointer_h,x\r
+       asl     a\r
+       bcc     fetchCode_3\r
+       iny\r
+fetchCode_3:\r
+       sty     ptr+1\r
+       tay\r
+       lda     (ptr),y\r
+       asl     a\r
+       iny\r
+       lda     (ptr),y\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+; Read low byte of value (length or distance), basing on code A\r
+\r
+getValue:\r
+       tay\r
+       ldx     lengthExtraBits-1,y\r
+       lda     lengthCode_l-1,y\r
+       pha\r
+       lda     lengthCode_h-1,y\r
+       tay\r
+       pla\r
+; fall into getBits\r
+\r
+; --------------------------------------------------------------------------\r
+; Read X-bit number from input stream and adds it to A.\r
+; In case of carry, Y is incremented.\r
+; If X > 8, only 8 bits are read.\r
+; On return X holds number of unread bits: X = (X > 8 ? X - 8 : 0);\r
+\r
+getBits:\r
+       cpx     #0\r
+       beq     getBits_ret\r
+       pha\r
+       lda     #1\r
+       sta     tmp\r
+       pla\r
+getBits_1:\r
+       jsr     getBit\r
+       bcc     getBits_2\r
+       clc\r
+       adc     tmp\r
+       bcc     getBits_2\r
+       iny\r
+getBits_2:\r
+       dex\r
+       beq     getBits_ret\r
+       asl     tmp\r
+       bcc     getBits_1\r
+getBits_ret:\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+; Read single bit from input stream, return it in C flag\r
+\r
+getBit:\r
+       lsr     getBitHold\r
+       bne     getBit_ret\r
+       pha\r
+.ifpc02\r
+       lda     (inputPointer)\r
+.else\r
+       tya\r
+       pha\r
+       ldy     #0\r
+       lda     (inputPointer),y\r
+.endif\r
+       inc     inputPointer\r
+       bne     getBit_1\r
+       inc     inputPointer+1\r
+getBit_1:\r
+       ror     a       ; C flag set\r
+       sta     getBitHold\r
+.ifpc02\r
+.else\r
+       pla\r
+       tay\r
+.endif\r
+       pla\r
+getBit_ret:\r
+       rts\r
+\r
+; --------------------------------------------------------------------------\r
+;\r
+; Constant data\r
+;\r
+\r
+       .rodata\r
+; --------------------------------------------------------------------------\r
+; Addresses of functions extracting different blocks\r
+extr_l:\r
+       .byte   <(inflateCopyBlock-1)\r
+       .byte   <(inflateFixedBlock-1)\r
+       .byte   <(inflateDynamicBlock-1)\r
+extr_h:\r
+       .byte   >(inflateCopyBlock-1)\r
+       .byte   >(inflateFixedBlock-1)\r
+       .byte   >(inflateDynamicBlock-1)\r
+\r
+; --------------------------------------------------------------------------\r
+; Order, in which lengths of temporary codes are stored\r
+bll:\r
+       .byte   16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15\r
+\r
+; --------------------------------------------------------------------------\r
+; Tables for length and distance codes\r
+; Value is Code + getBits(ExtraBits)\r
+\r
+; Base values\r
+lengthCode_l:\r
+       .byte   <3,<4,<5,<6,<7,<8,<9,<10\r
+       .byte   <11,<13,<15,<17,<19,<23,<27,<31\r
+       .byte   <35,<43,<51,<59,<67,<83,<99,<115\r
+       .byte   <131,<163,<195,<227,<258\r
+distanceCode_l:\r
+       .byte   <1,<2,<3,<4,<5,<7,<9,<13\r
+       .byte   <17,<25,<33,<49,<65,<97,<129,<193\r
+       .byte   <257,<385,<513,<769,<1025,<1537,<2049,<3073\r
+       .byte   <4097,<6145,<8193,<12289,<16385,<24577\r
+lengthCode_h:\r
+       .byte   >3,>4,>5,>6,>7,>8,>9,>10\r
+       .byte   >11,>13,>15,>17,>19,>23,>27,>31\r
+       .byte   >35,>43,>51,>59,>67,>83,>99,>115\r
+       .byte   >131,>163,>195,>227,>258\r
+distanceCode_h:\r
+       .byte   >1,>2,>3,>4,>5,>7,>9,>13\r
+       .byte   >17,>25,>33,>49,>65,>97,>129,>193\r
+       .byte   >257,>385,>513,>769,>1025,>1537,>2049,>3073\r
+       .byte   >4097,>6145,>8193,>12289,>16385,>24577\r
+\r
+; Number of extra bits to read\r
+lengthExtraBits:\r
+       .byte   0,0,0,0,0,0,0,0\r
+       .byte   1,1,1,1,2,2,2,2\r
+       .byte   3,3,3,3,4,4,4,4\r
+       .byte   5,5,5,5,0\r
+distanceExtraBits:\r
+       .byte   0,0,0,0,1,1,2,2\r
+       .byte   3,3,4,4,5,5,6,6\r
+       .byte   7,7,8,8,9,9,10,10\r
+       .byte   11,11,12,12,13,13\r
+\r
+; --------------------------------------------------------------------------\r
+;\r
+; Uninitialised data\r
+;\r
+\r
+       .bss\r
+\r
+; --------------------------------------------------------------------------\r
+; Data for building literal tree\r
+\r
+       .res    1\r
+; Length of literal codes\r
+literalCodeLength:\r
+       .res    256\r
+; Length of 'end' code\r
+endCodeLength:\r
+       .res    1\r
+; Length of 'length' codes\r
+lengthCodeLength:\r
+       .res    29\r
+\r
+; --------------------------------------------------------------------------\r
+; Data for building distance tree\r
+\r
+distanceCodeLength:\r
+       .res    30\r
+; For two unused codes in fixed trees and an end flag\r
+       .res    3\r
+\r
+; --------------------------------------------------------------------------\r
+; Huffman tree structure\r
+\r
+; Number of codes of each length\r
+bitsCount:\r
+       .res    TREES_SIZE\r
+\r
+; Pointer to sorted codes of each length\r
+bitsPointer_l:\r
+       .res    TREES_SIZE\r
+bitsPointer_h:\r
+       .res    TREES_SIZE\r
+\r
+; Sorted codes\r
+sortedCodes:\r
+       .res    2*(256+1+29+30+2)\r
+\r
+\r
+\r
diff --git a/libsrc/zlib/uncompress.c b/libsrc/zlib/uncompress.c
new file mode 100644 (file)
index 0000000..fb07ba4
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * uncompress.c\r
+ *\r
+ * Piotr Fusik, 18.11.2001\r
+ */\r
+\r
+#include <zlib.h>\r
+\r
+int uncompress (char* dest, unsigned* destLen,\r
+                const char* source, unsigned sourceLen)\r
+{\r
+       unsigned len;\r
+       unsigned char* ptr;\r
+       unsigned long csum;\r
+       /* source[0]: Compression method and flags\r
+           bits 0 to 3: Compression method (must be Z_DEFLATED)\r
+           bits 4 to 7: Compression info (must be <= 7)\r
+          source[1]: Flags\r
+           bits 0 to 4: Check bits\r
+           bit 5:       Preset dictionary (not supported, sorry)\r
+           bits 6 to 7: Compression level\r
+       */\r
+       if ((source[0] & 0x8f) != Z_DEFLATED || source[1] & 0x20)\r
+               return Z_DATA_ERROR;\r
+       if ((((unsigned) source[0] << 8) | (unsigned char) source[1]) % 31)\r
+               return Z_DATA_ERROR;\r
+       *destLen = len = inflatemem(dest, source + 2);\r
+       ptr = (unsigned char*) source + sourceLen - 4;\r
+       csum = adler32(adler32(0L, Z_NULL, 0), dest, len);\r
+       if ((unsigned char) csum != ptr[3]\r
+        || (unsigned char) (csum >> 8) != ptr[2]\r
+        || (unsigned char) (csum >> 16) != ptr[1]\r
+        || (unsigned char) (csum >> 24) != ptr[0])\r
+               return Z_DATA_ERROR;\r
+       return Z_OK;\r
+}\r