Subversion Repositories NedoOS

Rev

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

Rev Author Line No. Line
344 alone 1
 
2
ldirinpages;Z6542
3
;hl=откуда (логический адрес в буфере сохранения)
4
;bc=сколько
5
;TODO ускорить
6
        LD A,C
7
        OR B
8
        RET Z ;TODO надо ли?
9
         ;DI 
10
         ;CALL 8020
11
        ;JP C,_Z6545
12
        ; LD A,4
13
        ; CALL ON_BANK
14
        ; JP START_1
15
 
16
Z6546=$+1 ;сколько байт сохранить (это же текущий адрес в буфере, т.е. куда копировать)
17
        LD DE,0
18
 
19
        if depkbuf
20
        push bc
21
        ld bc,depkbuf
22
        add hl,bc
23
        ex de,hl
24
        add hl,bc
25
        ex de,hl
26
        pop bc
27
ldirinpages0
28
        ld a,(hl)
29
        CALL CRC32_
30
        ldi
31
        jp pe,ldirinpages0
32
        ld hl,-depkbuf
33
        add hl,de
34
        ld (Z6546),hl
35
        ret
36
        ;bit 7,h
37
        ;ret z
38
        ;jp saveblock ;save whole buffer
39
 
40
        else
41
 
42
        PUSH HL,DE
43
        LD A,D
44
        LD (SAVED+1),A
45
        LD A,H
46
        LD (SAVEH+1),A
47
 
48
        if depkbuf
49
        add a,depkbuf/256
50
        LD H,A
51
        else
52
        RLCA
53
        RLCA
54
        AND 3
55
        LD (BANKH+1),A
56
        CALL ON_BANK
57
        LD A,H
58
        OR #C0
59
        LD H,A
60
        endif
61
 
62
        LD (ADRH+1),HL
63
        LD A,(HL)
64
        EXA
65
        LD A,D
66
 
67
        if depkbuf
68
        add a,depkbuf/256
69
        LD D,A
70
        else
71
        RLCA
72
        RLCA
73
        AND 3
74
        LD (BANKD+1),A
75
        CALL ON_BANK
76
        LD A,D
77
        OR #C0
78
        LD D,A
79
        endif
80
 
81
        LD (ADRD+1),DE
82
        EXA
83
        LD (DE),A
84
        CALL CRC32_
85
        POP DE,HL
86
        INC DE
87
        LD A,D
88
        INC A
89
        JR Z,SV1
90
WOZW1   CPI
91
        JP PO,AFN5
92
ADRH    LD HL,0
93
ADRD    LD DE,0
94
AFN2    INC L
95
        JR Z,SAVEH
96
AFN1    INC E
97
        JR Z,SAVED
98
AFN3    LD A,B
99
        OR C
100
        JR Z,AFN4
101
 
102
        if depkbuf==0
103
BANKH   LD A,0
104
        CALL ON_BANK
105
        endif
106
 
107
        LD A,(HL)
108
 
109
        if depkbuf==0
110
        EXA
111
BANKD   LD A,0
112
        CALL ON_BANK
113
        EXA
114
        endif
115
 
116
        LD (DE),A
117
        CALL CRC32_
118
        DEC BC
119
        JP AFN2
120
 
121
SAVEH   LD A,0
122
       INC A,A
123
       JR Z,$+3
124
       DEC A
125
        LD H,A
126
        LD (SAVEH+1),A
127
 
128
        if depkbuf==0
129
        RLCA
130
        RLCA
131
        AND 3
132
        LD (BANKH+1),A
133
        LD A,H
134
        OR #C0
135
        LD H,A
136
        endif
137
        JR AFN1
138
 
139
SAVED   LD A,0
140
        INC A
141
        LD D,A
142
        if buf64k
143
        INC A
144
        else
145
        cp 0x80
146
        endif
147
        JR Z,SV2 ;save whole buffer
148
WOZWR2  LD A,D
149
        LD (SAVED+1),A
150
 
151
        if depkbuf==0
152
        RLCA
153
        RLCA
154
        AND 3
155
        LD (BANKD+1),A
156
        LD A,D
157
        OR #C0
158
        LD D,A
159
        endif
160
        LD (ADRD+2),A
161
        JR AFN3
162
 
163
AFN4    LD A,(SAVED+1)
164
        LD D,A
165
AFN5    LD (Z6546),DE ;сколько байт сохранить
166
        ret
167
        ;LD A,4
168
        ;CALL ON_BANK
169
        ;CALL COUNT ;процентомер?
170
        ;LD A,5
171
        ;JP ON_BANK
172
 
173
SV1     CALL SV0
174
        LD A,D
175
        DEC A
176
        LD (SAVED+1),A
177
 
178
        if depkbuf==0
179
        RLCA
180
        RLCA
181
        AND 3
182
        LD (BANKD+1),A
183
        LD A,D
184
        OR #C0
185
        LD D,A
186
        endif
187
        LD (ADRD+2),A
188
        LD E,-1 ;на случай выхода в AFN5
189
        JP WOZW1
190
 
191
SV2     CALL SV0
192
        JR WOZWR2
193
 
194
SV0     LD (Z6546),DE ;сколько байт сохранить
195
        ;LD A,5
196
        ;CALL ON_BANK
197
        CALL saveblock ;save whole buffer
