?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. ; Gunzip by Wouter Vermaelen
  2. ; https://github.com/m9710797/msx-gunzip
  3. ;
  4. ; Original code
  5. ; Copyright 2015 Laurens Holst laurens.nospam@grauw.nl
  6. ; http://www.grauw.nl/projects/gunzip
  7. ;
  8. ; You need to add the following to compile:
  9. ; Functions
  10. ;   GzipReadInputBuffer
  11. ;   GzipWriteOutputBuffer
  12. ;   GzipExitWithError
  13. ;   GzipThrowException
  14. ; Defines
  15. ;   GzipBuffersStart
  16. ;
  17. ;
  18.  
  19. ; Read a single bit from the input.
  20. ; This code fragment is generated by 'GenerateHuffman'
  21. ; Requires: PrepareRead has been called (registers C and DE are reserved)
  22. ; output: carry-flag, reset -> read 0-bit, set-> read 1-bit
  23. ; Modifies: a
  24. ; Unchanged: b, hl, ix, iy
  25. ReadBitInlineA: MACRO
  26.                 srl c
  27.                 call z,ReadBitA ; if sentinel bit is shifted out
  28.                 ENDM
  29.  
  30. GzipExtract:
  31. ; Read header
  32. ; Header constants
  33. FLAG_HCRC:      equ #02
  34. FLAG_EXTRA:     equ #04
  35. FLAG_NAME:      equ #08
  36. FLAG_COMMENT:   equ #10
  37. FLAG_RESERVED:  equ #20 ; #E0
  38.  
  39.                 ld hl,0
  40.                 ld (OutputCount + 0),hl
  41.                 ld (OutputCount + 2),hl
  42.                 ld hl,0xffff
  43.                 ld (Crc32Value + 0),hl
  44.                 ld (Crc32Value + 2),hl
  45.                 xor a
  46.                 ld (InputBits),a
  47.                 ld hl,InputBufferEnd - 1
  48.                 ld (InputBufPos),hl
  49.                 ld hl,OutputBuffer
  50.                 ld (OutputBufPos),hl
  51.  
  52.                 ld de,(InputBufPos)
  53. ; Check two signature bytes
  54.                 call ReadByte
  55.                 cp 31   ; gzip signature (1)
  56.                 ld hl,TextNotGzip
  57.                 jp nz,GzipExitWithError
  58.                 call ReadByte
  59.                 cp 139  ; gzip signature (1)
  60.                 ;ld hl,TextNotGzip  ; hl not changed
  61.                 jp nz,GzipExitWithError
  62.  
  63. ; Check compression algorithm
  64.                 call ReadByte
  65.                 cp 8    ; deflate compression ID (1)
  66.                 ld hl,TextNotDeflate
  67.                 jp nz,GzipExitWithError
  68.  
  69. ; Read flags
  70.                 call ReadByte
  71.                 ld (HeaderFlags),a
  72.  
  73. ; Skip mtime[4], xfl, os
  74.                 ld hl,6
  75.                 call SkipInputBytes
  76.  
  77. ; Check for unknown flags
  78.                 ld a,(HeaderFlags)
  79.                 and FLAG_RESERVED
  80.                 ld hl,TextUnknownFlag
  81.                 jp nz,GzipExitWithError
  82.  
  83. ; Check and skip extra section
  84.                 ld a,(HeaderFlags)
  85.                 and FLAG_EXTRA
  86.                 jr z,NoSkipExtra
  87.                 call ReadByte
  88.                 ld l,a
  89.                 call ReadByte
  90.                 ld h,a
  91.                 call SkipInputBytes
  92. NoSkipExtra:
  93.  
  94. ; Skip name
  95.                 ld a,(HeaderFlags)
  96.                 and FLAG_NAME
  97.                 call nz,SkipZString
  98.  
  99. ; Skip comment
  100.                 ld a,(HeaderFlags)
  101.                 and FLAG_COMMENT
  102.                 call nz,SkipZString
  103.  
  104. ; Skip header CRC
  105.                 ld a,(HeaderFlags)
  106.                 and FLAG_HCRC
  107.                 ld hl,2
  108.                 call nz,SkipInputBytes
  109.  
  110.                 ld (InputBufPos),de
  111.  
  112. ; Decompress all blocks in the gz file
  113. InflateLoop:    call PrepareRead
  114.                 ReadBitInlineA
  115.                 push af
  116.                 call Read2Bits
  117.                 push af
  118.                 call FinishRead
  119.                 pop af
  120.                 call InflateBlock
  121.                 pop af
  122.                 jr nc,InflateLoop
  123.  
  124. ; Finish last (partially filled) OutputBuffer (update count, crc)
  125.                 call FinishBlock
  126.  
  127. ; Verify the decompressed data
  128. ; Read expected values from file
  129.                 ld de,(InputBufPos)
  130.                 call ReadByte
  131.                 ld l,a  ; bits 7-0
  132.                 call ReadByte
  133.                 ld h,a  ; bits 15-8
  134.                 push hl ; expected crc bits 15-0
  135.                 call ReadByte
  136.                 ld l,a  ; bits 23-16
  137.                 call ReadByte
  138.                 ld h,a  ; bits 31-24
  139.                 push hl ; expected crc bits 31-16
  140.  
  141.                 call ReadByte
  142.                 ld l,a  ; bits 7-0
  143.                 call ReadByte
  144.                 ld h,a  ; bits 15-8
  145.                 push hl ; expected-size bits 15-0
  146.                 call ReadByte
  147.                 ld l,a  ; bits 23-16
  148.                 call ReadByte
  149.                 ld h,a  ; hl = expected-size bits 31-16
  150.                 ;ld (InputBufPos),de    ; not needed anymore
  151.  
  152. ; Verify size
  153.                 ld de,(OutputCount + 2) ; de = actual size bits 31-16
  154.                 or a                    ; hl = expected size bits 31-16
  155.                 sbc hl,de
  156.                 jr nz,SizeError
  157.                 ld de,(OutputCount + 0) ; de = actual size bits 15-0
  158.                 pop hl                  ; hl = expected size bits 15-0
  159.                 sbc hl,de
  160. SizeError:      ld hl,TextSizeError
  161.                 jp nz,GzipExitWithError
  162.  
  163. ; Verify CRC
  164.                 pop hl                  ; hl = expected crc bits 31-16
  165.                 pop de                  ; de = expected crc bits 15-0
  166.                 ld a,(NoCrcCheck)
  167.                 or a
  168.                 ret nz
  169.                 ld bc,(Crc32Value + 2)  ; de = actual crc bits 31-16
  170.                 scf
  171.                 adc hl,bc
  172.                 jr nz,CrcError
  173.                 ex de,hl
  174.                 ld bc,(Crc32Value + 0)  ; de = actual crc bits 15-0
  175.                 adc hl,bc
  176.                 ret z                   ; ok
  177. CrcError:       ld hl,TextCrcError
  178.                 jp GzipExitWithError
  179.  
  180.  
  181. ; Skip zero-terminated string
  182. SkipZString:    call ReadByte
  183.                 and a
  184.                 jr nz,SkipZString
  185.                 ret
  186.  
  187. ; hl = nr of bytes to skip
  188. SkipInputBytes: call ReadByte
  189.                 dec hl
  190.                 ld a,h
  191.                 or l
  192.                 jr nz,SkipInputBytes
  193.                 ret
  194.  
  195.  
  196. ; === Inflate decompression ===
  197. ; -- decompress one block --
  198.  
  199. ; a = block type
  200. InflateBlock:   and a
  201.                 jr z,Uncompressed
  202.                 cp 2
  203.                 jr c,FixedComp
  204.                 jp z,DynamicComp
  205.                 ld hl,TextBlockErr
  206.                 jp GzipExitWithError
  207.  
  208. ; An uncompressed block
  209. Uncompressed:   ld de,(InputBufPos)
  210.                 xor a
  211.                 ld (InputBits),a        ; re-align to byte boundary
  212.                 call ReadByte
  213.                 ld c,a
  214.                 call ReadByte
  215.                 ld b,a                  ; bc = block-length
  216.                 call ReadByte
  217.                 ld l,a
  218.                 call ReadByte
  219.                 ld h,a                  ; hl = complement of block-length
  220.                 scf
  221.                 adc hl,bc
  222.                 ld hl,TextLengthErr
  223.                 jp nz,GzipExitWithError
  224.  
  225.                 ld a,b
  226.                 or c
  227.                 jr z,UncompEnd  ; length = 0
  228.                 ld a,c
  229.                 dec bc
  230.                 inc b
  231.                 ld c,b
  232.                 ld b,a
  233.  
  234.                 ld hl,(OutputBufPos)
  235. UncompLoop:     ;call ReadByte  ; partially inline this call
  236.                 inc e
  237.                 call z,ReadByte2
  238.                 ld a,(de)
  239.                 ;call WriteByte ; partially inline this call
  240.                 ld (hl),a
  241.                 inc l
  242.                 call z,WriteByte2
  243.                 djnz UncompLoop
  244.                 dec c
  245.                 jr nz,UncompLoop
  246.                 ld (OutputBufPos),hl
  247.  
  248. UncompEnd:      ld (InputBufPos),de
  249.                 ret
  250.  
  251.  
  252. ; A block compressed using the fixed alphabet
  253. FixedComp:      ld bc,FixedLitCount
  254.                 ld de,FixedLitLen
  255.                 ld hl,LLSymbols
  256.                 ld iy,LiteralTree
  257.                 ld ix,LiteralTreeEnd
  258.                 call GenerateHuffman
  259.  
  260.                 ld bc,FixedDistCount
  261.                 ld de,FixedDistLen
  262.                 ld hl,DistSymbols
  263.                 ld iy,DistanceTree
  264.                 ld ix,DistanceTreeEnd
  265.                 call GenerateHuffman
  266.                 jr DoInflate
  267.  
  268. ; A block compressed using a dynamic alphabet
  269. DynamicComp:    call BuildDynAlpha
  270. DoInflate:      ; generate CopySetLength routine in front of DistanceTree
  271.                 ld hl,CopySL
  272.                 ld de,CopySetLength
  273.                 ld bc,CopySLLen
  274.                 ldir
  275.  
  276.                 ld iy,Write_AndNext
  277.                 call PrepareRead
  278.                 ld hl,(OutputBufPos)
  279.                 call LiteralTree        ; generated code
  280.                 ld (OutputBufPos),hl
  281.                 jp FinishRead
  282.  
  283.  
  284. ; -- Create dynamic alphabet --
  285.  
  286. MAX_HEADER_LEN: equ 19  ; maximum number of 'header code lengths'
  287. MAX_LIT_LEN:    equ 286 ; maximum number of 'literal/length code lengths'
  288. MAX_DIST_LEN:   equ 30  ; maximum number of 'distance code lengths'
  289.  
  290. BuildDynAlpha:
  291. ; Clear header code lengths
  292.                 ld hl,HdrCodeLengths
  293.                 ld de,HdrCodeLengths + 1
  294.                 ld bc,MAX_HEADER_LEN - 1
  295.                 ld (hl),b       ; 0
  296.                 ldir
  297.  
  298. ; Read hlit
  299.                 call PrepareRead
  300.                 call Read5Bits
  301.                 inc a
  302.                 cp ((MAX_LIT_LEN) & #FF) + 1
  303.                 call nc,GzipThrowException
  304.                 ld (hlit + 0),a
  305.  
  306. ; Read hdist
  307.                 call Read5Bits
  308.                 inc a
  309.                 cp MAX_DIST_LEN + 1
  310.                 call nc,GzipThrowException
  311.                 ld (hdist + 0),a
  312.  
  313. ; Read hclen
  314.                 call Read4Bits
  315.                 add a,4
  316.                 cp MAX_HEADER_LEN + 1
  317.                 call nc,GzipThrowException
  318.  
  319. ; Read header code lengths
  320.                 ld ixl,a        ; hclen
  321.                 ld hl,HeaderCodeOrder
  322.                 ld iy,HdrCodeLengths
  323. DynLoop:        ld a,(hl)
  324.                 inc hl
  325.                 ld (DynStore + 2),a     ; self modifying code!
  326.                 call Read3Bits          ; changes B
  327. DynStore:       ld (iy + 0),a           ; offset is dynamically changed!
  328.                 dec ixl
  329.                 jr nz,DynLoop
  330.                 push bc
  331.                 push de
  332.  
  333. ; Construct header code alphabet
  334.                 ld bc,MAX_HEADER_LEN
  335.                 ld de,HdrCodeLengths    ; de = length of symbols
  336.                 ld hl,HeaderSymbols
  337.                 ld iy,HeaderTree
  338.                 ld ix,HeaderTreeEnd
  339.                 call GenerateHuffman
  340.  
  341. ; Read literal length distance code lengths
  342.                 ld bc,(hdist)
  343.                 ld ix,(hlit)
  344.                 add ix,bc
  345.                 inc ixh ; +1 for nested 8-bit loop
  346.                 ld hl,LLDCodeLengths
  347.                 pop de
  348.                 pop bc
  349.                 call HeaderTree         ; decode the header (generated code)
  350.                 call FinishRead
  351.  
  352. ; Construct literal length alphabet
  353.                 ld bc,(hlit)            ; bc = number of symbols
  354.                 ld de,LLDCodeLengths    ; de = length of symbols
  355.                 ld hl,LLSymbols         ; iy = literal/length symbol handlers table
  356.                 ld iy,LiteralTree
  357.                 ld ix,LiteralTreeEnd
  358.                 call GenerateHuffman
  359.  
  360. ; Construct distance alphabet
  361.                 ld bc,(hdist)           ; bc = number of symbols
  362.                 ld hl,LLDCodeLengths
  363.                 ld de,(hlit)
  364.                 add hl,de
  365.                 ex de,hl                ; de = length of symbols
  366.                 ld hl,DistSymbols       ; iy = distance symbol handlers table
  367.                 ld iy,DistanceTree
  368.                 ld ix,DistanceTreeEnd
  369.                 jp GenerateHuffman
  370.  
  371.  
  372. ; -- Generate Huffman decoding function --
  373. ; In:
  374. ;  [bc] = number of symbols
  375. ;  [de] = table containing length of each symbol
  376. ;  [hl] = table containing pointer to leaf-routine for each symbol
  377. ;  [iy] = output-buffer
  378. ;  [ix] = output-buffer-end (only for buffer overflow check)
  379. ; Out:
  380. ;  output-buffer filled with decoding function
  381. ; Modifies:
  382. ;  - all registers
  383. ;  - buffers CountBuffer and SortedBuffer are changed, but can be
  384. ;    freely used outside this routine. IOW it's all scratch area.
  385. ; Requires:
  386. ;  CountBuffer must be 256-byte aligned
  387.  
  388. MAX_CODELENGTH: equ 16
  389.  
  390. GenerateHuffman:
  391.                 push ix
  392.                 push iy
  393.                 push hl
  394.                 push de
  395.                 push bc
  396.  
  397. ; Generate list of (code-length, symbol-handler) pairs, sorted on code-length
  398.                 ; clear CountBuffer
  399.                 ld hl,CountBuffer
  400.                 ld de,CountBuffer + 1
  401.                 ld bc,(2 * MAX_CODELENGTH) - 1
  402.                 ld (hl),b       ; b = 0
  403.                 ldir
  404.  
  405. ; count code lengths
  406.                 pop de          ; de = number of symbols
  407.                 ld b,e
  408.                 dec de
  409.                 inc d
  410.                 ld c,d          ; bc = numSymbols converted into 2 8-bit counters
  411.                 pop de          ; de = codeLengths
  412.                 push de
  413.                 push bc
  414.                 ld h,CountBuffer / 256
  415. CountLoop:      ld a,(de)
  416.                 inc de
  417.                 add a,a
  418.                 jr z,CountNext
  419.                 ld l,a
  420.                 inc (hl)
  421.                 jr nc,CountNext
  422.                 inc l
  423.                 inc (hl)
  424. CountNext:      djnz CountLoop
  425.                 dec c
  426.                 jr nz,CountLoop
  427.  
  428. ; calculate running sum * 4, transform CountBuffer into OffsetBuffer
  429.                 ld de,SortedBuffer
  430.                 ld l,c          ; c = 0   hl = CountBuffer
  431.                 ld a,MAX_CODELENGTH
  432. AccumLoop:      ld c,(hl)
  433.                 ld (hl),e
  434.                 inc l
  435.                 ld b,(hl)
  436.                 ld (hl),d
  437.                 inc l
  438.                 ex de,hl
  439.                 add hl,bc
  440.                 add hl,bc
  441.                 add hl,bc
  442.                 add hl,bc
  443.                 ex de,hl
  444.                 dec a
  445.                 jr nz,AccumLoop
  446.                 ex de,hl
  447.                 ld (hl),a       ; a = 0  sentinel
  448.  
  449. ; sort
  450.                 pop bc          ; bc = numSymbols converted into 2 8-bit counters
  451.                 pop hl          ; hl = codeLengths
  452.                 exx
  453.                 pop bc          ; bc = symbolHandlers
  454.                 ld h,CountBuffer / 256
  455.                 exx
  456. SortLoop:       ld a,(hl)       ; a = length
  457.                 inc hl
  458.                 add a,a
  459.                 exx
  460.                 jr z,SortSkip
  461.                 ld l,a
  462.                 ld e,(hl)
  463.                 inc l
  464.                 ld d,(hl)       ; de = ptr in SortedBuffer
  465.                 rrca
  466.                 ld (de),a       ; store length
  467.                 inc de
  468.                 ld a,(bc)       ; copy handler length
  469.                 inc bc
  470.                 ld (de),a
  471.                 inc de
  472.                 ld a,(bc)       ; copy ptr to handler
  473.                 inc bc
  474.                 ld (de),a
  475.                 inc de
  476.                 ld a,(bc)
  477.                 inc bc
  478.                 ld (de),a
  479.                 inc de
  480.                 ld (hl),d       ; update ptr to SortedBuffer
  481.                 dec l
  482.                 ld (hl),e
  483. SortNext        exx
  484.                 djnz SortLoop
  485.                 dec c
  486.                 jr nz,SortLoop
  487.  
  488. ; build tree
  489.                 ld hl,SortedBuffer      ; hl = ptr to sorted (code-length, symbol-handler)-pairs
  490.                 inc c                   ; b = 0 = bits left   c = 1 = code length
  491.                 call GetNextSymbol
  492.                 pop de                  ; de = treeBuffer
  493.                 call BuildBranch
  494.                 pop hl                  ; hl = treeBufferEnd
  495.                 and a
  496.                 sbc hl,de
  497.                 ret nc
  498.                 jp GzipThrowException
  499.  
  500. SortSkip:       inc bc
  501.                 inc bc
  502.                 inc bc
  503.                 jr SortNext
  504.  
  505. ; b = bits left
  506. ; c = code length
  507. ; de = tree position
  508. ; hl = sorted (code length, symbol) list pointer
  509. ; iy = current branch
  510. BuildBranch:    push iy
  511.                 ld iyl,e
  512.                 ld iyh,d
  513.                 ; generate code for a branch (test 1 bit from the input)
  514.                 ex de,hl
  515.                 ld (hl),#CB             ; +0  SRL C
  516.                 inc hl
  517.                 ld (hl),#39             ; +1
  518.                 inc hl
  519.                 ld (hl),#CC             ; +2  CALL Z,nn
  520.                 inc hl
  521.                 ld (hl),(ReadBitA) & #FF; +3
  522.                 inc hl
  523.                 ld (hl),ReadBitA / 256  ; +4
  524.                 inc hl
  525.                 ld (hl),#DA             ; +5  JP c,nn
  526.                 inc hl
  527.                 inc hl                  ; +6  skip address, filled-in later
  528.                 inc hl                  ; +7
  529.                 ex de,hl
  530.                 call BuildBranchZero
  531.                 call nc,BuildBranchOne
  532.                 pop iy
  533.                 inc b
  534.                 ret
  535.  
  536. BuildBranchOne: ; fill-in address of 'JP C,nn' instruction
  537.                 djnz Branch1
  538. Leaf1:          inc hl          ; symbol length
  539.                 inc hl          ; skip handler length
  540.                 ld a,(hl)
  541.                 inc hl
  542.                 ld (iy + 6),a   ; replace 'nn' with address of symbol handler
  543.                 ld a,(hl)
  544.                 inc hl
  545.                 ld (iy + 7),a
  546.                 jp GetNextSymbol
  547. Branch1:        ld (iy + 6),e   ; replace 'nn' with address of next branch
  548.                 ld (iy + 7),d
  549.                 jp BuildBranch
  550.  
  551. BuildBranchZero:; generate some code after the 'JP C,nn' instruction
  552.                 djnz BuildBranch; generate another branch
  553. Leaf0:          ; Generate code to handle a symbol. One possibility is to
  554.                 ; generate a JP to the handler routine. Usually these handlers
  555.                 ; are small, so instead we inline (=copy) them.
  556.                 inc hl          ; skip symbol length
  557.                 ld a,c
  558.                 push de         ; de = destination
  559.                 ld c,(hl)       ; b = 0   bc = length of handler routine
  560.                 inc hl
  561.                 ld e,(hl)
  562.                 inc hl
  563.                 ld d,(hl)
  564.                 inc hl
  565.                 ex (sp),hl      ; hl = destination  (sp) = SortedBuffer
  566.                 ex de,hl
  567.                 ldir            ; b = 0
  568.                 pop hl
  569.                 ld c,a
  570.                 ;jp GetNextSymbol
  571.  
  572. ; b = bits left
  573. ; c = code length
  574. ; hl = sorted (code length, symbol) list pointer
  575. ; b, c <- updated
  576. ; f <- c: end reached
  577. GetNextSymbol:  inc b
  578.                 ld a,(hl)
  579.                 sub c
  580.                 ret z
  581.                 ret c
  582.                 ld c,(hl)
  583.                 add a,b
  584.                 ld b,a
  585.                 ret
  586.  
  587.  
  588. ; -- Symbol routines used by the 'header decoder' Huffman tree
  589.  
  590. ; Pairs of
  591. ;  length  of the routine (1 bytes)
  592. ;  pointer to the routine (2 bytes)
  593. HeaderSymbols:  db WriteLen_0_len
  594.                 dw WriteLen_0
  595.                 db WriteLen_1_len
  596.                 dw WriteLen_1
  597.                 db WriteLen_2_len
  598.                 dw WriteLen_2
  599.                 db WriteLen_3_len
  600.                 dw WriteLen_3
  601.                 db WriteLen_4_len
  602.                 dw WriteLen_4
  603.                 db WriteLen_5_len
  604.                 dw WriteLen_5
  605.                 db WriteLen_6_len
  606.                 dw WriteLen_6
  607.                 db WriteLen_7_len
  608.                 dw WriteLen_7
  609.                 db WriteLen_8_len
  610.                 dw WriteLen_8
  611.                 db WriteLen_9_len
  612.                 dw WriteLen_9
  613.                 db WriteLen_10_len
  614.                 dw WriteLen_10
  615.                 db WriteLen_11_len
  616.                 dw WriteLen_11
  617.                 db WriteLen_12_len
  618.                 dw WriteLen_12
  619.                 db WriteLen_13_len
  620.                 dw WriteLen_13
  621.                 db WriteLen_14_len
  622.                 dw WriteLen_14
  623.                 db WriteLen_15_len
  624.                 dw WriteLen_15
  625.                 db HeaderCopyLen
  626.                 dw HeaderCopy
  627.                 db HdrZFill3Len
  628.                 dw HdrZFill3
  629.                 db HdrZFill11Len
  630.                 dw HdrZFill11
  631.                 db ThrowInlineLen
  632.                 dw ThrowInline
  633.  
  634. ; For all of these routines, the calling convention is like this:
  635. ; c = bit reader state
  636. ; de = InputBufPos
  637. ; hl = literal/length/distance code lengths position
  638. ; ix = loop counter for nested 8-bit loop
  639.  
  640. ; Header code alphabet symbols 0-15
  641. WriteLen_0:     ld (hl),0
  642.                 jp HeaderNext
  643. WriteLen_0_len: equ $-WriteLen_0
  644.  
  645. WriteLen_1:     ld (hl),1
  646.                 jp HeaderNext
  647. WriteLen_1_len: equ $-WriteLen_1
  648.  
  649. WriteLen_2:     ld (hl),2
  650.                 jp HeaderNext
  651. WriteLen_2_len: equ $-WriteLen_2
  652.  
  653. WriteLen_3:     ld (hl),3
  654.                 jp HeaderNext
  655. WriteLen_3_len: equ $-WriteLen_3
  656.  
  657. WriteLen_4:     ld (hl),4
  658.                 jp HeaderNext
  659. WriteLen_4_len: equ $-WriteLen_4
  660.  
  661. WriteLen_5:     ld (hl),5
  662.                 jp HeaderNext
  663. WriteLen_5_len: equ $-WriteLen_5
  664.  
  665. WriteLen_6:     ld (hl),6
  666.                 jp HeaderNext
  667. WriteLen_6_len: equ $-WriteLen_6
  668.  
  669. WriteLen_7:     ld (hl),7
  670.                 jp HeaderNext
  671. WriteLen_7_len: equ $-WriteLen_7
  672.  
  673. WriteLen_8:     ld (hl),8
  674.                 jp HeaderNext
  675. WriteLen_8_len: equ $-WriteLen_8
  676.  
  677. WriteLen_9:     ld (hl),9
  678.                 jp HeaderNext
  679. WriteLen_9_len: equ $-WriteLen_9
  680.  
  681. WriteLen_10:    ld (hl),10
  682.                 jp HeaderNext
  683. WriteLen_10_len:equ $-WriteLen_10
  684.  
  685. WriteLen_11:    ld (hl),11
  686.                 jp HeaderNext
  687. WriteLen_11_len:equ $-WriteLen_11
  688.  
  689. WriteLen_12:    ld (hl),12
  690.                 jp HeaderNext
  691. WriteLen_12_len:equ $-WriteLen_12
  692.  
  693. WriteLen_13:    ld (hl),13
  694.                 jp HeaderNext
  695. WriteLen_13_len:equ $-WriteLen_13
  696.  
  697. WriteLen_14:    ld (hl),14
  698.                 jp HeaderNext
  699. WriteLen_14_len:equ $-WriteLen_14
  700.  
  701. WriteLen_15:    ld (hl),15
  702.                 jp HeaderNext
  703. WriteLen_15_len:equ $-WriteLen_15
  704.  
  705. ; Header code alphabet symbol 16
  706. HeaderCopy:     call Read2Bits
  707.                 add a,3
  708.                 ld b,a
  709.                 dec hl
  710.                 ld a,(hl)
  711.                 inc hl
  712.                 jp HeaderFill
  713. HeaderCopyLen:  equ $ - HeaderCopy
  714.  
  715. ; Header code alphabet symbol 17
  716. HdrZFill3:      call Read3Bits
  717.                 add a,3         ; 3..10
  718.                 ld b,a
  719.                 xor a
  720.                 jp HeaderFill
  721. HdrZFill3Len:   equ $-HdrZFill3
  722.  
  723. ; Header code alphabet symbol 18
  724. HdrZFill11:     call Read7Bits
  725.                 add a,11        ; 11..138
  726.                 ld b,a
  727.                 xor a
  728.                 jp HeaderFill
  729. HdrZFill11Len:  equ $ - HdrZFill11
  730.  
  731.  
  732. HeaderNext:     inc hl
  733.                 dec ixl
  734.                 jp nz,HeaderTree
  735.                 dec ixh
  736.                 jp nz,HeaderTree
  737.                 ret
  738.  
  739. ; a = fill value
  740. ; b = repeat count
  741. FillLoop:       dec b
  742.                 jp z,HeaderTree
  743. HeaderFill:     ld (hl),a
  744.                 inc hl
  745.                 dec ixl
  746.                 jp nz,FillLoop
  747.                 dec ixh
  748.                 jr nz,FillLoop
  749.                 ret
  750.  
  751. ; Inline-able version of 'GzipThrowException'
  752. ThrowInline:    jp GzipThrowException
  753. ThrowInlineLen: equ $ - ThrowInline
  754.  
  755.  
  756. ; -- Symbol routines used by the 'literal + copy-length' Huffman tree
  757.  
  758. LLSymbols:      db WriteLitLen  ; 0
  759.                 dw WriteLit00
  760.                 db WriteLitLen
  761.                 dw WriteLit01
  762.                 db WriteLitLen
  763.                 dw WriteLit02
  764.                 db WriteLitLen
  765.                 dw WriteLit03
  766.                 db WriteLitLen
  767.                 dw WriteLit04
  768.                 db WriteLitLen
  769.                 dw WriteLit05
  770.                 db WriteLitLen
  771.                 dw WriteLit06
  772.                 db WriteLitLen
  773.                 dw WriteLit07
  774.                 db WriteLitLen
  775.                 dw WriteLit08
  776.                 db WriteLitLen
  777.                 dw WriteLit09
  778.                 db WriteLitLen
  779.                 dw WriteLit0A
  780.                 db WriteLitLen
  781.                 dw WriteLit0B
  782.                 db WriteLitLen
  783.                 dw WriteLit0C
  784.                 db WriteLitLen
  785.                 dw WriteLit0D
  786.                 db WriteLitLen
  787.                 dw WriteLit0E
  788.                 db WriteLitLen
  789.                 dw WriteLit0F
  790.                 db WriteLitLen
  791.                 dw WriteLit10
  792.                 db WriteLitLen
  793.                 dw WriteLit11
  794.                 db WriteLitLen
  795.                 dw WriteLit12
  796.                 db WriteLitLen
  797.                 dw WriteLit13
  798.                 db WriteLitLen
  799.                 dw WriteLit14
  800.                 db WriteLitLen
  801.                 dw WriteLit15
  802.                 db WriteLitLen
  803.                 dw WriteLit16
  804.                 db WriteLitLen
  805.                 dw WriteLit17
  806.                 db WriteLitLen
  807.                 dw WriteLit18
  808.                 db WriteLitLen
  809.                 dw WriteLit19
  810.                 db WriteLitLen
  811.                 dw WriteLit1A
  812.                 db WriteLitLen
  813.                 dw WriteLit1B
  814.                 db WriteLitLen
  815.                 dw WriteLit1C
  816.                 db WriteLitLen
  817.                 dw WriteLit1D
  818.                 db WriteLitLen
  819.                 dw WriteLit1E
  820.                 db WriteLitLen
  821.                 dw WriteLit1F
  822.                 db WriteLitLen
  823.                 dw WriteLit20
  824.                 db WriteLitLen
  825.                 dw WriteLit21
  826.                 db WriteLitLen
  827.                 dw WriteLit22
  828.                 db WriteLitLen
  829.                 dw WriteLit23
  830.                 db WriteLitLen
  831.                 dw WriteLit24
  832.                 db WriteLitLen
  833.                 dw WriteLit25
  834.                 db WriteLitLen
  835.                 dw WriteLit26
  836.                 db WriteLitLen
  837.                 dw WriteLit27
  838.                 db WriteLitLen
  839.                 dw WriteLit28
  840.                 db WriteLitLen
  841.                 dw WriteLit29
  842.                 db WriteLitLen
  843.                 dw WriteLit2A
  844.                 db WriteLitLen
  845.                 dw WriteLit2B
  846.                 db WriteLitLen
  847.                 dw WriteLit2C
  848.                 db WriteLitLen
  849.                 dw WriteLit2D
  850.                 db WriteLitLen
  851.                 dw WriteLit2E
  852.                 db WriteLitLen
  853.                 dw WriteLit2F
  854.                 db WriteLitLen
  855.                 dw WriteLit30
  856.                 db WriteLitLen
  857.                 dw WriteLit31
  858.                 db WriteLitLen
  859.                 dw WriteLit32
  860.                 db WriteLitLen
  861.                 dw WriteLit33
  862.                 db WriteLitLen
  863.                 dw WriteLit34
  864.                 db WriteLitLen
  865.                 dw WriteLit35
  866.                 db WriteLitLen
  867.                 dw WriteLit36
  868.                 db WriteLitLen
  869.                 dw WriteLit37
  870.                 db WriteLitLen
  871.                 dw WriteLit38
  872.                 db WriteLitLen
  873.                 dw WriteLit39
  874.                 db WriteLitLen
  875.                 dw WriteLit3A
  876.                 db WriteLitLen
  877.                 dw WriteLit3B
  878.                 db WriteLitLen
  879.                 dw WriteLit3C
  880.                 db WriteLitLen
  881.                 dw WriteLit3D
  882.                 db WriteLitLen
  883.                 dw WriteLit3E
  884.                 db WriteLitLen
  885.                 dw WriteLit3F
  886.                 db WriteLitLen
  887.                 dw WriteLit40
  888.                 db WriteLitLen
  889.                 dw WriteLit41
  890.                 db WriteLitLen
  891.                 dw WriteLit42
  892.                 db WriteLitLen
  893.                 dw WriteLit43
  894.                 db WriteLitLen
  895.                 dw WriteLit44
  896.                 db WriteLitLen
  897.                 dw WriteLit45
  898.                 db WriteLitLen
  899.                 dw WriteLit46
  900.                 db WriteLitLen
  901.                 dw WriteLit47
  902.                 db WriteLitLen
  903.                 dw WriteLit48
  904.                 db WriteLitLen
  905.                 dw WriteLit49
  906.                 db WriteLitLen
  907.                 dw WriteLit4A
  908.                 db WriteLitLen
  909.                 dw WriteLit4B
  910.                 db WriteLitLen
  911.                 dw WriteLit4C
  912.                 db WriteLitLen
  913.                 dw WriteLit4D
  914.                 db WriteLitLen
  915.                 dw WriteLit4E
  916.                 db WriteLitLen
  917.                 dw WriteLit4F
  918.                 db WriteLitLen
  919.                 dw WriteLit50
  920.                 db WriteLitLen
  921.                 dw WriteLit51
  922.                 db WriteLitLen
  923.                 dw WriteLit52
  924.                 db WriteLitLen
  925.                 dw WriteLit53
  926.                 db WriteLitLen
  927.                 dw WriteLit54
  928.                 db WriteLitLen
  929.                 dw WriteLit55
  930.                 db WriteLitLen
  931.                 dw WriteLit56
  932.                 db WriteLitLen
  933.                 dw WriteLit57
  934.                 db WriteLitLen
  935.                 dw WriteLit58
  936.                 db WriteLitLen
  937.                 dw WriteLit59
  938.                 db WriteLitLen
  939.                 dw WriteLit5A
  940.                 db WriteLitLen
  941.                 dw WriteLit5B
  942.                 db WriteLitLen
  943.                 dw WriteLit5C
  944.                 db WriteLitLen
  945.                 dw WriteLit5D
  946.                 db WriteLitLen
  947.                 dw WriteLit5E
  948.                 db WriteLitLen
  949.                 dw WriteLit5F
  950.                 db WriteLitLen
  951.                 dw WriteLit60
  952.                 db WriteLitLen
  953.                 dw WriteLit61
  954.                 db WriteLitLen
  955.                 dw WriteLit62
  956.                 db WriteLitLen
  957.                 dw WriteLit63
  958.                 db WriteLitLen
  959.                 dw WriteLit64
  960.                 db WriteLitLen
  961.                 dw WriteLit65
  962.                 db WriteLitLen
  963.                 dw WriteLit66
  964.                 db WriteLitLen
  965.                 dw WriteLit67
  966.                 db WriteLitLen
  967.                 dw WriteLit68
  968.                 db WriteLitLen
  969.                 dw WriteLit69
  970.                 db WriteLitLen
  971.                 dw WriteLit6A
  972.                 db WriteLitLen
  973.                 dw WriteLit6B
  974.                 db WriteLitLen
  975.                 dw WriteLit6C
  976.                 db WriteLitLen
  977.                 dw WriteLit6D
  978.                 db WriteLitLen
  979.                 dw WriteLit6E
  980.                 db WriteLitLen
  981.                 dw WriteLit6F
  982.                 db WriteLitLen
  983.                 dw WriteLit70
  984.                 db WriteLitLen
  985.                 dw WriteLit71
  986.                 db WriteLitLen
  987.                 dw WriteLit72
  988.                 db WriteLitLen
  989.                 dw WriteLit73
  990.                 db WriteLitLen
  991.                 dw WriteLit74
  992.                 db WriteLitLen
  993.                 dw WriteLit75
  994.                 db WriteLitLen
  995.                 dw WriteLit76
  996.                 db WriteLitLen
  997.                 dw WriteLit77
  998.                 db WriteLitLen
  999.                 dw WriteLit78
  1000.                 db WriteLitLen
  1001.                 dw WriteLit79
  1002.                 db WriteLitLen
  1003.                 dw WriteLit7A
  1004.                 db WriteLitLen
  1005.                 dw WriteLit7B
  1006.                 db WriteLitLen
  1007.                 dw WriteLit7C
  1008.                 db WriteLitLen
  1009.                 dw WriteLit7D
  1010.                 db WriteLitLen
  1011.                 dw WriteLit7E
  1012.                 db WriteLitLen
  1013.                 dw WriteLit7F
  1014.                 db WriteLitLen
  1015.                 dw WriteLit80
  1016.                 db WriteLitLen
  1017.                 dw WriteLit81
  1018.                 db WriteLitLen
  1019.                 dw WriteLit82
  1020.                 db WriteLitLen
  1021.                 dw WriteLit83
  1022.                 db WriteLitLen
  1023.                 dw WriteLit84
  1024.                 db WriteLitLen
  1025.                 dw WriteLit85
  1026.                 db WriteLitLen
  1027.                 dw WriteLit86
  1028.                 db WriteLitLen
  1029.                 dw WriteLit87
  1030.                 db WriteLitLen
  1031.                 dw WriteLit88
  1032.                 db WriteLitLen
  1033.                 dw WriteLit89
  1034.                 db WriteLitLen
  1035.                 dw WriteLit8A
  1036.                 db WriteLitLen
  1037.                 dw WriteLit8B
  1038.                 db WriteLitLen
  1039.                 dw WriteLit8C
  1040.                 db WriteLitLen
  1041.                 dw WriteLit8D
  1042.                 db WriteLitLen
  1043.                 dw WriteLit8E
  1044.                 db WriteLitLen
  1045.                 dw WriteLit8F
  1046.                 db WriteLitLen
  1047.                 dw WriteLit90
  1048.                 db WriteLitLen
  1049.                 dw WriteLit91
  1050.                 db WriteLitLen
  1051.                 dw WriteLit92
  1052.                 db WriteLitLen
  1053.                 dw WriteLit93
  1054.                 db WriteLitLen
  1055.                 dw WriteLit94
  1056.                 db WriteLitLen
  1057.                 dw WriteLit95
  1058.                 db WriteLitLen
  1059.                 dw WriteLit96
  1060.                 db WriteLitLen
  1061.                 dw WriteLit97
  1062.                 db WriteLitLen
  1063.                 dw WriteLit98
  1064.                 db WriteLitLen
  1065.                 dw WriteLit99
  1066.                 db WriteLitLen
  1067.                 dw WriteLit9A
  1068.                 db WriteLitLen
  1069.                 dw WriteLit9B
  1070.                 db WriteLitLen
  1071.                 dw WriteLit9C
  1072.                 db WriteLitLen
  1073.                 dw WriteLit9D
  1074.                 db WriteLitLen
  1075.                 dw WriteLit9E
  1076.                 db WriteLitLen
  1077.                 dw WriteLit9F
  1078.                 db WriteLitLen
  1079.                 dw WriteLitA0
  1080.                 db WriteLitLen
  1081.                 dw WriteLitA1
  1082.                 db WriteLitLen
  1083.                 dw WriteLitA2
  1084.                 db WriteLitLen
  1085.                 dw WriteLitA3
  1086.                 db WriteLitLen
  1087.                 dw WriteLitA4
  1088.                 db WriteLitLen
  1089.                 dw WriteLitA5
  1090.                 db WriteLitLen
  1091.                 dw WriteLitA6
  1092.                 db WriteLitLen
  1093.                 dw WriteLitA7
  1094.                 db WriteLitLen
  1095.                 dw WriteLitA8
  1096.                 db WriteLitLen
  1097.                 dw WriteLitA9
  1098.                 db WriteLitLen
  1099.                 dw WriteLitAA
  1100.                 db WriteLitLen
  1101.                 dw WriteLitAB
  1102.                 db WriteLitLen
  1103.                 dw WriteLitAC
  1104.                 db WriteLitLen
  1105.                 dw WriteLitAD
  1106.                 db WriteLitLen
  1107.                 dw WriteLitAE
  1108.                 db WriteLitLen
  1109.                 dw WriteLitAF
  1110.                 db WriteLitLen
  1111.                 dw WriteLitB0
  1112.                 db WriteLitLen
  1113.                 dw WriteLitB1
  1114.                 db WriteLitLen
  1115.                 dw WriteLitB2
  1116.                 db WriteLitLen
  1117.                 dw WriteLitB3
  1118.                 db WriteLitLen
  1119.                 dw WriteLitB4
  1120.                 db WriteLitLen
  1121.                 dw WriteLitB5
  1122.                 db WriteLitLen
  1123.                 dw WriteLitB6
  1124.                 db WriteLitLen
  1125.                 dw WriteLitB7
  1126.                 db WriteLitLen
  1127.                 dw WriteLitB8
  1128.                 db WriteLitLen
  1129.                 dw WriteLitB9
  1130.                 db WriteLitLen
  1131.                 dw WriteLitBA
  1132.                 db WriteLitLen
  1133.                 dw WriteLitBB
  1134.                 db WriteLitLen
  1135.                 dw WriteLitBC
  1136.                 db WriteLitLen
  1137.                 dw WriteLitBD
  1138.                 db WriteLitLen
  1139.                 dw WriteLitBE
  1140.                 db WriteLitLen
  1141.                 dw WriteLitBF
  1142.                 db WriteLitLen
  1143.                 dw WriteLitC0
  1144.                 db WriteLitLen
  1145.                 dw WriteLitC1
  1146.                 db WriteLitLen
  1147.                 dw WriteLitC2
  1148.                 db WriteLitLen
  1149.                 dw WriteLitC3
  1150.                 db WriteLitLen
  1151.                 dw WriteLitC4
  1152.                 db WriteLitLen
  1153.                 dw WriteLitC5
  1154.                 db WriteLitLen
  1155.                 dw WriteLitC6
  1156.                 db WriteLitLen
  1157.                 dw WriteLitC7
  1158.                 db WriteLitLen
  1159.                 dw WriteLitC8
  1160.                 db WriteLitLen
  1161.                 dw WriteLitC9
  1162.                 db WriteLitLen
  1163.                 dw WriteLitCA
  1164.                 db WriteLitLen
  1165.                 dw WriteLitCB
  1166.                 db WriteLitLen
  1167.                 dw WriteLitCC
  1168.                 db WriteLitLen
  1169.                 dw WriteLitCD
  1170.                 db WriteLitLen
  1171.                 dw WriteLitCE
  1172.                 db WriteLitLen
  1173.                 dw WriteLitCF
  1174.                 db WriteLitLen
  1175.                 dw WriteLitD0
  1176.                 db WriteLitLen
  1177.                 dw WriteLitD1
  1178.                 db WriteLitLen
  1179.                 dw WriteLitD2
  1180.                 db WriteLitLen
  1181.                 dw WriteLitD3
  1182.                 db WriteLitLen
  1183.                 dw WriteLitD4
  1184.                 db WriteLitLen
  1185.                 dw WriteLitD5
  1186.                 db WriteLitLen
  1187.                 dw WriteLitD6
  1188.                 db WriteLitLen
  1189.                 dw WriteLitD7
  1190.                 db WriteLitLen
  1191.                 dw WriteLitD8
  1192.                 db WriteLitLen
  1193.                 dw WriteLitD9
  1194.                 db WriteLitLen
  1195.                 dw WriteLitDA
  1196.                 db WriteLitLen
  1197.                 dw WriteLitDB
  1198.                 db WriteLitLen
  1199.                 dw WriteLitDC
  1200.                 db WriteLitLen
  1201.                 dw WriteLitDD
  1202.                 db WriteLitLen
  1203.                 dw WriteLitDE
  1204.                 db WriteLitLen
  1205.                 dw WriteLitDF
  1206.                 db WriteLitLen
  1207.                 dw WriteLitE0
  1208.                 db WriteLitLen
  1209.                 dw WriteLitE1
  1210.                 db WriteLitLen
  1211.                 dw WriteLitE2
  1212.                 db WriteLitLen
  1213.                 dw WriteLitE3
  1214.                 db WriteLitLen
  1215.                 dw WriteLitE4
  1216.                 db WriteLitLen
  1217.                 dw WriteLitE5
  1218.                 db WriteLitLen
  1219.                 dw WriteLitE6
  1220.                 db WriteLitLen
  1221.                 dw WriteLitE7
  1222.                 db WriteLitLen
  1223.                 dw WriteLitE8
  1224.                 db WriteLitLen
  1225.                 dw WriteLitE9
  1226.                 db WriteLitLen
  1227.                 dw WriteLitEA
  1228.                 db WriteLitLen
  1229.                 dw WriteLitEB
  1230.                 db WriteLitLen
  1231.                 dw WriteLitEC
  1232.                 db WriteLitLen
  1233.                 dw WriteLitED
  1234.                 db WriteLitLen
  1235.                 dw WriteLitEE
  1236.                 db WriteLitLen
  1237.                 dw WriteLitEF
  1238.                 db WriteLitLen
  1239.                 dw WriteLitF0
  1240.                 db WriteLitLen
  1241.                 dw WriteLitF1
  1242.                 db WriteLitLen
  1243.                 dw WriteLitF2
  1244.                 db WriteLitLen
  1245.                 dw WriteLitF3
  1246.                 db WriteLitLen
  1247.                 dw WriteLitF4
  1248.                 db WriteLitLen
  1249.                 dw WriteLitF5
  1250.                 db WriteLitLen
  1251.                 dw WriteLitF6
  1252.                 db WriteLitLen
  1253.                 dw WriteLitF7
  1254.                 db WriteLitLen
  1255.                 dw WriteLitF8
  1256.                 db WriteLitLen
  1257.                 dw WriteLitF9
  1258.                 db WriteLitLen
  1259.                 dw WriteLitFA
  1260.                 db WriteLitLen
  1261.                 dw WriteLitFB
  1262.                 db WriteLitLen
  1263.                 dw WriteLitFC
  1264.                 db WriteLitLen
  1265.                 dw WriteLitFD
  1266.                 db WriteLitLen
  1267.                 dw WriteLitFE
  1268.                 db WriteLitLen
  1269.                 dw WriteLitFF
  1270.                 db EndBlockLen  ; 256
  1271.                 dw EndBlock
  1272.                 db CopyLen0Len  ; 257
  1273.                 dw CopyLen0
  1274.                 db CopyLen1Len
  1275.                 dw CopyLen1
  1276.                 db CopyLen2Len
  1277.                 dw CopyLen2
  1278.                 db CopyLen3Len
  1279.                 dw CopyLen3
  1280.                 db CopyLen4Len
  1281.                 dw CopyLen4
  1282.                 db CopyLen5Len
  1283.                 dw CopyLen5
  1284.                 db CopyLen6Len
  1285.                 dw CopyLen6
  1286.                 db CopyLen7Len
  1287.                 dw CopyLen7
  1288.                 db CopyLen8Len
  1289.                 dw CopyLen8
  1290.                 db CopyLen9Len
  1291.                 dw CopyLen9
  1292.                 db CopyLen10Len
  1293.                 dw CopyLen10
  1294.                 db CopyLen11Len
  1295.                 dw CopyLen11
  1296.                 db CopyLen12Len
  1297.                 dw CopyLen12
  1298.                 db CopyLen13Len
  1299.                 dw CopyLen13
  1300.                 db CopyLen14Len
  1301.                 dw CopyLen14
  1302.                 db CopyLen15Len
  1303.                 dw CopyLen15
  1304.                 db CopyLen16Len
  1305.                 dw CopyLen16
  1306.                 db CopyLen17Len
  1307.                 dw CopyLen17
  1308.                 db CopyLen18Len
  1309.                 dw CopyLen18
  1310.                 db CopyLen19Len
  1311.                 dw CopyLen19
  1312.                 db CopyLen20Len
  1313.                 dw CopyLen20
  1314.                 db CopyLen21Len
  1315.                 dw CopyLen21
  1316.                 db CopyLen22Len
  1317.                 dw CopyLen22
  1318.                 db CopyLen23Len
  1319.                 dw CopyLen23
  1320.                 db CopyLen24Len
  1321.                 dw CopyLen24
  1322.                 db CopyLen25Len
  1323.                 dw CopyLen25
  1324.                 db CopyLen26Len
  1325.                 dw CopyLen26
  1326.                 db CopyLen27Len
  1327.                 dw CopyLen27
  1328.                 db CopyLen28Len
  1329.                 dw CopyLen28
  1330.                 db ThrowInlineLen       ; 286
  1331.                 dw ThrowInline
  1332.                 db ThrowInlineLen       ; 287
  1333.                 dw ThrowInline
  1334.  
  1335. ; For all of these routines, the calling convention is like this:
  1336. ; c = bit reader state
  1337. ; de = InputBufPos
  1338. ; hl = OutputBufPos
  1339. ; iy = Write_AndNext
  1340.  
  1341. ; Literal/length alphabet symbols 0-255
  1342. WriteLit00:     ld (hl),#00
  1343.                 jp (iy)         ; Write_AndNext
  1344. WriteLit01:     ld (hl),#01
  1345.                 jp (iy)
  1346. WriteLit02:     ld (hl),#02
  1347.                 jp (iy)
  1348. WriteLit03:     ld (hl),#03
  1349.                 jp (iy)
  1350. WriteLit04:     ld (hl),#04
  1351.                 jp (iy)
  1352. WriteLit05:     ld (hl),#05
  1353.                 jp (iy)
  1354. WriteLit06:     ld (hl),#06
  1355.                 jp (iy)
  1356. WriteLit07:     ld (hl),#07
  1357.                 jp (iy)
  1358. WriteLit08:     ld (hl),#08
  1359.                 jp (iy)
  1360. WriteLit09:     ld (hl),#09
  1361.                 jp (iy)
  1362. WriteLit0A:     ld (hl),#0A
  1363.                 jp (iy)
  1364. WriteLit0B:     ld (hl),#0B
  1365.                 jp (iy)
  1366. WriteLit0C:     ld (hl),#0C
  1367.                 jp (iy)
  1368. WriteLit0D:     ld (hl),#0D
  1369.                 jp (iy)
  1370. WriteLit0E:     ld (hl),#0E
  1371.                 jp (iy)
  1372. WriteLit0F:     ld (hl),#0F
  1373.                 jp (iy)
  1374. WriteLit10:     ld (hl),#10
  1375.                 jp (iy)
  1376. WriteLit11:     ld (hl),#11
  1377.                 jp (iy)
  1378. WriteLit12:     ld (hl),#12
  1379.                 jp (iy)
  1380. WriteLit13:     ld (hl),#13
  1381.                 jp (iy)
  1382. WriteLit14:     ld (hl),#14
  1383.                 jp (iy)
  1384. WriteLit15:     ld (hl),#15
  1385.                 jp (iy)
  1386. WriteLit16:     ld (hl),#16
  1387.                 jp (iy)
  1388. WriteLit17:     ld (hl),#17
  1389.                 jp (iy)
  1390. WriteLit18:     ld (hl),#18
  1391.                 jp (iy)
  1392. WriteLit19:     ld (hl),#19
  1393.                 jp (iy)
  1394. WriteLit1A:     ld (hl),#1A
  1395.                 jp (iy)
  1396. WriteLit1B:     ld (hl),#1B
  1397.                 jp (iy)
  1398. WriteLit1C:     ld (hl),#1C
  1399.                 jp (iy)
  1400. WriteLit1D:     ld (hl),#1D
  1401.                 jp (iy)
  1402. WriteLit1E:     ld (hl),#1E
  1403.                 jp (iy)
  1404. WriteLit1F:     ld (hl),#1F
  1405.                 jp (iy)
  1406. WriteLit20:     ld (hl),#20
  1407.                 jp (iy)
  1408. WriteLit21:     ld (hl),#21
  1409.                 jp (iy)
  1410. WriteLit22:     ld (hl),#22
  1411.                 jp (iy)
  1412. WriteLit23:     ld (hl),#23
  1413.                 jp (iy)
  1414. WriteLit24:     ld (hl),#24
  1415.                 jp (iy)
  1416. WriteLit25:     ld (hl),#25
  1417.                 jp (iy)
  1418. WriteLit26:     ld (hl),#26
  1419.                 jp (iy)
  1420. WriteLit27:     ld (hl),#27
  1421.                 jp (iy)
  1422. WriteLit28:     ld (hl),#28
  1423.                 jp (iy)
  1424. WriteLit29:     ld (hl),#29
  1425.                 jp (iy)
  1426. WriteLit2A:     ld (hl),#2A
  1427.                 jp (iy)
  1428. WriteLit2B:     ld (hl),#2B
  1429.                 jp (iy)
  1430. WriteLit2C:     ld (hl),#2C
  1431.                 jp (iy)
  1432. WriteLit2D:     ld (hl),#2D
  1433.                 jp (iy)
  1434. WriteLit2E:     ld (hl),#2E
  1435.                 jp (iy)
  1436. WriteLit2F:     ld (hl),#2F
  1437.                 jp (iy)
  1438. WriteLit30:     ld (hl),#30
  1439.                 jp (iy)
  1440. WriteLit31:     ld (hl),#31
  1441.                 jp (iy)
  1442. WriteLit32:     ld (hl),#32
  1443.                 jp (iy)
  1444. WriteLit33:     ld (hl),#33
  1445.                 jp (iy)
  1446. WriteLit34:     ld (hl),#34
  1447.                 jp (iy)
  1448. WriteLit35:     ld (hl),#35
  1449.                 jp (iy)
  1450. WriteLit36:     ld (hl),#36
  1451.                 jp (iy)
  1452. WriteLit37:     ld (hl),#37
  1453.                 jp (iy)
  1454. WriteLit38:     ld (hl),#38
  1455.                 jp (iy)
  1456. WriteLit39:     ld (hl),#39
  1457.                 jp (iy)
  1458. WriteLit3A:     ld (hl),#3A
  1459.                 jp (iy)
  1460. WriteLit3B:     ld (hl),#3B
  1461.                 jp (iy)
  1462. WriteLit3C:     ld (hl),#3C
  1463.                 jp (iy)
  1464. WriteLit3D:     ld (hl),#3D
  1465.                 jp (iy)
  1466. WriteLit3E:     ld (hl),#3E
  1467.                 jp (iy)
  1468. WriteLit3F:     ld (hl),#3F
  1469.                 jp (iy)
  1470. WriteLit40:     ld (hl),#40
  1471.                 jp (iy)
  1472. WriteLit41:     ld (hl),#41
  1473.                 jp (iy)
  1474. WriteLit42:     ld (hl),#42
  1475.                 jp (iy)
  1476. WriteLit43:     ld (hl),#43
  1477.                 jp (iy)
  1478. WriteLit44:     ld (hl),#44
  1479.                 jp (iy)
  1480. WriteLit45:     ld (hl),#45
  1481.                 jp (iy)
  1482. WriteLit46:     ld (hl),#46
  1483.                 jp (iy)
  1484. WriteLit47:     ld (hl),#47
  1485.                 jp (iy)
  1486. WriteLit48:     ld (hl),#48
  1487.                 jp (iy)
  1488. WriteLit49:     ld (hl),#49
  1489.                 jp (iy)
  1490. WriteLit4A:     ld (hl),#4A
  1491.                 jp (iy)
  1492. WriteLit4B:     ld (hl),#4B
  1493.                 jp (iy)
  1494. WriteLit4C:     ld (hl),#4C
  1495.                 jp (iy)
  1496. WriteLit4D:     ld (hl),#4D
  1497.                 jp (iy)
  1498. WriteLit4E:     ld (hl),#4E
  1499.                 jp (iy)
  1500. WriteLit4F:     ld (hl),#4F
  1501.                 jp (iy)
  1502. WriteLit50:     ld (hl),#50
  1503.                 jp (iy)
  1504. WriteLit51:     ld (hl),#51
  1505.                 jp (iy)
  1506. WriteLit52:     ld (hl),#52
  1507.                 jp (iy)
  1508. WriteLit53:     ld (hl),#53
  1509.                 jp (iy)
  1510. WriteLit54:     ld (hl),#54
  1511.                 jp (iy)
  1512. WriteLit55:     ld (hl),#55
  1513.                 jp (iy)
  1514. WriteLit56:     ld (hl),#56
  1515.                 jp (iy)
  1516. WriteLit57:     ld (hl),#57
  1517.                 jp (iy)
  1518. WriteLit58:     ld (hl),#58
  1519.                 jp (iy)
  1520. WriteLit59:     ld (hl),#59
  1521.                 jp (iy)
  1522. WriteLit5A:     ld (hl),#5A
  1523.                 jp (iy)
  1524. WriteLit5B:     ld (hl),#5B
  1525.                 jp (iy)
  1526. WriteLit5C:     ld (hl),#5C
  1527.                 jp (iy)
  1528. WriteLit5D:     ld (hl),#5D
  1529.                 jp (iy)
  1530. WriteLit5E:     ld (hl),#5E
  1531.                 jp (iy)
  1532. WriteLit5F:     ld (hl),#5F
  1533.                 jp (iy)
  1534. WriteLit60:     ld (hl),#60
  1535.                 jp (iy)
  1536. WriteLit61:     ld (hl),#61
  1537.                 jp (iy)
  1538. WriteLit62:     ld (hl),#62
  1539.                 jp (iy)
  1540. WriteLit63:     ld (hl),#63
  1541.                 jp (iy)
  1542. WriteLit64:     ld (hl),#64
  1543.                 jp (iy)
  1544. WriteLit65:     ld (hl),#65
  1545.                 jp (iy)
  1546. WriteLit66:     ld (hl),#66
  1547.                 jp (iy)
  1548. WriteLit67:     ld (hl),#67
  1549.                 jp (iy)
  1550. WriteLit68:     ld (hl),#68
  1551.                 jp (iy)
  1552. WriteLit69:     ld (hl),#69
  1553.                 jp (iy)
  1554. WriteLit6A:     ld (hl),#6A
  1555.                 jp (iy)
  1556. WriteLit6B:     ld (hl),#6B
  1557.                 jp (iy)
  1558. WriteLit6C:     ld (hl),#6C
  1559.                 jp (iy)
  1560. WriteLit6D:     ld (hl),#6D
  1561.                 jp (iy)
  1562. WriteLit6E:     ld (hl),#6E
  1563.                 jp (iy)
  1564. WriteLit6F:     ld (hl),#6F
  1565.                 jp (iy)
  1566. WriteLit70:     ld (hl),#70
  1567.                 jp (iy)
  1568. WriteLit71:     ld (hl),#71
  1569.                 jp (iy)
  1570. WriteLit72:     ld (hl),#72
  1571.                 jp (iy)
  1572. WriteLit73:     ld (hl),#73
  1573.                 jp (iy)
  1574. WriteLit74:     ld (hl),#74
  1575.                 jp (iy)
  1576. WriteLit75:     ld (hl),#75
  1577.                 jp (iy)
  1578. WriteLit76:     ld (hl),#76
  1579.                 jp (iy)
  1580. WriteLit77:     ld (hl),#77
  1581.                 jp (iy)
  1582. WriteLit78:     ld (hl),#78
  1583.                 jp (iy)
  1584. WriteLit79:     ld (hl),#79
  1585.                 jp (iy)
  1586. WriteLit7A:     ld (hl),#7A
  1587.                 jp (iy)
  1588. WriteLit7B:     ld (hl),#7B
  1589.                 jp (iy)
  1590. WriteLit7C:     ld (hl),#7C
  1591.                 jp (iy)
  1592. WriteLit7D:     ld (hl),#7D
  1593.                 jp (iy)
  1594. WriteLit7E:     ld (hl),#7E
  1595.                 jp (iy)
  1596. WriteLit7F:     ld (hl),#7F
  1597.                 jp (iy)
  1598. WriteLit80:     ld (hl),#80
  1599.                 jp (iy)
  1600. WriteLit81:     ld (hl),#81
  1601.                 jp (iy)
  1602. WriteLit82:     ld (hl),#82
  1603.                 jp (iy)
  1604. WriteLit83:     ld (hl),#83
  1605.                 jp (iy)
  1606. WriteLit84:     ld (hl),#84
  1607.                 jp (iy)
  1608. WriteLit85:     ld (hl),#85
  1609.                 jp (iy)
  1610. WriteLit86:     ld (hl),#86
  1611.                 jp (iy)
  1612. WriteLit87:     ld (hl),#87
  1613.                 jp (iy)
  1614. WriteLit88:     ld (hl),#88
  1615.                 jp (iy)
  1616. WriteLit89:     ld (hl),#89
  1617.                 jp (iy)
  1618. WriteLit8A:     ld (hl),#8A
  1619.                 jp (iy)
  1620. WriteLit8B:     ld (hl),#8B
  1621.                 jp (iy)
  1622. WriteLit8C:     ld (hl),#8C
  1623.                 jp (iy)
  1624. WriteLit8D:     ld (hl),#8D
  1625.                 jp (iy)
  1626. WriteLit8E:     ld (hl),#8E
  1627.                 jp (iy)
  1628. WriteLit8F:     ld (hl),#8F
  1629.                 jp (iy)
  1630. WriteLit90:     ld (hl),#90
  1631.                 jp (iy)
  1632. WriteLit91:     ld (hl),#91
  1633.                 jp (iy)
  1634. WriteLit92:     ld (hl),#92
  1635.                 jp (iy)
  1636. WriteLit93:     ld (hl),#93
  1637.                 jp (iy)
  1638. WriteLit94:     ld (hl),#94
  1639.                 jp (iy)
  1640. WriteLit95:     ld (hl),#95
  1641.                 jp (iy)
  1642. WriteLit96:     ld (hl),#96
  1643.                 jp (iy)
  1644. WriteLit97:     ld (hl),#97
  1645.                 jp (iy)
  1646. WriteLit98:     ld (hl),#98
  1647.                 jp (iy)
  1648. WriteLit99:     ld (hl),#99
  1649.                 jp (iy)
  1650. WriteLit9A:     ld (hl),#9A
  1651.                 jp (iy)
  1652. WriteLit9B:     ld (hl),#9B
  1653.                 jp (iy)
  1654. WriteLit9C:     ld (hl),#9C
  1655.                 jp (iy)
  1656. WriteLit9D:     ld (hl),#9D
  1657.                 jp (iy)
  1658. WriteLit9E:     ld (hl),#9E
  1659.                 jp (iy)
  1660. WriteLit9F:     ld (hl),#9F
  1661.                 jp (iy)
  1662. WriteLitA0:     ld (hl),#A0
  1663.                 jp (iy)
  1664. WriteLitA1:     ld (hl),#A1
  1665.                 jp (iy)
  1666. WriteLitA2:     ld (hl),#A2
  1667.                 jp (iy)
  1668. WriteLitA3:     ld (hl),#A3
  1669.                 jp (iy)
  1670. WriteLitA4:     ld (hl),#A4
  1671.                 jp (iy)
  1672. WriteLitA5:     ld (hl),#A5
  1673.                 jp (iy)
  1674. WriteLitA6:     ld (hl),#A6
  1675.                 jp (iy)
  1676. WriteLitA7:     ld (hl),#A7
  1677.                 jp (iy)
  1678. WriteLitA8:     ld (hl),#A8
  1679.                 jp (iy)
  1680. WriteLitA9:     ld (hl),#A9
  1681.                 jp (iy)
  1682. WriteLitAA:     ld (hl),#AA
  1683.                 jp (iy)
  1684. WriteLitAB:     ld (hl),#AB
  1685.                 jp (iy)
  1686. WriteLitAC:     ld (hl),#AC
  1687.                 jp (iy)
  1688. WriteLitAD:     ld (hl),#AD
  1689.                 jp (iy)
  1690. WriteLitAE:     ld (hl),#AE
  1691.                 jp (iy)
  1692. WriteLitAF:     ld (hl),#AF
  1693.                 jp (iy)
  1694. WriteLitB0:     ld (hl),#B0
  1695.                 jp (iy)
  1696. WriteLitB1:     ld (hl),#B1
  1697.                 jp (iy)
  1698. WriteLitB2:     ld (hl),#B2
  1699.                 jp (iy)
  1700. WriteLitB3:     ld (hl),#B3
  1701.                 jp (iy)
  1702. WriteLitB4:     ld (hl),#B4
  1703.                 jp (iy)
  1704. WriteLitB5:     ld (hl),#B5
  1705.                 jp (iy)
  1706. WriteLitB6:     ld (hl),#B6
  1707.                 jp (iy)
  1708. WriteLitB7:     ld (hl),#B7
  1709.                 jp (iy)
  1710. WriteLitB8:     ld (hl),#B8
  1711.                 jp (iy)
  1712. WriteLitB9:     ld (hl),#B9
  1713.                 jp (iy)
  1714. WriteLitBA:     ld (hl),#BA
  1715.                 jp (iy)
  1716. WriteLitBB:     ld (hl),#BB
  1717.                 jp (iy)
  1718. WriteLitBC:     ld (hl),#BC
  1719.                 jp (iy)
  1720. WriteLitBD:     ld (hl),#BD
  1721.                 jp (iy)
  1722. WriteLitBE:     ld (hl),#BE
  1723.                 jp (iy)
  1724. WriteLitBF:     ld (hl),#BF
  1725.                 jp (iy)
  1726. WriteLitC0:     ld (hl),#C0
  1727.                 jp (iy)
  1728. WriteLitC1:     ld (hl),#C1
  1729.                 jp (iy)
  1730. WriteLitC2:     ld (hl),#C2
  1731.                 jp (iy)
  1732. WriteLitC3:     ld (hl),#C3
  1733.                 jp (iy)
  1734. WriteLitC4:     ld (hl),#C4
  1735.                 jp (iy)
  1736. WriteLitC5:     ld (hl),#C5
  1737.                 jp (iy)
  1738. WriteLitC6:     ld (hl),#C6
  1739.                 jp (iy)
  1740. WriteLitC7:     ld (hl),#C7
  1741.                 jp (iy)
  1742. WriteLitC8:     ld (hl),#C8
  1743.                 jp (iy)
  1744. WriteLitC9:     ld (hl),#C9
  1745.                 jp (iy)
  1746. WriteLitCA:     ld (hl),#CA
  1747.                 jp (iy)
  1748. WriteLitCB:     ld (hl),#CB
  1749.                 jp (iy)
  1750. WriteLitCC:     ld (hl),#CC
  1751.                 jp (iy)
  1752. WriteLitCD:     ld (hl),#CD
  1753.                 jp (iy)
  1754. WriteLitCE:     ld (hl),#CE
  1755.                 jp (iy)
  1756. WriteLitCF:     ld (hl),#CF
  1757.                 jp (iy)
  1758. WriteLitD0:     ld (hl),#D0
  1759.                 jp (iy)
  1760. WriteLitD1:     ld (hl),#D1
  1761.                 jp (iy)
  1762. WriteLitD2:     ld (hl),#D2
  1763.                 jp (iy)
  1764. WriteLitD3:     ld (hl),#D3
  1765.                 jp (iy)
  1766. WriteLitD4:     ld (hl),#D4
  1767.                 jp (iy)
  1768. WriteLitD5:     ld (hl),#D5
  1769.                 jp (iy)
  1770. WriteLitD6:     ld (hl),#D6
  1771.                 jp (iy)
  1772. WriteLitD7:     ld (hl),#D7
  1773.                 jp (iy)
  1774. WriteLitD8:     ld (hl),#D8
  1775.                 jp (iy)
  1776. WriteLitD9:     ld (hl),#D9
  1777.                 jp (iy)
  1778. WriteLitDA:     ld (hl),#DA
  1779.                 jp (iy)
  1780. WriteLitDB:     ld (hl),#DB
  1781.                 jp (iy)
  1782. WriteLitDC:     ld (hl),#DC
  1783.                 jp (iy)
  1784. WriteLitDD:     ld (hl),#DD
  1785.                 jp (iy)
  1786. WriteLitDE:     ld (hl),#DE
  1787.                 jp (iy)
  1788. WriteLitDF:     ld (hl),#DF
  1789.                 jp (iy)
  1790. WriteLitE0:     ld (hl),#E0
  1791.                 jp (iy)
  1792. WriteLitE1:     ld (hl),#E1
  1793.                 jp (iy)
  1794. WriteLitE2:     ld (hl),#E2
  1795.                 jp (iy)
  1796. WriteLitE3:     ld (hl),#E3
  1797.                 jp (iy)
  1798. WriteLitE4:     ld (hl),#E4
  1799.                 jp (iy)
  1800. WriteLitE5:     ld (hl),#E5
  1801.                 jp (iy)
  1802. WriteLitE6:     ld (hl),#E6
  1803.                 jp (iy)
  1804. WriteLitE7:     ld (hl),#E7
  1805.                 jp (iy)
  1806. WriteLitE8:     ld (hl),#E8
  1807.                 jp (iy)
  1808. WriteLitE9:     ld (hl),#E9
  1809.                 jp (iy)
  1810. WriteLitEA:     ld (hl),#EA
  1811.                 jp (iy)
  1812. WriteLitEB:     ld (hl),#EB
  1813.                 jp (iy)
  1814. WriteLitEC:     ld (hl),#EC
  1815.                 jp (iy)
  1816. WriteLitED:     ld (hl),#ED
  1817.                 jp (iy)
  1818. WriteLitEE:     ld (hl),#EE
  1819.                 jp (iy)
  1820. WriteLitEF:     ld (hl),#EF
  1821.                 jp (iy)
  1822. WriteLitF0:     ld (hl),#F0
  1823.                 jp (iy)
  1824. WriteLitF1:     ld (hl),#F1
  1825.                 jp (iy)
  1826. WriteLitF2:     ld (hl),#F2
  1827.                 jp (iy)
  1828. WriteLitF3:     ld (hl),#F3
  1829.                 jp (iy)
  1830. WriteLitF4:     ld (hl),#F4
  1831.                 jp (iy)
  1832. WriteLitF5:     ld (hl),#F5
  1833.                 jp (iy)
  1834. WriteLitF6:     ld (hl),#F6
  1835.                 jp (iy)
  1836. WriteLitF7:     ld (hl),#F7
  1837.                 jp (iy)
  1838. WriteLitF8:     ld (hl),#F8
  1839.                 jp (iy)
  1840. WriteLitF9:     ld (hl),#F9
  1841.                 jp (iy)
  1842. WriteLitFA:     ld (hl),#FA
  1843.                 jp (iy)
  1844. WriteLitFB:     ld (hl),#FB
  1845.                 jp (iy)
  1846. WriteLitFC:     ld (hl),#FC
  1847.                 jp (iy)
  1848. WriteLitFD:     ld (hl),#FD
  1849.                 jp (iy)
  1850. WriteLitFE:     ld (hl),#FE
  1851.                 jp (iy)
  1852. WriteLitFF:     ld (hl),#FF
  1853.                 jp (iy)
  1854.  
  1855. WriteLitLen:    equ WriteLit02 - WriteLit01
  1856.  
  1857.  
  1858. ; Literal/length alphabet symbol 256
  1859. EndBlock:       ret     ; done inflating this block
  1860. EndBlockLen:    equ $ - EndBlock
  1861.  
  1862.  
  1863. ; Literal/length alphabet symbols 257-285
  1864. CopyLen0:       ld ix,Copy_AndNext3
  1865.                 jp DistanceTree
  1866. CopyLen0Len:    equ $ - CopyLen0
  1867.  
  1868. CopyLen1:       ld ix,Copy_AndNext4
  1869.                 jp DistanceTree
  1870. CopyLen1Len:    equ $ - CopyLen1
  1871.  
  1872. CopyLen2:       ld ix,Copy_AndNext5
  1873.                 jp DistanceTree
  1874. CopyLen2Len:    equ $ - CopyLen2
  1875.  
  1876. CopyLen3:       ld ix,Copy_AndNext6
  1877.                 jp DistanceTree
  1878. CopyLen3Len:    equ $ - CopyLen3
  1879.  
  1880. CopyLen4:       ld ix,Copy_AndNext7
  1881.                 jp DistanceTree
  1882. CopyLen4Len:    equ $ - CopyLen4
  1883.  
  1884. CopyLen5:       ld ix,Copy_AndNext8
  1885.                 jp DistanceTree
  1886. CopyLen5Len:    equ $ - CopyLen5
  1887.  
  1888. CopyLen6:       ld ix,Copy_AndNext9
  1889.                 jp DistanceTree
  1890. CopyLen6Len:    equ $ - CopyLen6
  1891.  
  1892. CopyLen7:       ld ix,Copy_AndNext10
  1893.                 jp DistanceTree
  1894. CopyLen7Len:    equ $ - CopyLen7
  1895.  
  1896. CopyLen8:       ReadBitInlineA
  1897.                 ld a,0
  1898.                 adc a,11        ; 11..12
  1899.                 jp CopySetLength
  1900. CopyLen8Len:    equ $ - CopyLen8
  1901.  
  1902. CopyLen9:       ReadBitInlineA
  1903.                 ld a,0
  1904.                 adc a,13        ; 13..14
  1905.                 jp CopySetLength
  1906. CopyLen9Len:    equ $ - CopyLen9
  1907.  
  1908. CopyLen10:      ReadBitInlineA
  1909.                 ld a,0
  1910.                 adc a,15        ; 15..16
  1911.                 jp CopySetLength
  1912. CopyLen10Len:   equ $ - CopyLen10
  1913.  
  1914. CopyLen11:      ReadBitInlineA
  1915.                 ld a,0
  1916.                 adc a,17        ; 17..18
  1917.                 jp CopySetLength
  1918. CopyLen11Len:   equ $ - CopyLen11
  1919.  
  1920. CopyLen12:      call Read2Bits
  1921.                 add a,19        ; 19..22
  1922.                 jp CopySetLength
  1923. CopyLen12Len:   equ $ - CopyLen12
  1924.  
  1925. CopyLen13:      call Read2Bits
  1926.                 add a,23        ; 23..26
  1927.                 jp CopySetLength
  1928. CopyLen13Len:   equ $ - CopyLen13
  1929.  
  1930. CopyLen14:      call Read2Bits
  1931.                 add a,27        ; 27..30
  1932.                 jp CopySetLength
  1933. CopyLen14Len:   equ $ - CopyLen14
  1934.  
  1935. CopyLen15:      call Read2Bits
  1936.                 add a,31        ; 31..34
  1937.                 jp CopySetLength
  1938. CopyLen15Len:   equ $ - CopyLen15
  1939.  
  1940. CopyLen16:      call Read3Bits
  1941.                 add a,35        ; 35..42
  1942.                 jp CopySetLength
  1943. CopyLen16Len:   equ $ - CopyLen16
  1944.  
  1945. CopyLen17:      call Read3Bits
  1946.                 add a,43        ; 43..50
  1947.                 jp CopySetLength
  1948. CopyLen17Len:   equ $ - CopyLen17
  1949.  
  1950. CopyLen18:      call Read3Bits
  1951.                 add a,51        ; 51..58
  1952.                 jp CopySetLength
  1953. CopyLen18Len:   equ $ - CopyLen18
  1954.  
  1955. CopyLen19:      call Read3Bits
  1956.                 add a,59        ; 59..66
  1957.                 jp CopySetLength
  1958. CopyLen19Len:   equ $ - CopyLen19
  1959.  
  1960. CopyLen20:      call Read4Bits
  1961.                 add a,67        ; 67..82
  1962.                 jp CopySetLength
  1963. CopyLen20Len:   equ $ - CopyLen20
  1964.  
  1965. CopyLen21:      call Read4Bits
  1966.                 add a,83        ; 83..98
  1967.                 jp CopySetLength
  1968. CopyLen21Len:   equ $ - CopyLen21
  1969.  
  1970. CopyLen22:      call Read4Bits
  1971.                 add a,99        ; 99..114
  1972.                 jp CopySetLength
  1973. CopyLen22Len:   equ $ - CopyLen22
  1974.  
  1975. CopyLen23:      call Read4Bits
  1976.                 add a,115       ; 115..130
  1977.                 jp CopySetLength
  1978. CopyLen23Len:   equ $ - CopyLen23
  1979.  
  1980. CopyLen24:      call Read5Bits
  1981.                 add a,131       ; 131..162
  1982.                 jp CopySetLength
  1983. CopyLen24Len:   equ $ - CopyLen24
  1984.  
  1985. CopyLen25:      call Read5Bits
  1986.                 add a,163       ; 163..194
  1987.                 jp CopySetLength
  1988. CopyLen25Len:   equ $ - CopyLen25
  1989.  
  1990. CopyLen26:      call Read5Bits
  1991.                 add a,195       ; 195..226
  1992.                 jp CopySetLength
  1993. CopyLen26Len:   equ $ - CopyLen26
  1994.  
  1995. CopyLen27:      call Read5Bits
  1996.                 add a,227       ; 227..257
  1997.                 exx
  1998.                 ld c,a
  1999.                 ld b,0
  2000.                 jr nc,CopySetLength0
  2001.                 inc b
  2002. CopySetLength0  ld ix,Copy_AndNext
  2003.                 exx
  2004.                 jp DistanceTree
  2005. CopyLen27Len:   equ $ - CopyLen27
  2006.  
  2007. CopyLen28:      ld ix,Copy_AndNext258
  2008.                 jp DistanceTree
  2009. CopyLen28Len:   equ $ - CopyLen28
  2010.  
  2011. ; a = length
  2012. ;CopySetLength:
  2013. CopySL:         exx
  2014.                 ld c,a
  2015.                 ld b,0
  2016.                 ld ix,Copy_AndNext
  2017.                 exx
  2018.                 ;jp DistanceTree        ; this routine is copied in front of DistanceTree
  2019. CopySLLen:      equ $ - CopySL
  2020.  
  2021.  
  2022. ; -- Symbol routines used by the 'distance' Huffman tree
  2023.  
  2024. DistSymbols:    db CopyDist0Len
  2025.                 dw CopyDist0
  2026.                 db CopyDist1Len
  2027.                 dw CopyDist1
  2028.                 db CopyDist2Len
  2029.                 dw CopyDist2
  2030.                 db CopyDist3Len
  2031.                 dw CopyDist3
  2032.                 db CopyDist4Len
  2033.                 dw CopyDist4
  2034.                 db CopyDist5Len
  2035.                 dw CopyDist5
  2036.                 db CopyDist6Len
  2037.                 dw CopyDist6
  2038.                 db CopyDist7Len
  2039.                 dw CopyDist7
  2040.                 db CopyDist8Len
  2041.                 dw CopyDist8
  2042.                 db CopyDist9Len
  2043.                 dw CopyDist9
  2044.                 db CopyDist10Len
  2045.                 dw CopyDist10
  2046.                 db CopyDist11Len
  2047.                 dw CopyDist11
  2048.                 db CopyDist12Len
  2049.                 dw CopyDist12
  2050.                 db CopyDist13Len
  2051.                 dw CopyDist13
  2052.                 db CopyDist14Len
  2053.                 dw CopyDist14
  2054.                 db CopyDist15Len
  2055.                 dw CopyDist15
  2056.                 db CopyDist16Len
  2057.                 dw CopyDist16
  2058.                 db CopyDist17Len
  2059.                 dw CopyDist17
  2060.                 db CopyDist18Len
  2061.                 dw CopyDist18
  2062.                 db CopyDist19Len
  2063.                 dw CopyDist19
  2064.                 db CopyDist20Len
  2065.                 dw CopyDist20
  2066.                 db CopyDist21Len
  2067.                 dw CopyDist21
  2068.                 db CopyDist22Len
  2069.                 dw CopyDist22
  2070.                 db CopyDist23Len
  2071.                 dw CopyDist23
  2072.                 db CopyDist24Len
  2073.                 dw CopyDist24
  2074.                 db CopyDist25Len
  2075.                 dw CopyDist25
  2076.                 db CopyDist26Len
  2077.                 dw CopyDist26
  2078.                 db CopyDist27Len
  2079.                 dw CopyDist27
  2080.                 db CopyDist28Len
  2081.                 dw CopyDist28
  2082.                 db CopyDist29Len
  2083.                 dw CopyDist29
  2084.                 db ThrowInlineLen
  2085.                 dw ThrowInline
  2086.                 db ThrowInlineLen
  2087.                 dw ThrowInline
  2088.  
  2089. ; For all of these routines, the calling convention is like this:
  2090. ; bc = length of the to-be-copied block
  2091. ; 'c = bit reader state
  2092. ; 'de = InputBufPos
  2093. ; 'hl = OutputBufPos
  2094. ; ix = copy-routine (Copy_AndNext or a specialized version Copy_AndNext<nn>)
  2095. ; iy = Write_AndNext
  2096.  
  2097. ; Distance alphabet symbols 0-29
  2098. CopyDist0:      push hl
  2099.                 exx
  2100.                 ld hl,-1
  2101.                 jp (ix)
  2102. CopyDist0Len:   equ $ - CopyDist0
  2103.  
  2104. CopyDist1:      push hl
  2105.                 exx
  2106.                 ld hl,-2
  2107.                 jp (ix)
  2108. CopyDist1Len:   equ $ - CopyDist1
  2109.  
  2110. CopyDist2:      push hl
  2111.                 exx
  2112.                 ld hl,-3
  2113.                 jp (ix)
  2114. CopyDist2Len:   equ $ - CopyDist2
  2115.  
  2116. CopyDist3:      push hl
  2117.                 exx
  2118.                 ld hl,-4
  2119.                 jp (ix)
  2120. CopyDist3Len:   equ $ - CopyDist3
  2121.  
  2122. CopyDist4:      ReadBitInlineA  ; set c-flag
  2123.                 sbc a,a         ; carry ? -1 :  0
  2124.                 sub 5           ; carry ? -6 : -5
  2125.                 push hl
  2126.                 exx
  2127.                 ld l,a
  2128.                 ld h,#ff
  2129.                 jp (ix)
  2130. CopyDist4Len:   equ $ - CopyDist4
  2131.  
  2132. CopyDist5:      ReadBitInlineA
  2133.                 sbc a,a
  2134.                 sub 7   ; -7..-8
  2135.                 push hl
  2136.                 exx
  2137.                 ld l,a
  2138.                 ld h,#ff
  2139.                 jp (ix)
  2140. CopyDist5Len:   equ $ - CopyDist5
  2141.  
  2142. CopyDist6:      call Read2Bits
  2143.                 xor -9  ; -9..-12
  2144.                 push hl
  2145.                 exx
  2146.                 ld l,a
  2147.                 ld h,#ff
  2148.                 jp (ix)
  2149. CopyDist6Len:   equ $ - CopyDist6
  2150.  
  2151. CopyDist7:      call Read2Bits
  2152.                 xor -13 ; -13..-16
  2153.                 push hl
  2154.                 exx
  2155.                 ld l,a
  2156.                 ld h,#ff
  2157.                 jp (ix)
  2158. CopyDist7Len:   equ $ - CopyDist7
  2159.  
  2160. CopyDist8:      call Read3Bits
  2161.                 xor -17 ; -17..-24
  2162.                 push hl
  2163.                 exx
  2164.                 ld l,a
  2165.                 ld h,#ff
  2166.                 jp (ix)
  2167. CopyDist8Len:   equ $ - CopyDist8
  2168.  
  2169. CopyDist9:      call Read3Bits
  2170.                 xor -25 ; -25..-32
  2171.                 push hl
  2172.                 exx
  2173.                 ld l,a
  2174.                 ld h,#ff
  2175.                 jp (ix)
  2176. CopyDist9Len:   equ $ - CopyDist9
  2177.  
  2178. CopyDist10:     call Read4Bits
  2179.                 xor -33 ; -33..-48
  2180.                 push hl
  2181.                 exx
  2182.                 ld l,a
  2183.                 ld h,#ff
  2184.                 jp (ix)
  2185. CopyDist10Len:  equ $ - CopyDist10
  2186.  
  2187. CopyDist11:     call Read4Bits
  2188.                 xor -49 ; -49..-64
  2189.                 push hl
  2190.                 exx
  2191.                 ld l,a
  2192.                 ld h,#ff
  2193.                 jp (ix)
  2194. CopyDist11Len:  equ $ - CopyDist11
  2195.  
  2196. CopyDist12:     call Read5Bits
  2197.                 xor -65 ; -64..-96
  2198.                 push hl
  2199.                 exx
  2200.                 ld l,a
  2201.                 ld h,#ff
  2202.                 jp (ix)
  2203. CopyDist12Len:  equ $ - CopyDist12
  2204.  
  2205. CopyDist13:     call Read5Bits
  2206.                 xor -97 ; -97..-128
  2207.                 push hl
  2208.                 exx
  2209.                 ld l,a
  2210.                 ld h,#ff
  2211.                 jp (ix)
  2212. CopyDist13Len:  equ $ - CopyDist13
  2213.  
  2214. CopyDist14:     call Read6Bits
  2215.                 xor -129        ; -129..-192
  2216.                 push hl
  2217.                 exx
  2218.                 ld l,a
  2219.                 ld h,#ff
  2220.                 jp (ix)
  2221. CopyDist14Len:  equ $ - CopyDist14
  2222.  
  2223. CopyDist15:     call Read6Bits
  2224.                 xor -193        ; -193..-256
  2225.                 push hl
  2226.                 exx
  2227.                 ld l,a
  2228.                 ld h,#ff
  2229.                 jp (ix)
  2230. CopyDist15Len:  equ $ - CopyDist15
  2231.  
  2232. CopyDist16:     call Read7Bits
  2233.                 push hl
  2234.                 exx
  2235.                 cpl
  2236.                 ld l,a
  2237.                 ld h,-2 ; -257..-384
  2238.                 jp (ix)
  2239. CopyDist16Len:  equ $ - CopyDist16
  2240.  
  2241. CopyDist17:     call Read7Bits
  2242.                 push hl
  2243.                 exx
  2244.                 xor -385 & #FF
  2245.                 ld l,a
  2246.                 ld h,-2 ; -385..-512
  2247.                 jp (ix)
  2248. CopyDist17Len:  equ $ - CopyDist17
  2249.  
  2250. CopyDist18:     call Read8Bits
  2251.                 push hl
  2252.                 exx
  2253.                 cpl
  2254.                 ld l,a
  2255.                 ld h,-3 ; -513..-768
  2256.                 jp (ix)
  2257. CopyDist18Len:  equ $ - CopyDist18
  2258.  
  2259. CopyDist19:     call Read8Bits
  2260.                 push hl
  2261.                 exx
  2262.                 cpl
  2263.                 ld l,a
  2264.                 ld h,-4 ; -769..-1024
  2265.                 jp (ix)
  2266. CopyDist19Len:  equ $ - CopyDist19
  2267.  
  2268. CopyDist20:     call Read8Bits
  2269.                 ex af,af'
  2270.                 ReadBitInlineA
  2271.                 sbc a,a
  2272.                 sub 5           ; -5/-6 -> -1025..-1536
  2273.                 push hl
  2274.                 exx
  2275.                 ld h,a
  2276.                 ex af,af'
  2277.                 cpl
  2278.                 ld l,a
  2279.                 jp (ix)
  2280. CopyDist20Len:  equ $ - CopyDist20
  2281.  
  2282. CopyDist21:     call Read8Bits
  2283.                 ex af,af'
  2284.                 ReadBitInlineA
  2285.                 sbc a,a
  2286.                 sub 7           ; -7/-8 -> -1537..-2048
  2287.                 push hl
  2288.                 exx
  2289.                 ld h,a
  2290.                 ex af,af'
  2291.                 cpl
  2292.                 ld l,a
  2293.                 jp (ix)
  2294. CopyDist21Len:  equ $ - CopyDist21
  2295.  
  2296. CopyDist22:     call Read8Bits
  2297.                 ex af,af'
  2298.                 call Read2Bits
  2299.                 xor -9  ; -2049..-3072
  2300.                 push hl
  2301.                 exx
  2302.                 ld h,a
  2303.                 ex af,af'
  2304.                 cpl
  2305.                 ld l,a
  2306.                 jp (ix)
  2307. CopyDist22Len:  equ $ - CopyDist22
  2308.  
  2309. CopyDist23:     call Read8Bits
  2310.                 ex af,af'
  2311.                 call Read2Bits
  2312.                 xor -13 ; -3073..-4096
  2313.                 push hl
  2314.                 exx
  2315.                 ld h,a
  2316.                 ex af,af'
  2317.                 cpl
  2318.                 ld l,a
  2319.                 jp (ix)
  2320. CopyDist23Len:  equ $ - CopyDist23
  2321.  
  2322. CopyDist24:     call Read8Bits
  2323.                 ex af,af'
  2324.                 call Read3Bits
  2325.                 xor -17 ; -4097..-6144
  2326.                 push hl
  2327.                 exx
  2328.                 ld h,a
  2329.                 ex af,af'
  2330.                 cpl
  2331.                 ld l,a
  2332.                 jp (ix)
  2333. CopyDist24Len:  equ $ - CopyDist24
  2334.  
  2335. CopyDist25:     call Read8Bits
  2336.                 ex af,af'
  2337.                 call Read3Bits
  2338.                 xor -25 ; -6145..-8192
  2339.                 push hl
  2340.                 exx
  2341.                 ld h,a
  2342.                 ex af,af'
  2343.                 cpl
  2344.                 ld l,a
  2345.                 jp (ix)
  2346. CopyDist25Len:  equ $ - CopyDist25
  2347.  
  2348. CopyDist26:     call Read8Bits
  2349.                 ex af,af'
  2350.                 call Read4Bits
  2351.                 xor -33 ; -8193..-12288
  2352.                 push hl
  2353.                 exx
  2354.                 ld h,a
  2355.                 ex af,af'
  2356.                 cpl
  2357.                 ld l,a
  2358.                 jp (ix)
  2359. CopyDist26Len:  equ $ - CopyDist26
  2360.  
  2361. CopyDist27:     call Read8Bits
  2362.                 ex af,af'
  2363.                 call Read4Bits
  2364.                 xor -49 ; -12289..-16364
  2365.                 push hl
  2366.                 exx
  2367.                 ld h,a
  2368.                 ex af,af'
  2369.                 cpl
  2370.                 ld l,a
  2371.                 jp (ix)
  2372. CopyDist27Len:  equ $ - CopyDist27
  2373.  
  2374. CopyDist28:     call Read8Bits
  2375.                 ex af,af'
  2376.                 call Read5Bits
  2377.                 xor -65 ; -16385..-24576
  2378.                 push hl
  2379.                 exx
  2380.                 ld h,a
  2381.                 ex af,af'
  2382.                 cpl
  2383.                 ld l,a
  2384.                 jp (ix)
  2385. CopyDist28Len:  equ $ - CopyDist28
  2386.  
  2387. CopyDist29:     call Read8Bits
  2388.                 ex af,af'
  2389.                 call Read5Bits
  2390.                 xor -97 ; -24577..-32768
  2391.                 push hl
  2392.                 exx
  2393.                 ld h,a
  2394.                 ex af,af'
  2395.                 cpl
  2396.                 ld l,a
  2397.                 jp (ix)
  2398. CopyDist29Len:  equ $ - CopyDist29
  2399.  
  2400.  
  2401. ; -- Routines to read bits and bytes from the GZ file --
  2402.  
  2403. ; Read a byte from the input
  2404. ; Requires: regsiter DE contains 'InputBufPos' (in/out)
  2405. ; a <- value
  2406. ; Unchanged: bc, hl, ix, iy
  2407. ; Note: Before the fast-path was:
  2408. ;          ld a,(de)
  2409. ;          inc e
  2410. ;          ret nz
  2411. ;   This is faster than the current implementation. Though in the places where
  2412. ;   performance matters ReadByte is (partially) inlined, and then this
  2413. ;   alternative is a tiny bit faster. It also results in overall simpler code.
  2414. ReadByte:       inc e
  2415.                 call z,ReadByte2        ; crosses 256-byte boundary?
  2416.                 ld a,(de)
  2417.                 ret
  2418.  
  2419. ReadByte2:      inc d
  2420.                 ld a,d
  2421.                 cp InputBufferEnd / 256
  2422.                 ret nz
  2423.                 push bc
  2424.                 push hl
  2425.                 ld de,InputBuffer
  2426.                 ld hl,InputBufSize
  2427.                 call GzipReadInputBuffer
  2428.                 pop hl
  2429.                 pop bc
  2430.                 ld de,InputBuffer
  2431.                 ret
  2432.  
  2433.  
  2434. ; For speed reasons all the ReadXX functions below require register C and DE
  2435. ; to contains certain values (and those functions also update C, DE). This
  2436. ; function sets up the correct values in C and DE.
  2437. PrepareRead:    ld a,(InputBits)
  2438.                 ld c,a
  2439.                 ld de,(InputBufPos)
  2440.                 ret
  2441.  
  2442. ; After you're done calling the ReadXX functions and you want to use regsiters
  2443. ; C and DE for other stuff again. They should be written back to memory.
  2444. FinishRead:     ld (InputBufPos),de
  2445.                 ld a,c
  2446.                 ld (InputBits),a
  2447.                 ret
  2448.  
  2449.  
  2450. ; 'outline' part of ReadBitInlineA
  2451. ReadBitA:       ;call ReadByte ; partially inline this call
  2452.                 inc e
  2453.                 jr z,ReadBitA2
  2454.                 ld a,(de)
  2455.                 scf     ; set sentinel bit
  2456.                 rra
  2457.                 ld c,a
  2458.                 ret
  2459. ReadBitA2:      call ReadByte2
  2460.                 ld a,(de)
  2461.                 scf     ; set sentinel bit
  2462.                 rra
  2463.                 ld c,a
  2464.                 ret
  2465.  
  2466. ; Similar to ReadBitInlineA, but changes regsiter B instead of A (is a tiny bit
  2467. ; slower because of that).
  2468. ReadBitInlineB: MACRO
  2469.                 srl c
  2470.                 call z,ReadBitB ; if sentinel bit is shifted out
  2471.                 ENDM
  2472.  
  2473. ; 'outline' part of ReadBitInlineB
  2474. ReadBitB:       ld b,a
  2475.                 ;call ReadByte ; partially inline this call
  2476.                 inc e
  2477.                 jr z,ReadBitB2
  2478.                 ld a,(de)
  2479.                 scf     ; set sentinel bit
  2480.                 rra
  2481.                 ld c,a
  2482.                 ld a,b
  2483.                 ret
  2484. ReadBitB2       call ReadByte2
  2485.                 ld a,(de)
  2486.                 scf     ; set sentinel bit
  2487.                 rra
  2488.                 ld c,a
  2489.                 ld a,b
  2490.                 ret
  2491.  
  2492. ; Routines to read {2..8} bits from the input.
  2493. ; Requires: PrepareRead has been called (registers C and DE are reserved)
  2494. ; a <- value
  2495. ; Modifies: b
  2496. ; Unchanged: hl, ix, iy
  2497. Read2Bits:      xor a
  2498.                 ReadBitInlineB
  2499.                 rra
  2500.                 ReadBitInlineB
  2501.                 rla
  2502.                 rla
  2503.                 ret
  2504.  
  2505. Read3Bits:      xor a
  2506.                 ReadBitInlineB
  2507.                 rra
  2508.                 ReadBitInlineB
  2509.                 rra
  2510.                 ReadBitInlineB
  2511.                 rla
  2512.                 rla
  2513.                 rla
  2514.                 ret
  2515.  
  2516. Read4Bits:      xor a
  2517.                 ReadBitInlineB
  2518.                 rra
  2519.                 ReadBitInlineB
  2520.                 rra
  2521.                 ReadBitInlineB
  2522.                 rra
  2523.                 ReadBitInlineB
  2524.                 rla
  2525.                 rla
  2526.                 rla
  2527.                 rla
  2528.                 ret
  2529.  
  2530. Read5Bits:      xor a
  2531.                 ReadBitInlineB
  2532.                 rra
  2533.                 ReadBitInlineB
  2534.                 rra
  2535.                 ReadBitInlineB
  2536.                 rra
  2537.                 ReadBitInlineB
  2538.                 rra
  2539.                 ReadBitInlineB
  2540.                 rra
  2541.                 rra
  2542.                 rra
  2543.                 rra
  2544.                 ret
  2545.  
  2546. Read6Bits:      xor a
  2547.                 ReadBitInlineB
  2548.                 rra
  2549.                 ReadBitInlineB
  2550.                 rra
  2551.                 ReadBitInlineB
  2552.                 rra
  2553.                 ReadBitInlineB
  2554.                 rra
  2555.                 ReadBitInlineB
  2556.                 rra
  2557.                 ReadBitInlineB
  2558.                 rra
  2559.                 rra
  2560.                 rra
  2561.                 ret
  2562.  
  2563. Read7Bits:      xor a
  2564.                 ReadBitInlineB
  2565.                 rra
  2566.                 ReadBitInlineB
  2567.                 rra
  2568.                 ReadBitInlineB
  2569.                 rra
  2570.                 ReadBitInlineB
  2571.                 rra
  2572.                 ReadBitInlineB
  2573.                 rra
  2574.                 ReadBitInlineB
  2575.                 rra
  2576.                 ReadBitInlineB
  2577.                 rra
  2578.                 rra
  2579.                 ret
  2580.  
  2581. Read8Bits:      ReadBitInlineB
  2582.                 rra
  2583.                 ReadBitInlineB
  2584.                 rra
  2585.                 ReadBitInlineB
  2586.                 rra
  2587.                 ReadBitInlineB
  2588.                 rra
  2589.                 ReadBitInlineB
  2590.                 rra
  2591.                 ReadBitInlineB
  2592.                 rra
  2593.                 ReadBitInlineB
  2594.                 rra
  2595.                 ReadBitInlineB
  2596.                 rra
  2597.                 ret
  2598.  
  2599.  
  2600. ; -- Routines to write to the output file --
  2601. ; --   they also maintain a sliding window to the last 32kB
  2602. ; --   and they calculate a CRC32 value of the data
  2603.  
  2604. ; Write a byte to the output.
  2605. ; This routine is very tightly coupled to the huffman decode routines. In fact
  2606. ; it's not really a function at all. Instead of returning it jumps to
  2607. ; 'LiteralTree'. And because of this, this function should not be called, but
  2608. ; jumped to.
  2609. ;
  2610. ; a = value
  2611. ; hl = OutputBufPos (in/out)
  2612. ; Modifies: a
  2613. Write_AndNext:  ;ld (hl),a      ; write is already done
  2614.                 inc l
  2615.                 jp nz,LiteralTree       ; crosses 256-byte boundary?
  2616.  
  2617.                 inc h
  2618.                 ld a,h
  2619.                 cp OutputBufEnd / 256
  2620.                 jp nz,LiteralTree       ; end of buffer reached?
  2621.  
  2622.                 call FinishBlock2
  2623.                 ; hl = OutputBufPos = OutputBuffer
  2624.                 jp LiteralTree
  2625.  
  2626. ;;; TODO
  2627. Copy_AndNext3:  pop de          ; de = destination = OutputBufPos
  2628.                 add hl,de       ; hl = source
  2629.                 ld a,h
  2630.                 sub OutputBuffer / 256
  2631.                 sub OutputBufSize / 256
  2632.                 jr nc,CopyWrap3
  2633. WrapContinue3   ld a,d
  2634.                 cp (OutputBufEnd / 256) - 1
  2635.                 jr nc,CopySlow3
  2636.                 ldi
  2637.                 ldi
  2638.                 ldi
  2639.                 push de
  2640.                 ; and next
  2641.                 exx
  2642.                 pop hl  ; updated OutputBufPos
  2643.                 jp LiteralTree
  2644.  
  2645. CopyWrap3:      add a,OutputBuffer / 256
  2646.                 ld h,a
  2647.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2648.                 jr c,WrapContinue3      ; does the source have a 256 byte margin without wrapping?
  2649. CopySlow3       ld bc,3
  2650.                 jp CopySlow
  2651.  
  2652. ;;; TODO
  2653. Copy_AndNext4:  pop de          ; de = destination = OutputBufPos
  2654.                 add hl,de       ; hl = source
  2655.                 ld a,h
  2656.                 sub OutputBuffer / 256
  2657.                 sub OutputBufSize / 256
  2658.                 jr nc,CopyWrap4
  2659. WrapContinue4   ld a,d
  2660.                 cp (OutputBufEnd / 256) - 1
  2661.                 jr nc,CopySlow4
  2662.                 ldi
  2663.                 ldi
  2664.                 ldi
  2665.                 ldi
  2666.                 push de
  2667.                 ; and next
  2668.                 exx
  2669.                 pop hl  ; updated OutputBufPos
  2670.                 jp LiteralTree
  2671.  
  2672. CopyWrap4:      add a,OutputBuffer / 256
  2673.                 ld h,a
  2674.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2675.                 jr c,WrapContinue4      ; does the source have a 256 byte margin without wrapping?
  2676. CopySlow4       ld bc,4
  2677.                 jp CopySlow
  2678.  
  2679. ;;; TODO
  2680. Copy_AndNext5:  pop de          ; de = destination = OutputBufPos
  2681.                 add hl,de       ; hl = source
  2682.                 ld a,h
  2683.                 sub OutputBuffer / 256
  2684.                 sub OutputBufSize / 256
  2685.                 jr nc,CopyWrap5
  2686. WrapContinue5   ld a,d
  2687.                 cp (OutputBufEnd / 256) - 1
  2688.                 jr nc,CopySlow5
  2689.                 ldi
  2690.                 ldi
  2691.                 ldi
  2692.                 ldi
  2693.                 ldi
  2694.                 push de
  2695.                 ; and next
  2696.                 exx
  2697.                 pop hl  ; updated OutputBufPos
  2698.                 jp LiteralTree
  2699.  
  2700. CopyWrap5:      add a,OutputBuffer / 256
  2701.                 ld h,a
  2702.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2703.                 jr c,WrapContinue5      ; does the source have a 256 byte margin without wrapping?
  2704. CopySlow5       ld bc,5
  2705.                 jp CopySlow
  2706.  
  2707. ;;; TODO
  2708. Copy_AndNext6:  pop de          ; de = destination = OutputBufPos
  2709.                 add hl,de       ; hl = source
  2710.                 ld a,h
  2711.                 sub OutputBuffer / 256
  2712.                 sub OutputBufSize / 256
  2713.                 jr nc,CopyWrap6
  2714. WrapContinue6   ld a,d
  2715.                 cp (OutputBufEnd / 256) - 1
  2716.                 jr nc,CopySlow6
  2717.                 ldi
  2718.                 ldi
  2719.                 ldi
  2720.                 ldi
  2721.                 ldi
  2722.                 ldi
  2723.                 push de
  2724.                 ; and next
  2725.                 exx
  2726.                 pop hl  ; updated OutputBufPos
  2727.                 jp LiteralTree
  2728.  
  2729. CopyWrap6:      add a,OutputBuffer / 256
  2730.                 ld h,a
  2731.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2732.                 jr c,WrapContinue6      ; does the source have a 256 byte margin without wrapping?
  2733. CopySlow6       ld bc,6
  2734.                 jp CopySlow
  2735.  
  2736. ;;; TODO
  2737. Copy_AndNext7:  pop de          ; de = destination = OutputBufPos
  2738.                 add hl,de       ; hl = source
  2739.                 ld a,h
  2740.                 sub OutputBuffer / 256
  2741.                 sub OutputBufSize / 256
  2742.                 jr nc,CopyWrap7
  2743. WrapContinue7   ld a,d
  2744.                 cp (OutputBufEnd / 256) - 1
  2745.                 jr nc,CopySlow7
  2746.                 ldi
  2747.                 ldi
  2748.                 ldi
  2749.                 ldi
  2750.                 ldi
  2751.                 ldi
  2752.                 ldi
  2753.                 push de
  2754.                 ; and next
  2755.                 exx
  2756.                 pop hl  ; updated OutputBufPos
  2757.                 jp LiteralTree
  2758.  
  2759. CopyWrap7:      add a,OutputBuffer / 256
  2760.                 ld h,a
  2761.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2762.                 jr c,WrapContinue7      ; does the source have a 256 byte margin without wrapping?
  2763. CopySlow7       ld bc,7
  2764.                 jp CopySlow
  2765.  
  2766. ;;; TODO
  2767. Copy_AndNext8:  pop de          ; de = destination = OutputBufPos
  2768.                 add hl,de       ; hl = source
  2769.                 ld a,h
  2770.                 sub OutputBuffer / 256
  2771.                 sub OutputBufSize / 256
  2772.                 jr nc,CopyWrap8
  2773. WrapContinue8   ld a,d
  2774.                 cp (OutputBufEnd / 256) - 1
  2775.                 jr nc,CopySlow8
  2776.                 ldi
  2777.                 ldi
  2778.                 ldi
  2779.                 ldi
  2780.                 ldi
  2781.                 ldi
  2782.                 ldi
  2783.                 ldi
  2784.                 push de
  2785.                 ; and next
  2786.                 exx
  2787.                 pop hl  ; updated OutputBufPos
  2788.                 jp LiteralTree
  2789.  
  2790. CopyWrap8:      add a,OutputBuffer / 256
  2791.                 ld h,a
  2792.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2793.                 jr c,WrapContinue8      ; does the source have a 256 byte margin without wrapping?
  2794. CopySlow8       ld bc,8
  2795.                 jp CopySlow
  2796.  
  2797. ;;; TODO
  2798. Copy_AndNext9:  pop de          ; de = destination = OutputBufPos
  2799.                 add hl,de       ; hl = source
  2800.                 ld a,h
  2801.                 sub OutputBuffer / 256
  2802.                 sub OutputBufSize / 256
  2803.                 jr nc,CopyWrap9
  2804. WrapContinue9   ld a,d
  2805.                 cp (OutputBufEnd / 256) - 1
  2806.                 jr nc,CopySlow9
  2807.                 ldi
  2808.                 ldi
  2809.                 ldi
  2810.                 ldi
  2811.                 ldi
  2812.                 ldi
  2813.                 ldi
  2814.                 ldi
  2815.                 ldi
  2816.                 push de
  2817.                 ; and next
  2818.                 exx
  2819.                 pop hl  ; updated OutputBufPos
  2820.                 jp LiteralTree
  2821.  
  2822. CopyWrap9:      add a,OutputBuffer / 256
  2823.                 ld h,a
  2824.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2825.                 jr c,WrapContinue9      ; does the source have a 256 byte margin without wrapping?
  2826. CopySlow9       ld bc,9
  2827.                 jp CopySlow
  2828.  
  2829. ;;; TODO
  2830. Copy_AndNext10: pop de          ; de = destination = OutputBufPos
  2831.                 add hl,de       ; hl = source
  2832.                 ld a,h
  2833.                 sub OutputBuffer / 256
  2834.                 sub OutputBufSize / 256
  2835.                 jr nc,CopyWrap10
  2836. WrapContinue10  ld a,d
  2837.                 cp (OutputBufEnd / 256) - 1
  2838.                 jr nc,CopySlow10
  2839.                 ldi
  2840.                 ldi
  2841.                 ldi
  2842.                 ldi
  2843.                 ldi
  2844.                 ldi
  2845.                 ldi
  2846.                 ldi
  2847.                 ldi
  2848.                 ldi
  2849.                 push de
  2850.                 ; and next
  2851.                 exx
  2852.                 pop hl  ; updated OutputBufPos
  2853.                 jp LiteralTree
  2854.  
  2855. CopyWrap10:     add a,OutputBuffer / 256
  2856.                 ld h,a
  2857.                 cp (OutputBufEnd / 256) - 1     ; only check source when it wrapped
  2858.                 jr c,WrapContinue10     ; does the source have a 256 byte margin without wrapping?
  2859. CopySlow10      ld bc,10
  2860.                 jr CopySlow
  2861.  
  2862. ;;; TODO
  2863. Copy_AndNext258:ld bc,258
  2864.                 pop de          ; de = destination = OutputBufPos
  2865.                 add hl,de       ; hl = source
  2866.                 ld a,h
  2867.                 sub OutputBuffer / 256
  2868.                 sub OutputBufSize / 256
  2869.                 jr nc,CopyWrap258
  2870. WrapContinue258 ld a,d
  2871.                 cp (OutputBufEnd / 256) - 2
  2872.                 jr nc,CopySlow
  2873.                 ldi
  2874.                 ldi
  2875. Ldi258          ldi
  2876.                 ldi
  2877.                 ldi
  2878.                 ldi
  2879.                 ldi
  2880.                 ldi
  2881.                 ldi
  2882.                 ldi
  2883.                 ldi
  2884.                 ldi
  2885.                 ldi
  2886.                 ldi
  2887.                 ldi
  2888.                 ldi
  2889.                 ldi
  2890.                 ldi
  2891.                 jp pe,Ldi258
  2892.                 push de
  2893.                 ; and next
  2894.                 exx
  2895.                 pop hl  ; updated OutputBufPos
  2896.                 jp LiteralTree
  2897.  
  2898. CopyWrap258:    add a,OutputBuffer / 256
  2899.                 ld h,a
  2900.                 cp (OutputBufEnd / 256) - 2     ; only check source when it wrapped
  2901.                 jr c,WrapContinue258    ; does the source have a 256 byte margin without wrapping?
  2902.                 jr CopySlow
  2903.  
  2904. ; Repeat (copy) a chunk of data that was written before.
  2905. ; Like 'Write_AndNext' above, this routine is very tightly coupled to the
  2906. ; huffman decode routines. It does not return, instead it jumps to LiteralTree.
  2907. ; (top-of-stack) = OutputBufPos
  2908. ; bc = byte count (range 3-258)
  2909. ; hl = -distance
  2910. ; hl <- new OutputBufPos
  2911. ; Modifies: (after exx) af, bc', de', hl'
  2912. Copy_AndNext:   pop de          ; de = destination = OutputBufPos
  2913.                 add hl,de       ; hl = source
  2914.                 ld a,h
  2915.                 jr nc,CopyWrap
  2916.                 cp OutputBuffer / 256
  2917.                 jr c,CopyWrap
  2918.                 ld a,(OutputBufEnd / 256) - 3
  2919. WrapContinue:   cp d    ; does the destination have a 512 byte margin without wrapping?
  2920.                 jr c,CopySlow
  2921.                 ldi
  2922.                 ldi
  2923.                 ldir
  2924.                 push de
  2925.                 ; and next
  2926.                 exx
  2927.                 pop hl  ; updated OutputBufPos
  2928.                 jp LiteralTree
  2929.  
  2930. CopyWrap:       add a,OutputBufSize / 256
  2931.                 ld h,a
  2932.                 ld a,(OutputBufEnd / 256) - 3   ; only check source when it wrapped
  2933.                 cp h    ; does the source have a 512 byte margin without wrapping?
  2934.                 jp nc,WrapContinue
  2935.  
  2936. ; bc = byte count
  2937. ; hl = buffer source
  2938. ; de = buffer destination
  2939. ; Modifies: af, bc, de, hl
  2940. CopySlow:       ld (OutputBufPos),de
  2941.                 ld e,l
  2942.                 ld d,h
  2943.                 add hl,bc
  2944.                 jr c,CopySplit
  2945.                 ld a,h
  2946.                 cp OutputBufEnd / 256
  2947.                 jp c,WrBlk_AndNext
  2948. ; hl = end address
  2949. CopySplit:      push bc
  2950.                 ld bc,OutputBufEnd
  2951.                 and a
  2952.                 sbc hl,bc       ; hl = bytes past end
  2953.                 ex (sp),hl
  2954.                 pop bc
  2955.                 push bc
  2956.                 sbc hl,bc       ; hl = bytes until end
  2957.                 ld c,l
  2958.                 ld b,h
  2959.                 call WriteBlock
  2960.                 pop bc
  2961.                 ld hl,OutputBuffer
  2962.                 ld a,b
  2963.                 or c
  2964.                 jp nz,CopySlow
  2965.                 ; and next
  2966.                 exx
  2967.                 ld hl,(OutputBufPos)
  2968.                 jp LiteralTree
  2969.  
  2970. WrBlk_AndNext:  call WriteBlock
  2971.                 ; and next
  2972.                 exx
  2973.                 ld hl,(OutputBufPos)
  2974.                 jp LiteralTree
  2975.  
  2976. ; bc = byte count
  2977. ; de = source
  2978. ; Modifies: af, bc, de, hl
  2979. WriteBlock:     ld hl,(OutputBufPos)
  2980.                 add hl,bc
  2981.                 jr c,CopySplit2
  2982.                 ld a,h
  2983.                 cp OutputBufEnd / 256
  2984.                 jr nc,CopySplit2
  2985.                 and a
  2986.                 sbc hl,bc
  2987.                 ex de,hl
  2988.                 ldir
  2989.                 ld (OutputBufPos),de
  2990.                 ret
  2991.  
  2992. ; hl = end address
  2993. CopySplit2:     push bc
  2994.                 ld bc,OutputBufEnd
  2995.                 and a
  2996.                 sbc hl,bc       ; hl = bytes past end
  2997.                 ld c,l
  2998.                 ld b,h
  2999.                 ex (sp),hl
  3000.                 sbc hl,bc       ; hl = bytes until end
  3001.                 ld c,l
  3002.                 ld b,h
  3003.                 ex de,hl
  3004.                 ld de,(OutputBufPos)
  3005.                 ldir
  3006.                 push hl
  3007.                 ex de,hl        ; hl = OutputBufPos
  3008.                 call FinishBlock2
  3009.                 pop de
  3010.                 pop bc
  3011.                 ld a,b
  3012.                 or c
  3013.                 jp nz,WriteBlock
  3014.                 ret
  3015.  
  3016. ; a = value
  3017. ; de,bc <- unchanged
  3018. ;WriteByte:     ld (hl),a
  3019. ;               inc l
  3020. ;               ret nz          ; crosses 256-byte boundary?
  3021.  
  3022. WriteByte2:     inc h
  3023.                 ld a,h
  3024.                 cp OutputBufEnd / 256
  3025.                 ret nz          ; end of buffer reached?
  3026.  
  3027.                 jp FinishBlock2
  3028.                 ; hl = OutputBufPos = OutputBuffer
  3029.  
  3030.  
  3031. ; 'Finish' the data in the (fully or partially filled) OutputBuffer. This is
  3032. ;  - update OutputCount
  3033. ;  - update Crc32Value
  3034. ;  - write the data to disk
  3035. ;  - reinitialize OutputBufPos
  3036. ; hl <- OutputBuffer
  3037. FinishBlock:    ld hl,(OutputBufPos)
  3038. FinishBlock2:   push bc
  3039.                 push de
  3040.  
  3041.                 ld bc,OutputBuffer
  3042.                 or a
  3043.                 sbc hl,bc       ; hl = #bytes in OutputBuffer
  3044.                 jp z,FinishBlockEnd     ; any data present?
  3045.  
  3046. ; Increase count
  3047.                 push hl
  3048.                 ld bc,(OutputCount + 0)
  3049.                 add hl,bc
  3050.                 ld (OutputCount + 0),hl
  3051.                 jr nc,SkipInc64
  3052.                 ld hl,(OutputCount + 2)
  3053.                 inc hl
  3054.                 ld (OutputCount + 2),hl
  3055. SkipInc64:
  3056.  
  3057. ; Update CRC32
  3058.                 ld a,(NoCrcCheck)
  3059.                 or a
  3060.                 jp nz,SkipCrcUpdate
  3061.                 ld hl,OutputBuffer
  3062.                 pop bc          ; bc = #bytes in OutputBuffer
  3063.                 push bc
  3064.                 exx
  3065.                 push bc
  3066.                 push de
  3067.                 push hl
  3068.                 ld de,(Crc32Value + 0)
  3069.                 ld bc,(Crc32Value + 2)  ; bc:de = old crc value (32-bit)
  3070.                 exx
  3071.  
  3072.                 ; crc loop is unrolled 2x, so handle the case of an odd number
  3073.                 ; of elements specially
  3074.                 bit 0,c
  3075.                 jr z,SkipOddCrc
  3076.                 ld a,(hl)
  3077.                 inc hl
  3078.                 exx
  3079.                 xor e
  3080.                 ld l,a
  3081.                 ld h,CRC32Table / 256
  3082.                 ld a,(hl)
  3083.                 xor d
  3084.                 ld e,a
  3085.                 inc h
  3086.                 ld a,(hl)
  3087.                 xor c
  3088.                 ld d,a
  3089.                 inc h
  3090.                 ld a,(hl)
  3091.                 xor b
  3092.                 ld c,a
  3093.                 inc h
  3094.                 ld b,(hl)
  3095.                 exx
  3096.  
  3097. SkipOddCrc:     srl b
  3098.                 rr c    ; bc /= 2
  3099.                 ld a,b
  3100.                 or c
  3101.                 jr z,CRC32End
  3102.                 ld a,c  ; convert 16-bit counter bc to two 8-bit counters in b and c
  3103.                 dec bc
  3104.                 inc b
  3105.                 ld c,b
  3106.                 ld b,a
  3107.  
  3108.                 ; Use the Z80 stack as an 'accelerator' to read bytes from a
  3109.                 ; table -> the 'pop' instruction reads two bytes and increments
  3110.                 ; the pointer into the table.
  3111.                 ; Of course this only works when interrupts are disabled.
  3112.                 ld (SaveSP),sp
  3113. CRC32Loop2:     di
  3114.                 ld sp,hl
  3115. CRC32Loop:      pop hl
  3116.                 ld a,l
  3117.                 exx
  3118.                 xor e
  3119.                 ld l,a
  3120.                 ld h,CRC32Table / 256
  3121.                 ld a,(hl)
  3122.                 xor d
  3123.                 ld e,a
  3124.                 inc h
  3125.                 ld a,(hl)
  3126.                 xor c
  3127.                 ld d,a
  3128.                 inc h
  3129.                 ld a,(hl)
  3130.                 xor b
  3131.                 ld c,a
  3132.                 inc h
  3133.                 ld b,(hl)
  3134.                 exx
  3135.  
  3136.                 ld a,h
  3137.                 exx
  3138.                 xor e
  3139.                 ld l,a
  3140.                 ld h,CRC32Table / 256
  3141.                 ld a,(hl)
  3142.                 xor d
  3143.                 ld e,a
  3144.                 inc h
  3145.                 ld a,(hl)
  3146.                 xor c
  3147.                 ld d,a
  3148.                 inc h
  3149.                 ld a,(hl)
  3150.                 xor b
  3151.                 ld c,a
  3152.                 inc h
  3153.                 ld b,(hl)
  3154.                 exx
  3155.                 djnz CRC32Loop
  3156.                 ; Don't disable interrupts for too long, so briefly enable them
  3157.                 ; before disabling them again for the next iteration of the
  3158.                 ; outer loop
  3159.                 ld hl,0
  3160.                 add hl,sp
  3161.                 ei
  3162. SaveSP=$+1
  3163.                 ld sp,0
  3164.                 dec c
  3165.                 jp nz,CRC32Loop2
  3166.  
  3167. CRC32End:       exx
  3168.                 ld (Crc32Value + 0),de
  3169.                 ld (Crc32Value + 2),bc  ; store updated crc value (32-bit)
  3170.                 pop hl
  3171.                 pop de
  3172.                 pop bc
  3173.                 exx
  3174. SkipCrcUpdate:
  3175.  
  3176. ; Write data to file
  3177.                 ld de,OutputBuffer
  3178.                 pop hl ; hl = #bytes in OutputBuffer
  3179.                 call GzipWriteOutputBuffer
  3180.  
  3181. FinishBlockEnd: pop de
  3182.                 pop bc
  3183.                 ld hl,OutputBuffer
  3184.                 ld (OutputBufPos),hl
  3185.                 ret
  3186.  
  3187. ; === strings ===
  3188. TextNotGzip:   
  3189. ;               db "Not a GZIP file.", 0
  3190. TextNotDeflate:
  3191. ;               db "Not compressed with DEFLATE.", 0
  3192. TextUnknownFlag:
  3193. ;               db "Unknown flag.", 0
  3194. TextSizeError:
  3195. ;               db "Inflated size mismatch.", 0
  3196. TextCrcError:
  3197. ;               db "Inflated CRC32 mismatch.", 0
  3198. TextBlockErr:
  3199. ;               db "Invalid block type.", 0
  3200. TextLengthErr:
  3201. ;               db "Invalid length.", 0
  3202.  
  3203. ; === variables ===
  3204. ; -- Set by parsing the gzip header --
  3205. HeaderFlags:    db 0
  3206.  
  3207. ; -- Filled in by parsing the command line --
  3208. NoCrcCheck:     db 0    ; non-zero when running without crc check
  3209.  
  3210. ; -- Used during building the dynamic alphabet --
  3211. ; Strictly speaking we only need to store the LSB of the following two values.
  3212. ; But also storing the MSB allows for simpler code, so the space overhead here
  3213. ; is more than made up in smaller code size.
  3214. hlit:           dw 256  ; MSB fixed at '1'
  3215. hdist:          dw 0    ; MSB fixed at '0'
  3216.  
  3217. ; -- Used for reading the input file --
  3218. InputBufPos:    dw InputBufferEnd - 1
  3219. InputBits:      db 0            ; partially consumed byte, 0 -> start new byte
  3220.  
  3221. ; -- Used for writing the output file
  3222. OutputCount:    ds 4            ; 32-bit value
  3223. Crc32Value:     ds 4,#FF        ; 32-bit value
  3224. OutputBufPos:   dw OutputBuffer
  3225.  
  3226. ; === Constant tables ===
  3227.  
  3228. ; -- Used during dynamic alphabet building
  3229. HeaderCodeOrder:db 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
  3230.  
  3231.  
  3232. ; -- The fixed alphabet --
  3233. ; Lengths of the literal symbols
  3234. FixedLitLen:    db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8       ; 0-143: 8
  3235.                 db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  3236.                 db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  3237.                 db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  3238.                 db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  3239.                 db 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
  3240.                 db 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9       ; 144-255: 9
  3241.                 db 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9
  3242.                 db 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9
  3243.                 db 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9
  3244.                 db 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7       ; 256-279: 7
  3245.                 db 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8       ; 280-287: 8
  3246. FixedLitCount:  equ $ - FixedLitLen
  3247.  
  3248. ; Lengths of the distance symbols
  3249. FixedDistLen:   db 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
  3250.                 db 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
  3251. FixedDistCount: equ $ - FixedDistLen
  3252.  
  3253.  
  3254. ; -- CRC32 lookup table, must be 256-byte aligned --
  3255.                 ds (256 - ($ & 255) & 255)
  3256. CRC32Table:     ; uint32_t[256]
  3257.                 ; bits 0-7
  3258.                 db #00, #96, #2c, #ba, #19, #8f, #35, #a3
  3259.                 db #32, #a4, #1e, #88, #2b, #bd, #07, #91
  3260.                 db #64, #f2, #48, #de, #7d, #eb, #51, #c7
  3261.                 db #56, #c0, #7a, #ec, #4f, #d9, #63, #f5
  3262.                 db #c8, #5e, #e4, #72, #d1, #47, #fd, #6b
  3263.                 db #fa, #6c, #d6, #40, #e3, #75, #cf, #59
  3264.                 db #ac, #3a, #80, #16, #b5, #23, #99, #0f
  3265.                 db #9e, #08, #b2, #24, #87, #11, #ab, #3d
  3266.                 db #90, #06, #bc, #2a, #89, #1f, #a5, #33
  3267.                 db #a2, #34, #8e, #18, #bb, #2d, #97, #01
  3268.                 db #f4, #62, #d8, #4e, #ed, #7b, #c1, #57
  3269.                 db #c6, #50, #ea, #7c, #df, #49, #f3, #65
  3270.                 db #58, #ce, #74, #e2, #41, #d7, #6d, #fb
  3271.                 db #6a, #fc, #46, #d0, #73, #e5, #5f, #c9
  3272.                 db #3c, #aa, #10, #86, #25, #b3, #09, #9f
  3273.                 db #0e, #98, #22, #b4, #17, #81, #3b, #ad
  3274.                 db #20, #b6, #0c, #9a, #39, #af, #15, #83
  3275.                 db #12, #84, #3e, #a8, #0b, #9d, #27, #b1
  3276.                 db #44, #d2, #68, #fe, #5d, #cb, #71, #e7
  3277.                 db #76, #e0, #5a, #cc, #6f, #f9, #43, #d5
  3278.                 db #e8, #7e, #c4, #52, #f1, #67, #dd, #4b
  3279.                 db #da, #4c, #f6, #60, #c3, #55, #ef, #79
  3280.                 db #8c, #1a, #a0, #36, #95, #03, #b9, #2f
  3281.                 db #be, #28, #92, #04, #a7, #31, #8b, #1d
  3282.                 db #b0, #26, #9c, #0a, #a9, #3f, #85, #13
  3283.                 db #82, #14, #ae, #38, #9b, #0d, #b7, #21
  3284.                 db #d4, #42, #f8, #6e, #cd, #5b, #e1, #77
  3285.                 db #e6, #70, #ca, #5c, #ff, #69, #d3, #45
  3286.                 db #78, #ee, #54, #c2, #61, #f7, #4d, #db
  3287.                 db #4a, #dc, #66, #f0, #53, #c5, #7f, #e9
  3288.                 db #1c, #8a, #30, #a6, #05, #93, #29, #bf
  3289.                 db #2e, #b8, #02, #94, #37, #a1, #1b, #8d
  3290.  
  3291.                 ; bits 8-15
  3292.                 db #00, #30, #61, #51, #c4, #f4, #a5, #95
  3293.                 db #88, #b8, #e9, #d9, #4c, #7c, #2d, #1d
  3294.                 db #10, #20, #71, #41, #d4, #e4, #b5, #85
  3295.                 db #98, #a8, #f9, #c9, #5c, #6c, #3d, #0d
  3296.                 db #20, #10, #41, #71, #e4, #d4, #85, #b5
  3297.                 db #a8, #98, #c9, #f9, #6c, #5c, #0d, #3d
  3298.                 db #30, #00, #51, #61, #f4, #c4, #95, #a5
  3299.                 db #b8, #88, #d9, #e9, #7c, #4c, #1d, #2d
  3300.                 db #41, #71, #20, #10, #85, #b5, #e4, #d4
  3301.                 db #c9, #f9, #a8, #98, #0d, #3d, #6c, #5c
  3302.                 db #51, #61, #30, #00, #95, #a5, #f4, #c4
  3303.                 db #d9, #e9, #b8, #88, #1d, #2d, #7c, #4c
  3304.                 db #61, #51, #00, #30, #a5, #95, #c4, #f4
  3305.                 db #e9, #d9, #88, #b8, #2d, #1d, #4c, #7c
  3306.                 db #71, #41, #10, #20, #b5, #85, #d4, #e4
  3307.                 db #f9, #c9, #98, #a8, #3d, #0d, #5c, #6c
  3308.                 db #83, #b3, #e2, #d2, #47, #77, #26, #16
  3309.                 db #0b, #3b, #6a, #5a, #cf, #ff, #ae, #9e
  3310.                 db #93, #a3, #f2, #c2, #57, #67, #36, #06
  3311.                 db #1b, #2b, #7a, #4a, #df, #ef, #be, #8e
  3312.                 db #a3, #93, #c2, #f2, #67, #57, #06, #36
  3313.                 db #2b, #1b, #4a, #7a, #ef, #df, #8e, #be
  3314.                 db #b3, #83, #d2, #e2, #77, #47, #16, #26
  3315.                 db #3b, #0b, #5a, #6a, #ff, #cf, #9e, #ae
  3316.                 db #c2, #f2, #a3, #93, #06, #36, #67, #57
  3317.                 db #4a, #7a, #2b, #1b, #8e, #be, #ef, #df
  3318.                 db #d2, #e2, #b3, #83, #16, #26, #77, #47
  3319.                 db #5a, #6a, #3b, #0b, #9e, #ae, #ff, #cf
  3320.                 db #e2, #d2, #83, #b3, #26, #16, #47, #77
  3321.                 db #6a, #5a, #0b, #3b, #ae, #9e, #cf, #ff
  3322.                 db #f2, #c2, #93, #a3, #36, #06, #57, #67
  3323.                 db #7a, #4a, #1b, #2b, #be, #8e, #df, #ef
  3324.  
  3325.                 ; bits 16-23
  3326.                 db #00, #07, #0e, #09, #6d, #6a, #63, #64
  3327.                 db #db, #dc, #d5, #d2, #b6, #b1, #b8, #bf
  3328.                 db #b7, #b0, #b9, #be, #da, #dd, #d4, #d3
  3329.                 db #6c, #6b, #62, #65, #01, #06, #0f, #08
  3330.                 db #6e, #69, #60, #67, #03, #04, #0d, #0a
  3331.                 db #b5, #b2, #bb, #bc, #d8, #df, #d6, #d1
  3332.                 db #d9, #de, #d7, #d0, #b4, #b3, #ba, #bd
  3333.                 db #02, #05, #0c, #0b, #6f, #68, #61, #66
  3334.                 db #dc, #db, #d2, #d5, #b1, #b6, #bf, #b8
  3335.                 db #07, #00, #09, #0e, #6a, #6d, #64, #63
  3336.                 db #6b, #6c, #65, #62, #06, #01, #08, #0f
  3337.                 db #b0, #b7, #be, #b9, #dd, #da, #d3, #d4
  3338.                 db #b2, #b5, #bc, #bb, #df, #d8, #d1, #d6
  3339.                 db #69, #6e, #67, #60, #04, #03, #0a, #0d
  3340.                 db #05, #02, #0b, #0c, #68, #6f, #66, #61
  3341.                 db #de, #d9, #d0, #d7, #b3, #b4, #bd, #ba
  3342.                 db #b8, #bf, #b6, #b1, #d5, #d2, #db, #dc
  3343.                 db #63, #64, #6d, #6a, #0e, #09, #00, #07
  3344.                 db #0f, #08, #01, #06, #62, #65, #6c, #6b
  3345.                 db #d4, #d3, #da, #dd, #b9, #be, #b7, #b0
  3346.                 db #d6, #d1, #d8, #df, #bb, #bc, #b5, #b2
  3347.                 db #0d, #0a, #03, #04, #60, #67, #6e, #69
  3348.                 db #61, #66, #6f, #68, #0c, #0b, #02, #05
  3349.                 db #ba, #bd, #b4, #b3, #d7, #d0, #d9, #de
  3350.                 db #64, #63, #6a, #6d, #09, #0e, #07, #00
  3351.                 db #bf, #b8, #b1, #b6, #d2, #d5, #dc, #db
  3352.                 db #d3, #d4, #dd, #da, #be, #b9, #b0, #b7
  3353.                 db #08, #0f, #06, #01, #65, #62, #6b, #6c
  3354.                 db #0a, #0d, #04, #03, #67, #60, #69, #6e
  3355.                 db #d1, #d6, #df, #d8, #bc, #bb, #b2, #b5
  3356.                 db #bd, #ba, #b3, #b4, #d0, #d7, #de, #d9
  3357.                 db #66, #61, #68, #6f, #0b, #0c, #05, #02
  3358.  
  3359.                 ; bits 24-31
  3360.                 db #00, #77, #ee, #99, #07, #70, #e9, #9e
  3361.                 db #0e, #79, #e0, #97, #09, #7e, #e7, #90
  3362.                 db #1d, #6a, #f3, #84, #1a, #6d, #f4, #83
  3363.                 db #13, #64, #fd, #8a, #14, #63, #fa, #8d
  3364.                 db #3b, #4c, #d5, #a2, #3c, #4b, #d2, #a5
  3365.                 db #35, #42, #db, #ac, #32, #45, #dc, #ab
  3366.                 db #26, #51, #c8, #bf, #21, #56, #cf, #b8
  3367.                 db #28, #5f, #c6, #b1, #2f, #58, #c1, #b6
  3368.                 db #76, #01, #98, #ef, #71, #06, #9f, #e8
  3369.                 db #78, #0f, #96, #e1, #7f, #08, #91, #e6
  3370.                 db #6b, #1c, #85, #f2, #6c, #1b, #82, #f5
  3371.                 db #65, #12, #8b, #fc, #62, #15, #8c, #fb
  3372.                 db #4d, #3a, #a3, #d4, #4a, #3d, #a4, #d3
  3373.                 db #43, #34, #ad, #da, #44, #33, #aa, #dd
  3374.                 db #50, #27, #be, #c9, #57, #20, #b9, #ce
  3375.                 db #5e, #29, #b0, #c7, #59, #2e, #b7, #c0
  3376.                 db #ed, #9a, #03, #74, #ea, #9d, #04, #73
  3377.                 db #e3, #94, #0d, #7a, #e4, #93, #0a, #7d
  3378.                 db #f0, #87, #1e, #69, #f7, #80, #19, #6e
  3379.                 db #fe, #89, #10, #67, #f9, #8e, #17, #60
  3380.                 db #d6, #a1, #38, #4f, #d1, #a6, #3f, #48
  3381.                 db #d8, #af, #36, #41, #df, #a8, #31, #46
  3382.                 db #cb, #bc, #25, #52, #cc, #bb, #22, #55
  3383.                 db #c5, #b2, #2b, #5c, #c2, #b5, #2c, #5b
  3384.                 db #9b, #ec, #75, #02, #9c, #eb, #72, #05
  3385.                 db #95, #e2, #7b, #0c, #92, #e5, #7c, #0b
  3386.                 db #86, #f1, #68, #1f, #81, #f6, #6f, #18
  3387.                 db #88, #ff, #66, #11, #8f, #f8, #61, #16
  3388.                 db #a0, #d7, #4e, #39, #a7, #d0, #49, #3e
  3389.                 db #ae, #d9, #40, #37, #a9, #de, #47, #30
  3390.                 db #bd, #ca, #53, #24, #ba, #cd, #54, #23
  3391.                 db #b3, #c4, #5d, #2a, #b4, #c3, #5a, #2d
  3392.  
  3393.  
  3394. ; === Buffers ===
  3395.  
  3396. ; -- BuildDynAlpha --
  3397. ; union {
  3398. ;     HdrCodeLengths      ds MAX_HEADER_LEN
  3399. ;     struct {
  3400. ;         LLDCodeLengths  ds MAX_LIT_LEN + MAX_DIST_LEN
  3401. ;         HeaderTree      ds (8 + 5) * (MAX_HEADER_LEN - 1)
  3402. ;     }
  3403. ; }
  3404. ; These 3 buffers are only needed during BuildDynAlpha, though LLDCodeLengths
  3405. ; cannot overlap with LiteralTree and DistanceTree
  3406.  
  3407. HdrCodeLSize:   equ MAX_HEADER_LEN
  3408. LLDCodeLSize:   equ MAX_LIT_LEN + MAX_DIST_LEN
  3409. HeaderTreeSize: equ (8 + 5) * (MAX_HEADER_LEN - 1)
  3410.  
  3411. HdrCodeLengths: equ GzipBuffersStart                    ; ds HdrCodeLSize
  3412. LLDCodeLengths: equ GzipBuffersStart                    ; ds LLDCodeLSize
  3413. HeaderTree:     equ LLDCodeLengths + LLDCodeLSize       ; ds HeaderTreeSize
  3414.  
  3415. HeaderTreeEnd:  equ HeaderTree + HeaderTreeSize
  3416.  
  3417.  
  3418. ; -- Generated literal/distance huffman trees
  3419. ; These cannot overlap LLDCodeLengths, but overlapping HeaderTree is fine
  3420. LiteralTreeSize:equ (8 +  5) * (288 - 1)
  3421. LiteralTree:    equ HeaderTree
  3422. LiteralTreeEnd: equ LiteralTree + LiteralTreeSize
  3423.  
  3424. DistTreeSize:   equ (8 + 12) * (32 - 1)
  3425. CopySetLength:  equ LiteralTreeEnd
  3426. DistanceTree:   equ CopySetLength + CopySLLen
  3427. DistanceTreeEnd:equ DistanceTree + DistTreeSize
  3428.  
  3429. ; -- Input and output file buffers
  3430. ; These must be aligned at 256-byte boundary. OutputBuffer must be exactly
  3431. ; 32kB. InputBuffer must be (any) multiple of 256 bytes, but bigger improves
  3432. ; read performance.
  3433. Padding:        equ (256 - ((DistanceTreeEnd) & 255)) & 255
  3434.  
  3435. OutputBufSize:  equ #8000       ; _must_ be exactly 32kB
  3436. OutputBuffer:   equ DistanceTreeEnd + Padding
  3437. OutputBufEnd:   equ OutputBuffer + OutputBufSize
  3438.  
  3439. InputBufSize:   equ 512
  3440. InputBuffer:    equ OutputBufEnd
  3441. InputBufferEnd: equ InputBuffer + InputBufSize
  3442.  
  3443. ; -- Huffman scratch area --
  3444. ; Used while generating Huffman decoder.  TODO maybe overlap with 'Padding'?
  3445. CountBufSize:   equ MAX_CODELENGTH * 2  ; must be 256-byte aligned
  3446. CountBuffer:    equ InputBufferEnd
  3447. CountBufEnd:    equ CountBuffer + CountBufSize
  3448.  
  3449. SortedBufSize:  equ 4 * MAX_LIT_LEN + 1
  3450. SortedBuffer:   equ CountBufEnd
  3451. SortedBufEnd:   equ SortedBuffer + SortedBufSize
  3452.  
  3453. GzipBuffersEnd: equ SortedBufEnd
  3454.