?login_element?

Subversion Repositories NedoOS

Rev

Rev 344 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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
  1151.         LD HL,(0) ;ok
  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.  
  1167.