198
        LD DE,(Z6546) ;сколько байт сохранить (=0?)
199
        RET
200
 
201
        endif
202
 
203
;запись одного байта в память + обновление CRC32 + при необходимости сохранение
204
SBYTE
205
;a=byte
206
        PUSH HL
207
        LD HL,(Z6546) ;сколько байт сохранить (он же текущий адрес, куда писать)
208
        PUSH HL
209
 
210
        if depkbuf
211
        exa
212
        ld a,h
213
        add a,depkbuf/256
214
        ld h,a
215
        exa
216
        else
217
        EXA
218
        LD A,H
219
        RLCA
220
        RLCA
221
        AND 3
222
        CALL ON_BANK
223
        LD A,H
224
        OR #C0
225
        LD H,A
226
        EXA
227
        endif
228
        LD (HL),A
229
        CALL CRC32_
230
        POP HL
231
        INC HL
232
        ;LD A,H
233
        ;AND A
234
        ;JR NZ,CON2
235
        ;LD A,L
236
        ;CP #11
237
        ;CALL Z,HOBETA1
238
;CON2    
239
        LD (Z6546),HL ;сколько байт сохранить
240
        ;LD A,5
241
        ;CALL ON_BANK
242
        LD A,H
243
        if buf64k
244
        INC A
245
        else
246
        cp 0x80
247
        endif
248
        POP HL
249
        RET NZ
250
 
251
        jp saveblock
252
 
253
 
254
 
255
;ИНИЦИАЛИЗАЦИЯ ДЕПAKEPA
256
initdepk=initCRC;Z6629
257
 
258
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
259
 
260
;метод store
261
ZD102
262
        LD A,B
263
        CP 8
264
        CALL NZ,read_a_bits
265
        EX DE,HL ;??? (hl=0x802b) длина блока
266
        CALL readbyte_d
267
        LD E,D
268
        CALL readbyte_d ;??? (de=0x7fd4)
269
        LD A,D
270
        XOR H
271
        LD D,A
272
        LD A,E
273
        XOR L
274
        AND D
275
        INC A
276
        call NZ,depkqerror ;save whole buffer и выйти
277
           ;CALL readbyte_d
278
           EX DE,HL
279
 
280
;ZD11F=$+1
281
        ;LD HL,0
282
 
283
        ;DEC HL
284
_ZD122  
285
        ;LD A,(HL)
286
        ;INC HL
287
         ;push hl
288
         ;LD HL,(Z6546)
289
         ;bit 7,h
290
         ;jr nz,$
291
         ;pop hl
292
        ziprdbyte
293
        CALL SBYTE ;запись одного байта в память + обновление CRC32 + при необходимости сохранение
294
        ;PUSH HL
295
        ;LD BC,#4001
296
        ;ADD HL,BC
297
        ;POP HL
298
       ;JR NC,ZD135
299
       ;CALL LBLOKZIP
300
       ;LD HL,BUFER
301
;ZD135   
302
        DEC DE
303
        LD A,D
304
        OR E
305
        JR NZ,_ZD122
306
        ;LD (ZD11F),HL
307
        POP DE ;снимаем адрес возврата
308
        JR _ZD14D ;читаем следующий блок
309
 
310
;ZD140
311
INFLATING
312
;init read buffer, inflate file
313
        XOR A
314
        LD (_ZD159),A ;не последний блок
315
        ;CALL LBLOKZIP
316
       ;LD HL,0
317
       ; LD (U6546),HL ;сколько байт сохранить = текущий адрес в буфере
318
_ZD14D
319
        ;LD HL,(ZD11F)
320
        ;LD E,(HL)
321
        ;INC HL
322
        ;LD (ZD11F),HL
323
        ziprdbyte
324
        ld e,a
325
        CALL readbyte_d ;установит b=8
326
 
327
_ZD158 ;сюда попадаем по коду 256 (end of block)
328
        ;push hl
329
        ;ld hl,(Z6546)
330
        ;jr $
331
        ;pop hl
332
_ZD159=$+1
333
        LD A,0 ;1 = был последний блок
334
        OR A
335
        jp NZ,savelastblock ;save (U6546) bytes, выход
336
        CALL readbit_de ;1 = last block, 0 = not last block
337
        LD HL,_ZD159 ;см. выше
338
        RR (HL)
339
        CALL readtrees;ZD2E4
340
_ZD168  
341
         ;push de
342
         ;push hl
343
          ;LD HL,(Z6546)
344
          ;bit 7,h
345
          ;jr nz,$ ;почему-то не попадаем сюда
346
         ;ld hl,(Z6546)
347
         ;ld de,0x53c7;0x546f
348
         ;or a
349
         ;sbc hl,de
350
         ;jr nc,$
351
         ;pop hl
352
         ;pop de
353
        CALL readcodetree1 ;out: hl=code
354
        ;jr $
355
         LD A,H
356
         OR A
357
         JR NZ,_ZD175 ;если код - не байт
358
        LD A,L ;байт
359
        CALL SBYTE ;запись одного байта в память + обновление CRC32 + при необходимости сохранение
360
        JR _ZD168
361
_ZD175  DEC A
362
        OR L
