Subversion Repositories NedoOS

Rev

Rev 1797 | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
1797 galstaff 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
2272 galstaff 15
;   GzipOutputBuffersStart
16
;   GzipWorkBuffersStart
1797 galstaff 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
2272 galstaff 3080
                add a,CRC32Table % 256
1797 galstaff 3081
                ld l,a
2272 galstaff 3082
                adc a,CRC32Table / 256
3083
                sub l
3084
                ld h,a
1797 galstaff 3085
                ld a,(hl)
3086
                xor d
3087
                ld e,a
3088
                inc h
3089
                ld a,(hl)
3090
                xor c
3091
                ld d,a
3092
                inc h
3093
                ld a,(hl)
3094
                xor b
3095
                ld c,a
3096
                inc h
3097
                ld b,(hl)
3098
                exx
3099
 
3100
SkipOddCrc:     srl b
3101
                rr c    ; bc /= 2
3102
                ld a,b
3103
                or c
3104
                jr z,CRC32End
3105
                ld a,c  ; convert 16-bit counter bc to two 8-bit counters in b and c
3106
                dec bc
3107
                inc b
3108
                ld c,b
3109
                ld b,a
3110
 
3111
                ; Use the Z80 stack as an 'accelerator' to read bytes from a
3112
                ; table -> the 'pop' instruction reads two bytes and increments
3113
                ; the pointer into the table.
3114
                ; Of course this only works when interrupts are disabled.
3115
                ld (SaveSP),sp
3116
CRC32Loop2:     di
3117
                ld sp,hl
3118
CRC32Loop:      pop hl
3119
                ld a,l
3120
                exx
3121
                xor e
2272 galstaff 3122
                add a,CRC32Table % 256
1797 galstaff 3123
                ld l,a
2272 galstaff 3124
                adc a,CRC32Table / 256
3125
                sub l
3126
                ld h,a
1797 galstaff 3127
                ld a,(hl)
3128
                xor d
3129
                ld e,a
3130
                inc h
3131
                ld a,(hl)
3132
                xor c
3133
                ld d,a
3134
                inc h
3135
                ld a,(hl)
3136
                xor b
3137
                ld c,a
3138
                inc h
3139
                ld b,(hl)
3140
                exx
3141
 
3142
                ld a,h
3143
                exx
3144
                xor e
2272 galstaff 3145
                add a,CRC32Table % 256
1797 galstaff 3146
                ld l,a
2272 galstaff 3147
                adc a,CRC32Table / 256
3148
                sub l
3149
                ld h,a
1797 galstaff 3150
                ld a,(hl)
3151
                xor d
3152
                ld e,a
3153
                inc h
3154
                ld a,(hl)
3155
                xor c
3156
                ld d,a
3157
                inc h
3158
                ld a,(hl)
3159
                xor b
3160
                ld c,a
3161
                inc h
3162
                ld b,(hl)
3163
                exx
3164
                djnz CRC32Loop
3165
                ; Don't disable interrupts for too long, so briefly enable them
3166
                ; before disabling them again for the next iteration of the
3167
                ; outer loop
3168
                ld hl,0
3169
                add hl,sp
3170
                ei
3171
SaveSP=$+1
3172
                ld sp,0
3173
                dec c
3174
                jp nz,CRC32Loop2
3175
 
3176
CRC32End:       exx
3177
                ld (Crc32Value + 0),de
3178
                ld (Crc32Value + 2),bc  ; store updated crc value (32-bit)
3179
                pop hl
3180
                pop de
3181
                pop bc
3182
                exx
3183
SkipCrcUpdate:
3184
 
3185
; Write data to file
3186
                ld de,OutputBuffer
3187
                pop hl ; hl = #bytes in OutputBuffer
3188
                call GzipWriteOutputBuffer
3189
 
3190
FinishBlockEnd: pop de
3191
                pop bc
3192
                ld hl,OutputBuffer
3193
                ld (OutputBufPos),hl
3194
                ret
3195
 
3196
; === strings ===
3197
TextNotGzip:   
3198
;               db "Not a GZIP file.", 0
3199
TextNotDeflate:
3200
;               db "Not compressed with DEFLATE.", 0
3201
TextUnknownFlag:
3202
;               db "Unknown flag.", 0
3203
TextSizeError:
3204
;               db "Inflated size mismatch.", 0
3205
TextCrcError:
3206
;               db "Inflated CRC32 mismatch.", 0
3207
TextBlockErr:
3208
;               db "Invalid block type.", 0
3209
TextLengthErr:
3210
;               db "Invalid length.", 0
3211
 
