;LAST UPDATE: 03.02.2014 savelij
maintree EQU RARS
tree EQU (298-6)*4-4+maintree
bdlens EQU tree
ldlens EQU tree
ddlens EQU 298+ldlens
;rdlens=ddlens+48
tabend EQU ddlens+48+28
NEWBYTE
LD A,(IX)
RLA
INC IX
RET
dPPbr16
PUSH BC
JR NZ,dPPn16
;16=prev len copies-3
CALL LDA2
DEC HL
LD A,(HL)
INC HL
LD (dPPdupV),A
LD A,3
JR dPPfil
UNILDRAR
ADD HL,DE
LD (theEnd),HL;сам HL не нужен!
;IX->DE
LD A,128
EX AF,AF'
NEWTREE
PUSH DE
CALL LDA2
LD HL,bdlens
LD E,19
dPPtetr LD B,4
CALL LDA18B
LD (HL),C
INC HL
DEC E
JR NZ,dPPtetr
;EXX
;PUSH DE
LD DE,19+1
CALL MKMAINTREE ;делаем из них дерево
;POP DE
;EXX
LD BC,298+48+28 ;tabsize
LD HL,ldlens;UnpOldTable
dPP0 PUSH HL
CALL DEHUFFMAIN
POP HL
CP 16
JR NC,dPPbr16
;<16 delta from prev codelen tab
LD (HL),A
INC HL
DEC BC
JR dPPQ
dPPn16 CP 17
JR NZ,dPPn3b
;17=zerolens-3
LD B,3
LD A,B
dPPfilG CALL LDA18B
dPPfil ADD A,C
POP BC
dPPdupV := $+1
dPPdup0 LD (HL),0
INC HL
DEC BC
DEC A
JR NZ,dPPdup0
LD (dPPdupV),A
dPPQ LD A,B
OR C
JR NZ,dPP0
;EXX
;PUSH DE
LD DE,298+1
CALL MKMAINTREE ;делаем из них дерево
LD HL,ddlens+49
LD DE,48+1
LD BC,tree
CALL MKTREE ;делаем из них дерево
POP DE
;EXX
DEPK0
CALL DEHUFFMAIN
DEC H
JR NZ,yBYTE
SUB LOW (269)
JR Z,NEWTREE
JR C,len2
DEC A
;SUB 270
LD L,A
CP 8
CALL NC,EMMTPP
REPT 3
INC HL
ENDM
PUSH HL ;len
LD HL,tree
CALL DEHUFF
ADD A,-4
JR NC,EMBBTQ
LD L,1
ADC A,L
RRA
RL L
LD B,A
CALL EM_TPP
EMBBTQ INC HL
;NC
LD B,H
LD C,L
GPldir LD C,L
LD H,D
LD L,E
;OR A
SBC HL,BC
LD A,B
POP BC ;3..255
AND 0XE0
JR Z,$+3
INC C
;CALL UNILDIR
LDIR
GPq
;или просто BIT 7,D
theEnd := $+1
LD HL,0
SCF
SBC HL,DE
;LD A,H ;!
;ADD A,2;!
JR NC,DEPK0
RET
;LD A,(UNIpg)
;JP OUTME
;18=zerolens-11
dPPn3b
LD B,7
LD A,11
JR dPPfilG
yBYTE
LD A,L
LD (DE),A
INC DE
JR GPq
len2
;261..268=>-8..-1
ADD A,A
LD L,A
LD H,HIGH (tlen2);'tlen2
LD B,(HL) ;bits
INC L
LD L,(HL) ;N>>bits
CALL EM_TPP
LD C,2
PUSH BC
;CY
JR GPldir
DEHUFFMAIN
LD HL,maintree
DEHUFF
EX AF,AF'
ADD A,A
CALL Z,NEWBYTE
JR NC,$+4 ;ноль
INC L ;единица
INC L;HL
EX AF,AF'
LD A,(HL)
INC L
LD H,(HL)
LD L,A
IF LOW (maintree&0X40)=0; IFN 'maintree&0X40
BIT 6,H
ELSE
IF LOW (maintree&0X80)=0; IFN 'maintree&0X80
BIT 7,H
ENDIF
ENDIF
JR NZ,DEHUFF
RET
;создание дерева. нули - более короткие ветки
;сначала создаются все ветки для
;символов с bitlen=1, потом 2 и т.д. до 15
;by Roman Petrov
MKMAINTREE
LD HL,ldlens ;было просто tree
ADD HL,DE
LD BC,maintree
MKTREE
PUSH BC
EXX
POP DE ;начало буфера
LD H,D
LD L,E
XOR A ;=0 признак выхода
PUSH AF
INC A ;=1
PUSH HL
PUSH AF
LD C,A
MKTREE0 EXX ;HL=кон.bitlens+1
LD B,D
LD C,E
;ADD HL,BC;указ.на последний bitlen
;OR A
SBC HL,BC;указ.на 1й bitlen
EXX
MKTREE1 LD B,A
LD A,C
EXX
;CPDR ;BC=число листьев+1
CPIR
LD A,B
OR C
EXX
LD A,B
JR NZ,MKTREEY;найден символ с таким bitlen
INC C ;не найден такой символ
JR NZ,MKTREE0
JR MTREEbug
MKTREE_DEEPER
INC DE ;новое место
INC DE ;для
INC DE ;новых
INC DE ;узлов
LD (HL),E
INC HL
LD (HL),D ;указатель для "0"
LD H,D
LD L,E ;адрес для "код+0"
INC A ;длина этого кода
PUSH HL ;заносим это
PUSH AF ;в стек
MKTREEY CP C
JR NZ,MKTREE_DEEPER ;пока не углубимся до нужной длины
;A=C
EXX
PUSH BC ;антиномер литерала+1
PUSH DE ;Q+1
EXX
MTREEbug
LD (MKhl),HL
POP HL
POP BC
;DEC BC ;номер литерала
;LD (HL),C
;INC HL
;LD (HL),B ;формируем лист
SCF
SBC HL,BC
MKhl := $+1
LD (0),HL
LD C,A
POP AF
RET Z ;=0 признак выхода
POP HL
INC HL
INC HL ;следующий свободный узел
;A=его глубина
;DE=адрес места для новых узлов
JR MKTREE1
EMMTPP
LD B,A
AND 3
OR 4
LD L,A
SRL B
SRL B
DEC B
EM_TPP EX AF,AF'
MLEN0 ADD A,A
CALL Z,NEWBYTE
ADC HL,HL
DJNZ MLEN0
EX AF,AF'
RET
LDA2 LD A,2
LDA
CP 9
JR NC,LDA915
LDA18 LD B,A
LDA18B
LD C,0
EX AF,AF'
LDA0 ADD A,A
CALL Z,NEWBYTE
RL C
DJNZ LDA0
EX AF,AF'
RET
LDA915
SUB 8
CALL LDA18
LD A,C
LD B,8
CALL LDA0-1
LD B,A
RET
; DISPLAY $
DUPL (HIGH ($)<<8)+0XF0-$,0; DUPL $+15/256<8+0XF0-$,0
; DISPLAY "=",$
tlen2
DB 2,0>>2
DB 2,4>>2
DB 3,8>>3
DB 4,16>>4
DB 5,32>>5
DB 6,64>>6
DB 6,128>>6
DB 6,192>>6