363
;256: end of block - stop processing if last block, otherwise start processing next block.
364
;257-285: combined with extra-bits, a match length of 3-258 bytes.
365
;286, 287: not used, reserved and illegal but still part of the tree.
366
         ;jr z,$ ;не доходим сюда на adv 1,2, а в adv3 его нет в первом блоке
367
         ;push hl
368
         ;LD HL,(Z6546)
369
         ;pop hl
370
        JR Z,_ZD158 ;если 256 (end of block), то назад на чтение заголовка блока и деревьев
371
        ;jr $
372
 
373
        DEC H
374
        INC HL,HL
375
        PUSH HL ;2+(код-256) = сколько
376
        CALL readcodetree2 ;distance
377
        INC HL
378
        POP AF
379
        PUSH BC,DE,AF
380
        POP BC ;2+(код-256) = сколько
381
        EX DE,HL ;de=код по tree2 (расстояние?)
382
        LD HL,(U6546) ;сколько байт сохранить = текущий адрес в буфере
383
       OR A
384
        SBC HL,DE
385
        JR NC,_ZD1B5 ;расстояние умещается внутри несохранённого блока?
386
        EX DE,HL ;de = -сколько байт не хватает?
387
       LD HL,0
388
       OR A
389
        SBC HL,DE ;сколько байт не хватает?
390
        PUSH HL
391
        LD HL,#2121
392
TD198=$-2 ;сколько байт сохраняли в прошлый раз
393
        ADD HL,DE ;hl = сколько байт сохраняли - сколько байт не хватает? (получается адрес в прошлом буфере?)
394
        POP DE
395
        EX DE,HL ;de=адрес в прошлом буфере?, hl=сколько байт не хватает?
396
        PUSH HL ;сколько байт не хватает?
397
       CP A
398
        SBC HL,BC ;NC=блок не пересекает границу старого и нового буферов (сколько байт не хватает >= сколько)
399
        POP HL ;сколько байт не хватает?
400
        EX DE,HL
401
        JR NC,_ZD1B5 ;если блок не пересекает границу старого и нового буферов, то откуда = адрес в прошлом буфере?
402
        EX DE,HL
403
        PUSH BC
404
        EX (SP),HL
405
        POP BC ;hl=сколько, bc=сколько байт не хватает?
406
       AND A
407
        SBC HL,BC
408
        PUSH HL ;сколько-сколько байт не хватает
409
        EX DE,HL ;hl=адрес в прошлом буфере, bc=сколько байт не хватает?
410
        CALL ldirinpages ;скопировали первый кусок в текущий адрес в буфере ;TODO разрезать на 2 части при пересечении 32К
411
        LD HL,0 ;продолжение будем копировать из начала нового буфера
412
        POP BC ;длина продолжения (сколько-сколько байт не хватает)
413
;TODO сделать настоящее скользящее окно 32К, т.к. Relative back-references can be made across any number of blocks, as long as the distance appears within the last 32 KiB of uncompressed data decoded (termed the sliding window)
414
_ZD1B5  
415
;hl = откуда (логический адрес в буфере)
416
;bc = сколько
417
        CALL ldirinpages ;копируем в текущий адрес в буфере ;TODO разрезать на 2 части при пересечении 32К
418
        LD A,(Z6546+1) ;(Z6546) = сколько байт сохранить = текущий адрес в буфере
419
        if buf64k
420
        CP -1
421
        else
422
        CP 0x80
423
        endif
424
        CALL NC,saveblock ;save whole buffer ;буфер на [64K]32K, надо сохранить и создать новый буфер ;TODO зациклить окно
425
        POP DE
426
        POP BC
427
        JR _ZD168 ;читаем следующий код
428
 
429
;?
430
       ;DS 10
431
;какие-то стандартные длины кодов
432
;256: end of block - stop processing if last block, otherwise start processing next block.
433
;257-285: combined with extra-bits, a match length of 3-258 bytes.
434
;286, 287: not used, reserved and illegal but still part of the tree.
435
;TODO почему тут всего 19 стандартных длин, а не 28?
436
TD1EE   db #10,#11
437
        db #12,0
438
        db 8,7
439
        db 9,6
440
        db #A,5
441
        db #B,4
442
        db #C,3
443
        db #D,2
444
        db #E,1
445
        db #F ;,1 ;#F заходил на следующий сегмент, а 1 был частью TD201 ;читается максимум 19 байт, т.е. до #F включительно (в gunzip нет 1)
446
 
447
        align 256
448
         db 0 ;чтобы на 1 байт позже
449
TD201   DB 1,3,7,#F,#1F,#3F,#7F,-1 ;маски
450
;?
451
TD209  DS 34;70 ;туда пишется 32 байта (2-байтные счётчики, сколько раз встретилась каждая длина кода 0..15)
452
TD22B  ds 70-34 ;с #xx2d лежат 2-байтные начальные коды для каждой длины кода (1..15)
453
 
454
get_a_bits_tohl;ZD24F
455
        CP 9
456
        JR C,_ZD262
457
        SUB 8
458
        LD H,A
459
        LD A,8
460
        CALL get_a_bits
461
        LD L,A
462
        LD A,H
463
        CALL get_a_bits
464
        LD H,A
465
        RET
466
_ZD262  CALL get_a_bits
467
        LD H,0
468
        LD L,A
469
        RET
470
 