3212
; === variables ===
3213
; -- Set by parsing the gzip header --
3214
HeaderFlags:    db 0
3215
 
3216
; -- Filled in by parsing the command line --
3217
NoCrcCheck:     db 0    ; non-zero when running without crc check
3218
 
3219
; -- Used during building the dynamic alphabet --
3220
; Strictly speaking we only need to store the LSB of the following two values.
3221
; But also storing the MSB allows for simpler code, so the space overhead here
3222
; is more than made up in smaller code size.
3223
hlit:           dw 256  ; MSB fixed at '1'
3224
hdist:          dw 0    ; MSB fixed at '0'
3225
 
3226
; -- Used for reading the input file --
3227
InputBufPos:    dw InputBufferEnd - 1
3228
InputBits:      db 0            ; partially consumed byte, 0 -> start new byte
3229
 
3230
; -- Used for writing the output file
3231
OutputCount:    ds 4            ; 32-bit value
3232
Crc32Value:     ds 4,#FF        ; 32-bit value
3233
OutputBufPos:   dw OutputBuffer
3234
 
3235
; === Constant tables ===
3236
 
3237
; -- Used during dynamic alphabet building
3238
HeaderCodeOrder:db 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
3239
 
3240
 
3241
; -- The fixed alphabet --
3242
; Lengths of the literal symbols
3243
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
3244
                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
3245
                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
3246
                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
3247
                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
3248
                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
3249
                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
3250
                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
3251
                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
3252
                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
3253
                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
3254
                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
3255
FixedLitCount:  equ $ - FixedLitLen
3256
 
3257
; Lengths of the distance symbols
3258
FixedDistLen:   db 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
3259
                db 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
3260
FixedDistCount: equ $ - FixedDistLen
3261
 
3262
 
2272 galstaff 3263
; -- CRC32 lookup table --
1797 galstaff 3264
CRC32Table:     ; uint32_t[256]
3265
                ; bits 0-7
3266
                db #00, #96, #2c, #ba, #19, #8f, #35, #a3
3267
                db #32, #a4, #1e, #88, #2b, #bd, #07, #91
3268
                db #64, #f2, #48, #de, #7d, #eb, #51, #c7
3269
                db #56, #c0, #7a, #ec, #4f, #d9, #63, #f5
3270
                db #c8, #5e, #e4, #72, #d1, #47, #fd, #6b
3271
                db #fa, #6c, #d6, #40, #e3, #75, #cf, #59
3272
                db #ac, #3a, #80, #16, #b5, #23, #99, #0f
3273
                db #9e, #08, #b2, #24, #87, #11, #ab, #3d
3274
                db #90, #06, #bc, #2a, #89, #1f, #a5, #33
3275
                db #a2, #34, #8e, #18, #bb, #2d, #97, #01
3276
                db #f4, #62, #d8, #4e, #ed, #7b, #c1, #57
3277
                db #c6, #50, #ea, #7c, #df, #49, #f3, #65
3278
                db #58, #ce, #74, #e2, #41, #d7, #6d, #fb
3279
                db #6a, #fc, #46, #d0, #73, #e5, #5f, #c9
3280
                db #3c, #aa, #10, #86, #25, #b3, #09, #9f
3281
                db #0e, #98, #22, #b4, #17, #81, #3b, #ad
3282
                db #20, #b6, #0c, #9a, #39, #af, #15, #83
3283
                db #12, #84, #3e, #a8, #0b, #9d, #27, #b1
3284
                db #44, #d2, #68, #fe, #5d, #cb, #71, #e7
3285
                db #76, #e0, #5a, #cc, #6f, #f9, #43, #d5
3286
                db #e8, #7e, #c4, #52, #f1, #67, #dd, #4b
3287
                db #da, #4c, #f6, #60, #c3, #55, #ef, #79
3288
                db #8c, #1a, #a0, #36, #95, #03, #b9, #2f
3289
                db #be, #28, #92, #04, #a7, #31, #8b, #1d
