2 ; 2003-09-21, Piotr Fusik
3 ; 2016-07-19, Greg King
5 ; unsigned __fastcall__ inflatemem (char* dest, const char* source);
11 .importzp sp, sreg, ptr1, ptr2, ptr3, ptr4, tmp1
15 ; --------------------------------------------------------------------------
20 ; Maximum length of a Huffman code.
23 ; All Huffman trees are stored in the bitsCount, bitsPointer_l
24 ; and bitsPointer_h arrays. There may be two trees: the literal/length tree
25 ; and the distance tree, or just one - the temporary tree.
27 ; Index in the mentioned arrays for the beginning of the literal/length tree
28 ; or the temporary tree.
31 ; Index in the mentioned arrays for the beginning of the distance tree.
32 DISTANCE_TREE = MAX_BITS
35 TREES_SIZE = 2*MAX_BITS
38 ; --------------------------------------------------------------------------
43 ; Pointer to the compressed data.
44 inputPointer := ptr1 ; 2 bytes
46 ; Pointer to the uncompressed data.
47 outputPointer := ptr2 ; 2 bytes
50 ; As far as there is no conflict, same memory locations are used
51 ; for different variables.
53 inflateDynamicBlock_cnt := ptr3 ; 1 byte
54 inflateCodes_src := ptr3 ; 2 bytes
55 buildHuffmanTree_src := ptr3 ; 2 bytes
56 getNextLength_last := ptr3 ; 1 byte
57 getNextLength_index := ptr3+1 ; 1 byte
59 buildHuffmanTree_ptr := ptr4 ; 2 bytes
60 fetchCode_ptr := ptr4 ; 2 bytes
61 getBits_tmp := ptr4 ; 1 byte
63 moveBlock_len := sreg ; 2 bytes
64 inflateDynamicBlock_np := sreg ; 1 byte
65 inflateDynamicBlock_nd := sreg+1 ; 1 byte
67 getBit_hold := tmp1 ; 1 byte
70 ; --------------------------------------------------------------------------
77 ; inputPointer = source
80 ; outputPointer = dest
81 .if (.cpu & CPU_ISET_65SC02)
96 ; Get a bit of EOF and two bits of block type
101 ; A and Z contain block type, C contains EOF flag
104 ; Go to the routine decompressing this block
110 ; return outputPointer - dest;
112 .if (.cpu & CPU_ISET_65SC02)
113 sbc (sp) ; C flag is set
117 sbc (sp),y ; C flag is set
128 ; --------------------------------------------------------------------------
129 ; Go to proper block decoding routine.
132 bne inflateCompressedBlock
134 ; --------------------------------------------------------------------------
135 ; Decompress a 'stored' data block.
138 ; Ignore bits until byte boundary
147 ; Skip the length and one's complement of it
156 ; --------------------------------------------------------------------------
157 ; Copy block of length moveBlock_len from (0,x) to the output.
162 .if (.cpu & CPU_ISET_65SC02)
169 .if (.cpu & CPU_ISET_65SC02)
172 sta (outputPointer),y
182 .if (.cpu & CPU_ISET_65SC02)
192 ; --------------------------------------------------------------------------
193 ; Decompress a Huffman-coded data block
194 ; (A = 1: fixed, A = 2: dynamic).
196 inflateCompressedBlock:
198 bne inflateDynamicBlock
199 ; Note: inflateDynamicBlock may assume that A = 1
201 ; --------------------------------------------------------------------------
202 ; Decompress a Huffman-coded data block with default Huffman trees
203 ; (defined by the DEFLATE format):
204 ; literalCodeLength: 144 times 8, 112 times 9
206 ; lengthCodeLength: 23 times 7, 6 times 8
207 ; distanceCodeLength: 30 times 5+DISTANCE_TREE, 2 times 8
208 ; (two 8-bit codes from the primary tree are not used).
212 stx distanceCodeLength+32
215 sta literalCodeLength-1,x
216 sta literalCodeLength+159-1,x
218 bne inflateFixedBlock_1
222 inc literalCodeLength+144-1,x ; sta
224 bne inflateFixedBlock_2
228 dec endCodeLength-1,x ; sta
230 bne inflateFixedBlock_3
234 sta distanceCodeLength-1,x
236 bne inflateFixedBlock_4
237 beq inflateCodes ; branch always
239 ; --------------------------------------------------------------------------
240 ; Decompress a Huffman-coded data block, reading Huffman trees first.
243 ; numberOfPrimaryCodes = 257 + getBits(5)
247 sta inflateDynamicBlock_np
248 ; numberOfDistanceCodes = 1 + getBits(5)
252 sta inflateDynamicBlock_nd
253 ; numberOfTemporaryCodes = 4 + getBits(4)
257 sta inflateDynamicBlock_cnt
258 ; Get lengths of temporary codes in the order stored in tempCodeLengthOrder
261 inflateDynamicBlock_1:
263 jsr getBits ; does not change Y
264 inflateDynamicBlock_2:
265 ldx tempCodeLengthOrder,y
266 sta literalCodeLength,x
269 cpy inflateDynamicBlock_cnt
270 bcc inflateDynamicBlock_1
272 bcc inflateDynamicBlock_2
273 ror literalCodeLength+19 ; C flag is set, so this will set b7
274 ; Build the tree for temporary codes
277 ; Use temporary codes to get lengths of literal/length and distance codes
280 stx getNextLength_last
281 inflateDynamicBlock_3:
283 sta literalCodeLength,x
285 bne inflateDynamicBlock_3
286 inflateDynamicBlock_4:
288 inflateDynamicBlock_5:
291 cpx inflateDynamicBlock_np
292 bcc inflateDynamicBlock_4
295 bcc inflateDynamicBlock_5
296 inflateDynamicBlock_6:
299 beq inflateDynamicBlock_7
300 adc #DISTANCE_TREE-1 ; C flag is set
301 inflateDynamicBlock_7:
304 cpx inflateDynamicBlock_nd
305 bcc inflateDynamicBlock_6
306 ror endCodeLength,x ; C flag is set, so this will set b7
309 ; --------------------------------------------------------------------------
310 ; Decompress a data block basing on given Huffman trees.
318 .if (.cpu & CPU_ISET_65SC02)
322 sta (outputPointer),y
327 bcc inflateCodes_1 ; branch always
333 ; Restore a block from the look-behind buffer
352 sta inflateCodes_src+1
353 ldx #inflateCodes_src
355 beq inflateCodes_1 ; branch always
357 ; --------------------------------------------------------------------------
358 ; Build Huffman trees basing on code lengths (in bits).
359 ; stored in the *CodeLength arrays.
360 ; A byte with its highest bit set marks the end.
363 lda #<literalCodeLength
364 sta buildHuffmanTree_src
365 lda #>literalCodeLength
366 sta buildHuffmanTree_src+1
367 ; Clear bitsCount and bitsPointer_l
373 bne buildHuffmanTree_1
374 beq buildHuffmanTree_3 ; branch always
375 ; Count number of codes of each length
380 bne buildHuffmanTree_3
381 inc buildHuffmanTree_src+1
383 lda (buildHuffmanTree_src),y
384 bpl buildHuffmanTree_2
385 ; Calculate a pointer for each length
394 lda bitsPointer_l+1,x
395 adc bitsPointer_l,x ; C flag is zero
396 bcc buildHuffmanTree_5
401 bcc buildHuffmanTree_4
402 lda #>literalCodeLength
403 sta buildHuffmanTree_src+1
405 bcs buildHuffmanTree_9 ; branch always
406 ; Put codes into their place in sorted table
408 beq buildHuffmanTree_7
410 lda bitsPointer_l-1,x
411 sta buildHuffmanTree_ptr
412 lda bitsPointer_h-1,x
413 sta buildHuffmanTree_ptr+1
417 sta (buildHuffmanTree_ptr),y
421 bne buildHuffmanTree_9
422 inc buildHuffmanTree_src+1
428 bpl buildHuffmanTree_8
430 lda (buildHuffmanTree_src),y
431 bpl buildHuffmanTree_6
434 ; --------------------------------------------------------------------------
435 ; Decode next code length using temporary codes.
438 stx getNextLength_index
441 ; Fetch a temporary code
443 ; Temporary code 0..15: put this length
447 ; Temporary code 16: repeat last length 3 + getBits(2) times
448 ; Temporary code 17: put zero length 3 + getBits(3) times
449 ; Temporary code 18: put zero length 11 + getBits(7) times
451 ldx tempExtraBits-16,y
452 lda tempBaseValue-16,y
459 lda getNextLength_last
461 sta getNextLength_last
462 ldx getNextLength_index
465 ; --------------------------------------------------------------------------
466 ; Read a code basing on the primary tree.
472 ; --------------------------------------------------------------------------
473 ; Read a code from input basing on the tree specified in X.
474 ; Return low byte of this code in A.
475 ; For the literal/length tree, the C flag is set if the code is non-literal.
486 adc bitsCount-1,x ; C flag is zero
489 ldy bitsPointer_l-1,x
490 lda bitsPointer_h-1,x
492 lda (fetchCode_ptr),y
495 ; --------------------------------------------------------------------------
496 ; Decode low byte of a value (length or distance), basing on the code in A.
497 ; The result is the base value for this code plus some bits read from input.
501 ldx lengthExtraBits-1,y
502 lda lengthBaseValue_l-1,y
504 lda lengthBaseValue_h-1,y
509 ; --------------------------------------------------------------------------
510 ; Read X-bit number from the input and add it to A.
511 ; Increment Y if overflow.
512 ; If X > 8, read only 8 bits.
513 ; On return X holds number of unread bits: X = (X > 8 ? X - 8 : 0);
518 .if (.cpu & CPU_ISET_65SC02)
530 sbc getBits_tmp ; C flag is set
541 ; --------------------------------------------------------------------------
542 ; Read a single bit from input, return it in the C flag.
548 .if (.cpu & CPU_ISET_65SC02)
560 ror a ; (C flag was set)
567 ; --------------------------------------------------------------------------
573 ; --------------------------------------------------------------------------
574 ; Arrays for the temporary codes.
576 ; Order, in which lengths of the temporary codes are stored.
578 .byte 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15
584 ; Number of extra bits to read.
588 ; --------------------------------------------------------------------------
589 ; Arrays for the length and distance codes.
593 .byte <3,<4,<5,<6,<7,<8,<9,<10
594 .byte <11,<13,<15,<17,<19,<23,<27,<31
595 .byte <35,<43,<51,<59,<67,<83,<99,<115
596 .byte <131,<163,<195,<227,<258
598 .byte <1,<2,<3,<4,<5,<7,<9,<13
599 .byte <17,<25,<33,<49,<65,<97,<129,<193
600 .byte <257,<385,<513,<769,<1025,<1537,<2049,<3073
601 .byte <4097,<6145,<8193,<12289,<16385,<24577
603 .byte >3,>4,>5,>6,>7,>8,>9,>10
604 .byte >11,>13,>15,>17,>19,>23,>27,>31
605 .byte >35,>43,>51,>59,>67,>83,>99,>115
606 .byte >131,>163,>195,>227,>258
608 .byte >1,>2,>3,>4,>5,>7,>9,>13
609 .byte >17,>25,>33,>49,>65,>97,>129,>193
610 .byte >257,>385,>513,>769,>1025,>1537,>2049,>3073
611 .byte >4097,>6145,>8193,>12289,>16385,>24577
613 ; Number of extra bits to read.
615 .byte 0,0,0,0,0,0,0,0
616 .byte 1,1,1,1,2,2,2,2
617 .byte 3,3,3,3,4,4,4,4
620 .byte 0,0,0,0,1,1,2,2
621 .byte 3,3,4,4,5,5,6,6
622 .byte 7,7,8,8,9,9,10,10
623 .byte 11,11,12,12,13,13
626 ; --------------------------------------------------------------------------
633 ; Number of literal codes of each length in the primary tree
634 ; (MAX_BITS bytes, overlap with literalCodeLength).
637 ; --------------------------------------------------------------------------
638 ; Data for building the primary tree.
640 ; Lengths of literal codes.
643 ; Length of the end code.
646 ; Lengths of length codes.
650 ; --------------------------------------------------------------------------
651 ; Data for building the distance tree.
653 ; Lengths of distance codes.
656 ; For two unused codes in the fixed trees and an 'end' mark.
659 ; --------------------------------------------------------------------------
662 ; Number of codes of each length.
665 ; Pointers to sorted codes of each length.