471
get_a_bits;ZD269
472
;a=число бит, b=число бит d в наличии, de=данные в наличии
473
;out: a=число из e (младшие биты по маске количества бит)
474
        LD (_ZD26E),A
475
        EXA
476
_ZD26E=$+1
477
        LD A,(TD201) ;a=маска 0x01,0x03,0x07...0xff (для 1,2,3...8)
478
        AND E
479
        PUSH AF
480
        EXA
481
        CALL read_a_bits
482
        POP AF
483
        RET
484
 
485
readbit_de;ZD278
486
;"читать бит" (текущие биты в de, b=число верных битов d)
487
;out: CY=вылетевший младший бит de
488
        SRL D
489
        RR E
490
        DEC B
491
        RET NZ
492
readbyte_d;ZD27E
493
;читать байт в d, установить b=8
494
;TODO макрос и без push af
495
        PUSH AF
496
        ;push HL
497
        ;push BC
498
        ;LD HL,(ZD11F)
499
        ;LD BC,#4001
500
        ;ADD HL,BC
501
        ;POP BC
502
        ;CALL C,LBLOKZIP
503
        ;LD HL,(ZD11F)
504
        ;LD D,(HL)
505
        ;INC HL
506
        ;LD (ZD11F),HL
507
        ziprdbyte
508
        ld d,a
509
        LD B,8
510
        ;POP HL
511
        pop AF
512
        RET
513
 
514
;a=число бит (бывает 8)
515
;b=число бит d в наличии
516
;de=имеющиеся данные (e - самые старые)
517
read_a_bits;ZD299
518
        CP B ;сколько бит в d
519
        JR C,_ZD2A6 ;в d достаточно бит
520
_ZD29C   SRL D
521
        RR E
522
        DEC A
523
        DJNZ _ZD29C
524
        CALL readbyte_d
525
        ;теперь в d имеется 8 бит, b=8, a уменьшено на сколько имелось бит
526
_ZD2A6  OR A
527
       RET Z ;выходим, когда прочитали нужное количество бит
528
        SRL D
529
       RR E
530
        DEC A
531
        DJNZ _ZD2A6
532
;сюда можно попасть только при a >= 8+сколько имелось бит
533
;строим деревья по умолчанию (коды 0..127 по 8 бит, 128..255 по 9 бит и т.д.)
534
;b=0
535
;a=сколько бит не хватило (может быть 0)
536
_ZD2AF   PUSH BC,DE
537
        LD HL,ziptrees ;длины кодов первого дерева?
538
        LD BC,#9008
539
_ZD2B7  LD (HL),C
540
        INC HL
541
        DJNZ _ZD2B7
542
        LD BC,#7009 ;...продолжение
543
_ZD2BE  LD (HL),C
544
        INC HL
545
        DJNZ _ZD2BE
546
        LD BC,#1807
547
_ZD2C5  LD (HL),C
548
        INC HL
549
        DJNZ _ZD2C5
550
        LD BC,#808
551
_ZD2CC  LD (HL),C
552
        INC HL
553
        DJNZ _ZD2CC
554
        LD HL,ziptrees+#140 ;длины кодов второго дерева?
555
        LD BC,#2005
556
        LD A,B ;32
557
_ZD2D7  LD (HL),C
558
        INC HL
559
        DJNZ _ZD2D7
560
        LD (ZD3C8),A ;число кодов второго дерева?
561
        LD (ZD3B8),A ;число кодов первого дерева (-256)?
562
        JP gentrees;ZD3B7 ;построить 2 дерева?
563
 
564
readtrees;ZD2E4
565
        LD A,2
566
        CALL get_a_bits ;читаем метод
567
        DEC A
568
        JP M,ZD102 ;00 = stored/raw/literal section, between 0 and 65,535 bytes in length
569
        JR Z,_ZD2AF ;01 = static Huffman compressed block, using a pre-agreed Huffman tree
570
        DEC A
571
        call NZ,depkqerror ;11 = ошибка, save whole buffer и выйти
572
;10 = compressed block complete with the Huffman table supplied
573
        LD A,5
574
        CALL get_a_bits
575
        INC A
576
        LD (ZD3B8),A ;число кодов первого дерева (-256)
577
        LD A,5
578
        CALL get_a_bits
579
        INC A
580
        LD (ZD3C8),A ;число кодов второго дерева
581
        LD HL,ziptrees+#560 ;почему сюда кладутся длины кодов??? TODO
582
        LD A,#13
583
_ZD30A  LD (HL),0
584
        INC HL
585
        DEC A
586
        JR NZ,_ZD30A
587
        LD A,4
588
        CALL get_a_bits
589
        ADD A,4 ;4..19 кодов
590
        LD C,A
591
        LD HL,TD1EE
592
_ZD31B  LD A,3
593
        CALL get_a_bits
594
        PUSH DE
595
        LD E,(HL)
596
        LD D,0
597
        PUSH HL
598
        LD HL,ziptrees+#560 ;почему сюда кладутся длины кодов??? TODO
599
        ADD HL,DE
600
        LD (HL),A
601
        POP HL,DE
602
        INC HL
603
        DEC C
604
        JR NZ,_ZD31B
605
        PUSH BC
606
        push DE
607
        LD HL,ziptrees+#160 ;там будет лежать первое дерево