3290
                db #b0, #26, #9c, #0a, #a9, #3f, #85, #13
3291
                db #82, #14, #ae, #38, #9b, #0d, #b7, #21
3292
                db #d4, #42, #f8, #6e, #cd, #5b, #e1, #77
3293
                db #e6, #70, #ca, #5c, #ff, #69, #d3, #45
3294
                db #78, #ee, #54, #c2, #61, #f7, #4d, #db
3295
                db #4a, #dc, #66, #f0, #53, #c5, #7f, #e9
3296
                db #1c, #8a, #30, #a6, #05, #93, #29, #bf
3297
                db #2e, #b8, #02, #94, #37, #a1, #1b, #8d
3298
 
3299
                ; bits 8-15
3300
                db #00, #30, #61, #51, #c4, #f4, #a5, #95
3301
                db #88, #b8, #e9, #d9, #4c, #7c, #2d, #1d
3302
                db #10, #20, #71, #41, #d4, #e4, #b5, #85
3303
                db #98, #a8, #f9, #c9, #5c, #6c, #3d, #0d
3304
                db #20, #10, #41, #71, #e4, #d4, #85, #b5
3305
                db #a8, #98, #c9, #f9, #6c, #5c, #0d, #3d
3306
                db #30, #00, #51, #61, #f4, #c4, #95, #a5
3307
                db #b8, #88, #d9, #e9, #7c, #4c, #1d, #2d
3308
                db #41, #71, #20, #10, #85, #b5, #e4, #d4
3309
                db #c9, #f9, #a8, #98, #0d, #3d, #6c, #5c
3310
                db #51, #61, #30, #00, #95, #a5, #f4, #c4
3311
                db #d9, #e9, #b8, #88, #1d, #2d, #7c, #4c
3312
                db #61, #51, #00, #30, #a5, #95, #c4, #f4
3313
                db #e9, #d9, #88, #b8, #2d, #1d, #4c, #7c
3314
                db #71, #41, #10, #20, #b5, #85, #d4, #e4
3315
                db #f9, #c9, #98, #a8, #3d, #0d, #5c, #6c
3316
                db #83, #b3, #e2, #d2, #47, #77, #26, #16
3317
                db #0b, #3b, #6a, #5a, #cf, #ff, #ae, #9e
3318
                db #93, #a3, #f2, #c2, #57, #67, #36, #06
3319
                db #1b, #2b, #7a, #4a, #df, #ef, #be, #8e
3320
                db #a3, #93, #c2, #f2, #67, #57, #06, #36
3321
                db #2b, #1b, #4a, #7a, #ef, #df, #8e, #be
3322
                db #b3, #83, #d2, #e2, #77, #47, #16, #26
3323
                db #3b, #0b, #5a, #6a, #ff, #cf, #9e, #ae
3324
                db #c2, #f2, #a3, #93, #06, #36, #67, #57
3325
                db #4a, #7a, #2b, #1b, #8e, #be, #ef, #df
3326
                db #d2, #e2, #b3, #83, #16, #26, #77, #47
3327
                db #5a, #6a, #3b, #0b, #9e, #ae, #ff, #cf
3328
                db #e2, #d2, #83, #b3, #26, #16, #47, #77
3329
                db #6a, #5a, #0b, #3b, #ae, #9e, #cf, #ff
3330
                db #f2, #c2, #93, #a3, #36, #06, #57, #67
3331
                db #7a, #4a, #1b, #2b, #be, #8e, #df, #ef
3332
 
3333
                ; bits 16-23
3334
                db #00, #07, #0e, #09, #6d, #6a, #63, #64
3335
                db #db, #dc, #d5, #d2, #b6, #b1, #b8, #bf
3336
                db #b7, #b0, #b9, #be, #da, #dd, #d4, #d3
3337
                db #6c, #6b, #62, #65, #01, #06, #0f, #08
3338
                db #6e, #69, #60, #67, #03, #04, #0d, #0a
3339
                db #b5, #b2, #bb, #bc, #d8, #df, #d6, #d1
3340
                db #d9, #de, #d7, #d0, #b4, #b3, #ba, #bd
3341
                db #02, #05, #0c, #0b, #6f, #68, #61, #66
3342
                db #dc, #db, #d2, #d5, #b1, #b6, #bf, #b8
3343
                db #07, #00, #09, #0e, #6a, #6d, #64, #63
3344
                db #6b, #6c, #65, #62, #06, #01, #08, #0f
3345
                db #b0, #b7, #be, #b9, #dd, #da, #d3, #d4
3346
                db #b2, #b5, #bc, #bb, #df, #d8, #d1, #d6
3347
                db #69, #6e, #67, #60, #04, #03, #0a, #0d
3348
                db #05, #02, #0b, #0c, #68, #6f, #66, #61
3349
                db #de, #d9, #d0, #d7, #b3, #b4, #bd, #ba
3350
                db #b8, #bf, #b6, #b1, #d5, #d2, #db, #dc
3351
                db #63, #64, #6d, #6a, #0e, #09, #00, #07
3352
                db #0f, #08, #01, #06, #62, #65, #6c, #6b
3353
                db #d4, #d3, #da, #dd, #b9, #be, #b7, #b0
3354
                db #d6, #d1, #d8, #df, #bb, #bc, #b5, #b2
3355
                db #0d, #0a, #03, #04, #60, #67, #6e, #69
3356
                db #61, #66, #6f, #68, #0c, #0b, #02, #05
3357
                db #ba, #bd, #b4, #b3, #d7, #d0, #d9, #de
3358
                db #64, #63, #6a, #6d, #09, #0e, #07, #00
3359
                db #bf, #b8, #b1, #b6, #d2, #d5, #dc, #db
3360
                db #d3, #d4, #dd, #da, #be, #b9, #b0, #b7
3361
                db #08, #0f, #06, #01, #65, #62, #6b, #6c
3362
                db #0a, #0d, #04, #03, #67, #60, #69, #6e
3363
                db #d1, #d6, #df, #d8, #bc, #bb, #b2, #b5
3364
                db #bd, #ba, #b3, #b4, #d0, #d7, #de, #d9
3365
                db #66, #61, #68, #6f, #0b, #0c, #05, #02
3366
 
3367
                ; bits 24-31
3368
                db #00, #77, #ee, #99, #07, #70, #e9, #9e
3369
                db #0e, #79, #e0, #97, #09, #7e, #e7, #90
3370
                db #1d, #6a, #f3, #84, #1a, #6d, #f4, #83
3371
                db #13, #64, #fd, #8a, #14, #63, #fa, #8d
3372
                db #3b, #4c, #d5, #a2, #3c, #4b, #d2, #a5
3373
                db #35, #42, #db, #ac, #32, #45, #dc, #ab
3374
                db #26, #51, #c8, #bf, #21, #56, #cf, #b8
3375
                db #28, #5f, #c6, #b1, #2f, #58, #c1, #b6
3376
                db #76, #01, #98, #ef, #71, #06, #9f, #e8
3377
                db #78, #0f, #96, #e1, #7f, #08, #91, #e6
3378
                db #6b, #1c, #85, #f2, #6c, #1b, #82, #f5
3379
                db #65, #12, #8b, #fc, #62, #15, #8c, #fb
3380
                db #4d, #3a, #a3, #d4, #4a, #3d, #a4, #d3
3381
                db #43, #34, #ad, #da, #44, #33, #aa, #dd
3382
                db #50, #27, #be, #c9, #57, #20, #b9, #ce
3383
                db #5e, #29, #b0, #c7, #59, #2e, #b7, #c0
3384
                db #ed, #9a, #03, #74, #ea, #9d, #04, #73
3385
                db #e3, #94, #0d, #7a, #e4, #93, #0a, #7d
3386
                db #f0, #87, #1e, #69, #f7, #80, #19, #6e
3387
                db #fe, #89, #10, #67, #f9, #8e, #17, #60
3388
                db #d6, #a1, #38, #4f, #d1, #a6, #3f, #48
3389
                db #d8, #af, #36, #41, #df, #a8, #31, #46
3390
                db #cb, #bc, #25, #52, #cc, #bb, #22, #55
3391
                db #c5, #b2, #2b, #5c, #c2, #b5, #2c, #5b
3392
                db #9b, #ec, #75, #02, #9c, #eb, #72, #05
3393
                db #95, #e2, #7b, #0c, #92, #e5, #7c, #0b
3394
                db #86, #f1, #68, #1f, #81, #f6, #6f, #18
3395
                db #88, #ff, #66, #11, #8f, #f8, #61, #16