608
        LD DE,ziptrees+#560 ;почему отсюда берутся длины кодов??? TODO
609
        LD BC,#13
610
        CALL gentree
611
        LD HL,(ZD3B8) ;число кодов первого дерева
612
        LD DE,(ZD3C8) ;число кодов второго дерева
613
        ADD HL,DE
614
        DEC HL
615
        POP DE
616
        pop BC
617
        LD IX,ziptrees ;длины кодов первого дерева (реально прочитаем оба (там место с запасом), потом перебросим остаток длин)
618
ZD34D   PUSH HL,DE
619
       LD D,0
620
        LD HL,ziptrees+#160 ;первое дерево
621
       ADD HL,DE
622
       ADD HL,DE
623
       LD E,(HL)
624
        LD HL,ziptrees+#560 ;длины кодов???
625
       ADD HL,DE
626
        LD A,(HL)
627
       LD C,E
628
        POP DE
629
        CALL read_a_bits
630
        LD A,C
631
        POP HL
632
        CP #10
633
        JR NC,ZD36C
634
;< #10: это будет длина кода, пишем её
635
        LD C,A ;длина кода?
636
        LD A,1 ;число повторов
637
        JR _ZD390
638
 
639
ZD36C   JR NZ,ZD37A
640
;= #10: пишем 3..6 предыдущих длин
641
        LD A,2
642
        CALL get_a_bits
643
        ADD A,3 ;число повторов
644
        LD C,(IX-1) ;длина кода?
645
        JR _ZD390
646
 
647
ZD37A   CP #11
648
        JR NZ,_ZD387
649
;= #11: пишем 3..10 длин 0
650
        LD A,3
651
        CALL get_a_bits
652
        ADD A,3
653
        JR _ZD38E
654
 
655
_ZD387
656
;> #11: пишем 11..138 длин 0
657
        LD A,7
658
        CALL get_a_bits
659
        ADD A,#B ;число повторов
660
_ZD38E  LD C,0
661
_ZD390  LD (IX),C ;длина кода
662
        INC IX
663
        DEC A
664
        DEC HL
665
        JR Z,ZD3A0
666
        BIT 7,H
667
        call NZ,depkqerror ;save whole buffer и выйти
668
        JR _ZD390
669
 
670
ZD3A0   BIT 7,H
671
        JR Z,ZD34D
672
        PUSH BC
673
        push DE
674
        LD HL,ziptrees ;длины кодов первого дерева
675
        LD DE,(ZD3B8) ;число кодов первого дерева
676
        ADD HL,DE
677
        LD DE,ziptrees+#140 ;длины кодов второго дерева
678
        LD BC,(ZD3C8) ;число кодов второго дерева
679
        LDIR ;TODO lddr и убрать запас после ziptrees, или предавать указатель на длины кодов второго дерева в gentrees
680
 
681
gentrees;ZD3B7
682
;на стеке de,bc
683
ZD3B8=$+1 ;пишется 1 байт
684
        LD BC,#100 ;число кодов первого дерева
685
        LD DE,ziptrees ;длины кодов первого дерева
686
        LD HL,ziptrees+#160 ;там будет лежать первое дерево
687
        LD IX,ziptrees+#560
688
        CALL gentree
689
ZD3C8=$+1
690
        LD BC,0 ;число кодов второго дерева ;обычно 32
691
        LD DE,ziptrees+#140 ;длины кодов второго дерева
692
        LD HL,ziptrees+#360 ;там будет лежать второе дерево
693
        LD IX,ziptrees+#9E0
694
        CALL gentree
695
        POP DE
696
        pop BC
697
        RET
698
 
699
;построение дерева
700
;de=длины кодов
701
;hl=адрес, где будет лежать дерево
702
;ix=? (записывается в (ZD523) - что-то для кодов длиннее 8)
703
;bc=число кодов = #100+(ZD3B8) для первого дерева, (ZD3C8) для второго (обычно 32)
704
gentree;ZD3DA
705
        LD A,B
706
        OR C
707
        RET Z
708
        LD (ZD443),BC ;число кодов
709
        LD (ZD4A9),HL
710
 
711
;очищаем, сколько раз встретились коды каждой длины (0..15)
712
        LD HL,TD209
713
        PUSH HL
714
        push BC
715
        LD BC,#2000
716
_ZD3EC  LD (HL),C;0
717
        INC HL
718
        DJNZ _ZD3EC
719
        POP BC
720
        pop HL
721
 
722
        PUSH DE ;длины кодов
723
 
724
;считаем, сколько раз встретились коды каждой длины (0..15)
725
_ZD3F3  LD A,(DE)
726
        INC DE
727
        ADD A,A
728
         ADD A,9 ;TD209
729
         LD L,A
730
        INC (HL)
731
        JR NZ,_ZD3FE
732
        INC HL
733
        INC (HL)
734
_ZD3FE  DEC BC
735
        LD A,B
736
        OR C
737
        JR NZ,_ZD3F3
738
;теперь в TD209 лежат 2-байтные значения, сколько раз встретились коды каждой длины (0..15)
739
 
740
       LD L,#2D ;TD22B+2
741
       LD (HL),C;0
742
       INC HL
743
       LD (HL),C;0 ;начальный код для длины 1 ;TODO ld (TD22B+2),bc
744
 