3396
                db #a0, #d7, #4e, #39, #a7, #d0, #49, #3e
3397
                db #ae, #d9, #40, #37, #a9, #de, #47, #30
3398
                db #bd, #ca, #53, #24, #ba, #cd, #54, #23
3399
                db #b3, #c4, #5d, #2a, #b4, #c3, #5a, #2d
3400
 
3401
 
3402
; === Buffers ===
3403
 
3404
; -- BuildDynAlpha --
3405
; union {
3406
;     HdrCodeLengths      ds MAX_HEADER_LEN
3407
;     struct {
3408
;         LLDCodeLengths  ds MAX_LIT_LEN + MAX_DIST_LEN
3409
;         HeaderTree      ds (8 + 5) * (MAX_HEADER_LEN - 1)
3410
;     }
3411
; }
3412
; These 3 buffers are only needed during BuildDynAlpha, though LLDCodeLengths
3413
; cannot overlap with LiteralTree and DistanceTree
3414
 
3415
HdrCodeLSize:   equ MAX_HEADER_LEN
3416
LLDCodeLSize:   equ MAX_LIT_LEN + MAX_DIST_LEN
3417
HeaderTreeSize: equ (8 + 5) * (MAX_HEADER_LEN - 1)
3418
 
2272 galstaff 3419
HdrCodeLengths: equ GzipWorkBuffersStart                ; ds HdrCodeLSize
3420
LLDCodeLengths: equ GzipWorkBuffersStart                ; ds LLDCodeLSize
1797 galstaff 3421
HeaderTree:     equ LLDCodeLengths + LLDCodeLSize       ; ds HeaderTreeSize
3422
 
3423
HeaderTreeEnd:  equ HeaderTree + HeaderTreeSize
3424
 
3425
 
3426
; -- Generated literal/distance huffman trees
3427
; These cannot overlap LLDCodeLengths, but overlapping HeaderTree is fine
3428
LiteralTreeSize:equ (8 +  5) * (288 - 1)
3429
LiteralTree:    equ HeaderTree
3430
LiteralTreeEnd: equ LiteralTree + LiteralTreeSize
3431
 
3432
DistTreeSize:   equ (8 + 12) * (32 - 1)
3433
CopySetLength:  equ LiteralTreeEnd
3434
DistanceTree:   equ CopySetLength + CopySLLen
3435
DistanceTreeEnd:equ DistanceTree + DistTreeSize
3436
 
2272 galstaff 3437
Padding1:       equ (256 - ((DistanceTreeEnd) & 255)) & 255
3438
 
3439
InputBufSize:   equ 8192
3440
InputBuffer:    equ DistanceTreeEnd + Padding1
3441
InputBufferEnd: equ InputBuffer + InputBufSize
3442
 
3443
GzipWorkBuffersEnd: equ InputBufferEnd
3444
 
1797 galstaff 3445
; -- Input and output file buffers
3446
; These must be aligned at 256-byte boundary. OutputBuffer must be exactly
3447
; 32kB. InputBuffer must be (any) multiple of 256 bytes, but bigger improves
3448
; read performance.
2272 galstaff 3449
Padding2:       equ (256 - ((GzipOutputBuffersStart) & 255)) & 255
1797 galstaff 3450
 
3451
OutputBufSize:  equ #8000       ; _must_ be exactly 32kB
2272 galstaff 3452
OutputBuffer:   equ GzipOutputBuffersStart + Padding2
1797 galstaff 3453
OutputBufEnd:   equ OutputBuffer + OutputBufSize
3454
 
3455
; -- Huffman scratch area --
3456
; Used while generating Huffman decoder.  TODO maybe overlap with 'Padding'?
3457
CountBufSize:   equ MAX_CODELENGTH * 2  ; must be 256-byte aligned
2272 galstaff 3458
CountBuffer:    equ OutputBufEnd
1797 galstaff 3459
CountBufEnd:    equ CountBuffer + CountBufSize
3460
 
3461
SortedBufSize:  equ 4 * MAX_LIT_LEN + 1
3462
SortedBuffer:   equ CountBufEnd
3463
SortedBufEnd:   equ SortedBuffer + SortedBufSize
3464
 
2272 galstaff 3465
GzipOutputBuffersEnd:   equ SortedBufEnd