745
         PUSH BC;0 ;текущий код?
746
 
747
        LD BC,#F02 ;перебираем длины кодов 1..15
748
_ZD40C  LD A,C ;длина кода*2
749
         ADD A,9 ;TD209
750
         LD L,A
751
        LD E,(HL)
752
        INC HL
753
        LD D,(HL) ;de=сколько раз встретилась эта длина кода
754
         EX (SP),HL
755
        ADD HL,DE
756
        ADD HL,HL
757
        LD E,L
758
        LD D,H ;какой-то магией формируем текущий код из предыдущего
759
         EX (SP),HL
760
        INC C
761
        INC C
762
        LD A,C
763
         ADD A,#2B ;TD22B
764
         LD L,A
765
        LD (HL),E
766
        INC HL
767
        LD (HL),D ;начальный код для заданной длины кода
768
        DJNZ _ZD40C
769
 
770
         POP DE ;текущий код?
771
 
772
        LD A,D
773
        OR E
774
        JR Z,ZD440 ;последний начальный код должен получиться 0 (т.е. все варианты в бинарном дереве использованы)
775
;ошибочное дерево?
776
       LD D,B
777
       LD E,B;de=0
778
        LD A,#F
779
         LD L,#B ;TD209+2
780
_ZD42F  LD C,(HL)
781
        INC HL
782
        LD B,(HL) ;сколько раз встретился код этой длины
783
        INC HL
784
        EX DE,HL
785
        ADD HL,BC
786
        EX DE,HL
787
        DEC A
788
        JR NZ,_ZD42F
789
;de=количество ненулевых длин кодов -2
790
       LD HL,-2
791
       ADD HL,DE
792
        call C,depkqerror ;если кодов более 1, save whole buffer и выйти (ошибочное дерево? в архиве с адвентюрерами - на каждом большом файле)
793
;всего 1 код используется - считаем, что не ошибка, что не получилось построить дерево из 1 кода?
794
ZD440  
795
        POP DE ;длины кодов
796
        PUSH DE ;длины кодов
797
 
798
ZD443=$+1
799
        LD BC,0 ;число кодов
800
 
801
        LD HL,ziptrees+#A60 ;сюда положим все коды по 2 байта на код
802
_ZD448  LD A,(DE) ;длина кода
803
        INC DE
804
        PUSH DE
805
        ADD A,A
806
        LD E,A
807
        LD D,A
808
        JR Z,__ZD45F ;длина кода=de=0
809
;берём код номер "длина кода" в de (и инкрементируем его там, где он лежал)
810
        PUSH HL
811
       LD H,TD209/256;UD2
812
       ADD A,#2B ;TD22B
813
        LD L,A
814
        LD E,(HL)
815
        INC HL
816
        LD D,(HL)
817
        INC DE
818
        LD (HL),D
819
        DEC HL
820
        LD (HL),E
821
        DEC DE
822
        POP HL
823
__ZD45F LD (HL),E
824
        INC HL
825
        LD (HL),D
826
        INC HL
827
        POP DE
828
        DEC BC
829
        LD A,C
830
        OR B
831
        JR NZ,_ZD448
832
 
833
        POP DE ;длины кодов
834
        PUSH DE ;длины кодов
835
 
836
        LD HL,ziptrees+#A60 ;все коды по 2 байта на код
837
        LD BC,(ZD443) ;число кодов
838
_ZD472  LD A,(DE)
839
        INC DE
840
        DEC A
841
        JP M,_ZD4A1 ;код длиной 0 (неиспользуемый) - пропускаем
842
        JR Z,_ZD4A1 ;код длиной 1 - пропускаем
843
        PUSH DE
844
        LD E,(HL)
845
        INC HL
846
        LD D,(HL) ;берём код
847
        PUSH HL
848
        LD HL,0
849
;начинаем переворачивать код, сначала длинакода-1 битиков:
850
_ZD482  SRL D
851
        RR E
852
        ADC HL,HL
853
       EXA
854
        LD A,D
855
        OR E
856
        JR Z,_ZD493 ;код кончился
857
       EXA
858
        DEC A
859
        JR NZ,_ZD482
860
        INC A ;a=1: сдвинем потом ещё на 1 битик
861
       EXA
862
_ZD493 EXA
863
;сдвинем на несколько оставшихся битиков:
864
        RR E
865
_ZD496  ADC HL,HL
866
        DEC A
867
        JR NZ,_ZD496
868
        EX DE,HL
869
        POP HL
870
        LD (HL),D
871
        DEC HL
872
        LD (HL),E ;записали перевёрнутый код
873
        POP DE
874
_ZD4A1  INC HL
875
        INC HL
876
        DEC BC
877
        LD A,C
878
        OR B
879
        JR NZ,_ZD472
880
 
881
ZD4A9=$+1
882
        LD HL,0 ;адрес дерева
883
        LD E,L
884
        LD D,H
885
        INC DE
886
        LD BC,#1FF
887
        LD (HL),A;0
888
        LDIR ;очистили 512 байт (TODO почему не больше? литералов может быть больше 256!)
889
 
890
        POP HL ;длины кодов
891
 
892
        LD BC,(ZD443) ;число кодов
893
        DEC BC
894
        ADD HL,BC
895
        EX DE,HL ;de=указатель на длину последнего кода
896
 
897
        LD (ZD523),IX ;какой-то адрес для кодов длиннее 8
898
 
899
        LD HL,ziptrees+#A60+1 ;все коды по 2 байта на код (уже перевёрнутые)
900
        ADD HL,BC
901
        ADD HL,BC ;указатель на последний байт последнего кода
902
;генерируем дерево:
903
_ZD4C5  
904
;bc=литерал
905
        LD A,(DE)
906
        DEC DE
907
        OR A
908
        JR Z,_ZD503 ;код длиной 0 (неиспользуемый) - пропускаем
909
        CP 9
910
        PUSH DE
911
        LD D,(HL)
912
        DEC HL
913
        LD E,(HL) ;de=код
914
         INC HL
915
        PUSH HL ;TODO выше
916
        JR NC,_ZD50B ;код не умещается в 1 байт - используем буфер ix+...
917
;код умещается в 1 байт
918
        LD HL,1
919
        INC A ;1..9
920
_ZD4D8  ADD HL,HL
921
        DEC A
922
        JR NZ,_ZD4D8
923
        EX DE,HL ;de=1<<(1..9)
924
        ADD HL,HL ;код*2
925
        LD A,(ZD4A9) ;адрес дерева
926
        ADD A,L
927
        LD L,A
928
        LD (__ZD4FE),A ;это и...
929
        LD A,(ZD4A9+1)
930
        ADC A,H
931
        LD H,A
932
       INC A,A
933
        LD (__ZD4F7),A ;...это задаёт адрес выхода (адрес дерева + код*2 + 512)
934
        DEC DE
935
;кладём литерал в дерево
936
_ZD4F1  LD (HL),C
937
        INC HL
938
        LD (HL),B ;кладём литерал
939
        ADD HL,DE ;какой-то магией находим следующий адрес (адрес литерала + код*2)
940
         LD A,H
941
__ZD4F7=$+1
942
         CP 0
943
         JR C,_ZD4F1
944
         JR NZ,_ZD501
945
         LD A,L
946
__ZD4FE=$+1
947
         CP 0
948
        JR C,_ZD4F1 ;пока не дошли до адреса выхода, кладём этот литерал (TODO зачем много раз???)
949
_ZD501
950
        POP HL,DE
951
_ZD503
952
        DEC HL
953
        DEC HL ;предыдущий код
954
        DEC BC ;предыдущий литерал
955
        BIT 7,B
956
        JR Z,_ZD4C5
957
        RET
958
 
959
_ZD50B
960
;код не умещается в 1 байт - используем буфер ix+...
961
;a=длина кода
962
;de=код
963
        SUB 8
964
        PUSH BC ;литерал
965
        LD B,A ;длина кода-8
966
        LD A,D
967
        LD D,0
968
        LD HL,(ZD4A9) ;адрес дерева
969
        ADD HL,DE
970
        ADD HL,DE
971
        LD C,1 ;некий бит для проверки старшего байта кода
972
        EXA
973
_ZD51A  LD E,(HL)
974
        INC HL
975
        LD D,(HL) ;берём литерал из дерева по смещению 2*(код-256) (или адрес ix+... после прохода - см. ниже)
976
        DEC HL
977
        LD A,D
978
        OR E
979
        JR NZ,_ZD535 ;литерал уже заполнен!
980
;нулевой литерал (ещё не заполненный)
981
ZD523=$+1
982
        LD DE,0 ;сначала туда клали ix
983
        LD (HL),E
984
        INC HL
985
        LD (HL),D ;кладём этот адрес в дерево на место ещё не заполненного литерала
986
       LD H,D
987
       LD L,E
988
       LD (HL),A;0
989
       INC HL
990
       LD (HL),A;0
991
       INC HL
992
       LD (HL),A;0
993
       INC HL
994
       LD (HL),A;0 ;и кладём 4 нуля по этому адресу (на следующем проходе можем использовать первые два или последние два нуля, чтобы положить туда адрес литерала или литерал)
995
       INC HL
996
       LD (ZD523),HL ;обновляем бывший ix
997
_ZD535
998
        EX DE,HL ;hl=адрес = ix+... (или уже заполненный литерал)
999
        EXA
1000
        LD E,A ;старший байт кода
1001
        AND C ;проверяем некий бит
1002
        LD A,E ;старший байт кода
1003
        JR Z,_ZD53E
1004
        INC HL,HL ;если установлен, то адрес+2 (TODO а если это был литерал???)
1005
_ZD53E  EXA
1006
        SLA C ;сдвигаем некий бит
1007
        DJNZ _ZD51A ;попробуем следующий адрес или ещё раз этот же (TODO а что если это был литерал, а не ix+..., а битик не совпал - повторим с тем же адресом???)
1008
        POP BC
1009
        LD (HL),C
1010
        INC HL
1011
        LD (HL),B ;кладём литерал
1012
        JR _ZD501 ;конец текущего кода
1013
 
1014
readcodetree1;ZD549
1015
;de=имеющиеся данные
1016
;out: hl=code
1017
        PUSH DE
1018
        XOR A
1019
        LD D,A
1020
        LD HL,ziptrees+#160+1 ;тут лежит первое дерево
1021
        ADD HL,DE
1022
        ADD HL,DE ;hl=адрес второго байта кода номер e в дереве
1023
        OR (HL)
1024
        DEC HL
1025
        LD L,(HL)
1026
        LD H,A
1027
         if ziptrees>=0x8000
1028
         else
1029
         add a,a
1030
         endif
1031
        JP M,_ZD58C ;h bit 6 значит дерево, иначе hl=литерал
1032
         PUSH HL
1033
         LD DE,ziptrees ;длины кодов первого дерева???
1034
         ADD HL,DE
1035
         LD A,(HL) ;длина добавки кода для имеющегося hl???
1036
         POP HL
1037
         pop DE
1038
_ZD560
1039
;256: end of block - stop processing if last block, otherwise start processing next block.
1040
;257-285: combined with extra-bits, a match length of 3-258 bytes.
1041
;286, 287: not used, reserved and illegal but still part of the tree.
1042
        CALL read_a_bits
1043
        LD A,H
1044
        OR A
1045
        RET Z
1046
        LD A,L
1047
        CP 9
1048
        RET C
1049
        CP #1D
1050
        LD HL,#200
1051
        RET Z
1052
        DEC A
1053
        LD C,A
1054
        SRL C
1055
        SRL C
1056
        DEC C
1057
        AND 3
1058
        ADD A,4
1059
        LD H,L
1060
        LD L,A
1061
        LD A,C
1062
_ZD57E   ADD HL,HL
1063
        DEC C
1064
        JR NZ,_ZD57E
1065
        INC H
1066
        CALL get_a_bits
1067
        INC A
1068
        ADD A,L
1069
        LD L,A
1070
        RET NC
1071
        INC H
1072
        RET
1073
 
1074
_ZD58C  POP DE
1075
        CALL ZD5CB ;читать 8 бит и пройти по ним дерево hl
1076
        JR _ZD560
1077
 
1078
readcodetree2;ZD592
1079
;de=имеющиеся данные
1080
;out: hl=code
1081
;The distance tree contains space for 32 symbols:
1082
;0-3: distances 1-4
1083
;4-5: distances 5-8, 1 extra bit
1084
;6-7: distances 9-16, 2 extra bits
1085
;8-9: distances 17-32, 3 extra bits
1086
;...
1087
;26-27: distances 8,193-16,384, 12 extra bits
1088
;28-29: distances 16,385-32,768, 13 extra bits
1089
;30-31: not used, reserved and illegal but still part of the tree.
1090
;Note that for the match distance symbols 2-29, the number of extra bits can be calculated as [n/2]-1.
1091
        PUSH DE
1092
        XOR A
1093
        LD D,A
1094
        LD HL,ziptrees+#360+1
1095
        ADD HL,DE
1096
        ADD HL,DE
1097
        OR (HL)
1098
        DEC HL
1099
        LD L,(HL)
1100
        LD H,A ;h bit 6 значит дерево, иначе hl=литерал
1101
         if ziptrees>=0x8000
1102
         else
1103
         add a,a
1104
         endif
1105
        JP M,_ZD5C5 ;читать 8 бит и пройти по ним дерево hl
1106
         PUSH HL
1107
         LD DE,ziptrees+#140 ;длины кодов второго дерева???
1108
         ADD HL,DE
1109
         LD A,(HL) ;длина добавки кода для имеющегося hl???
1110
         POP HL,DE
1111
_ZD5A9  CALL read_a_bits ;дочитываем столько бит, сколько прошагали?
1112
        LD A,L ;литерал
1113
        CP 4
1114
        RET C
1115
        RRA
1116
        DEC A
1117
        LD C,A
1118
        LD L,H
1119
        RL L
1120
        INC L,L
1121
ZD5B8   ADD HL,HL
1122
        DEC C
1123
        JR NZ,ZD5B8
1124
        PUSH HL
1125
        CALL get_a_bits_tohl
1126
        EX DE,HL
1127
        EX (SP),HL
1128
        ADD HL,DE
1129
        POP DE
1130
        RET
1131
 
1132
_ZD5C5   POP DE
1133
        CALL ZD5CB ;читать 8 бит и пройти по ним дерево hl
1134
        JR _ZD5A9
1135
 
1136
ZD5CB
1137
;читать 8 бит и пройти по ним дерево hl
1138
;out: a=сколько бит реально прошагали, l=литерал?
1139
        LD A,8
1140
        CALL read_a_bits
1141
        LD C,E ;эквивалентно ld a,8:call get_a_bits:ld c,a ?
1142
;ходим по дереву hl, имея код C (младшие биты сначала)
1143
        XOR A
1144
ZD5D2   INC A
1145
        RR C
1146
        JR NC,ZD5D9
1147
        INC HL
1148
        inc HL
1149
ZD5D9   LD (ZD5DD),HL
1150
ZD5DD=$+1
555 alone 1151
        LD HL,(0) ;ok
344 alone 1152
         if ziptrees>=0x8000
1153
         BIT 7,H
1154
         else
1155
         BIT 6,H ;h bit 6 значит дерево, иначе l=литерал
1156
         endif
1157
        JR NZ,ZD5D2
1158
        RET
1159
 
1160
;       ENT 
1161
 
1162
;END_DEP=$ 
1163
 
1164
U6546=Z6546 ;сколько байт сохранить = текущий адрес в буфере
1165
 
1166