home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 25 / CD_ASCQ_25_1095.iso / dos / prg / cpe50 / comp386.asm next >
Assembly Source File  |  1995-05-09  |  24KB  |  1,014 lines

  1.  
  2. ; ************************************
  3. ; * Compressor/decompressor routines *
  4. ; * 386+ version                     *
  5. ; ************************************
  6.  
  7. ; the algorithm is my own invention except for the huffman part.
  8.  
  9. ; * NEVER compress/decompress more than 32K of data!
  10. ; * leave about 33000 bytes in destination buffer!
  11.  
  12. IDEAL
  13. P386
  14.  
  15. PUBLIC PackArea,UnpackArea
  16. PUBLIC PasPack,PasUnpack
  17.  
  18. SEGMENT packer_text PAGE PUBLIC 'CODE'
  19. ASSUME CS:packer_text
  20. ASSUME FS:packer_data
  21.  
  22. MAX_VAL EQU     103h
  23.  
  24. PasPack:
  25.         PUSH    BP
  26.         MOV     BP,SP
  27.         PUSH    DS
  28.         LDS     SI,[BP+12]
  29.         LES     DI,[BP+8]
  30.         MOV     CX,[BP+6]
  31.         CALL    FAR PackArea
  32.         POP     DS
  33.         POP     BP
  34.         RETF
  35.  
  36. PasUnpack:
  37.         PUSH    BP
  38.         MOV     BP,SP
  39.         PUSH    DS
  40.         LDS     SI,[BP+12]
  41.         LES     DI,[BP+8]
  42.         MOV     CX,[BP+6]
  43.         CALL    FAR UnpackArea
  44.         POP     DS
  45.         POP     BP
  46.         RETF
  47.  
  48. PackArea:          ; IN: DS:SI area to be packed, ES:DI dest buffer,
  49.                    ;     at least same size+10. Restrict data size to 32KB!
  50.                    ;     CX length
  51.                    ; returns packed len + headersize in AX
  52.         PUSH    FS
  53.         MOV     AX,SEG bitpos
  54.         MOV     FS,AX
  55.  
  56.         CALL    Initialize
  57.         CALL    FindRepetitions
  58.         OR      AX,AX           ; no length? strange...
  59.         JE      PARE_HuffSrcOK
  60.         MOV     DX,CX
  61.         MOV     CX,AX
  62.         MOV     SI,OFFSET tempbuf
  63.         MOV     AX,SEG tempbuf
  64.         MOV     DS,AX
  65. PARE_HuffSrcOK:
  66.         PUSH    DI
  67.         PUSh    DX
  68.         ADD     DI,12
  69.         CALL    EncodeHuffman
  70.         POP     DX
  71.         POP     DI
  72.         MOV     AX,'RC'
  73.         STOSW
  74.         MOV     AX,'XU'
  75.         STOSW
  76.         MOV     AX,'AP'
  77.         STOSW
  78.         MOV     AX,'KC'
  79.         STOSW
  80.         MOV     AX,[pckflg]
  81.         STOSW
  82.         MOV     AX,DX
  83.         STOSW
  84.         MOV     AX,CX
  85.         ADD     AX,12           ; add header size
  86. PARE_End:
  87.         POP     FS
  88.         RETF
  89.  
  90. FindRepetitions:                    ; pack method 1, to tempbuf
  91.         PUSH    ES                  ; returns packed length
  92.         PUSH    DI
  93.         PUSH    SI
  94.         PUSH    CX
  95.  
  96.         PUSH    SEG tempbuf
  97.         POP     ES
  98.         MOV     DI,OFFSET tempbuf
  99.         XOR     DX,DX
  100.         XOR     BX,BX
  101. FREP_Loop:
  102.         MOV     EAX,[SI]
  103.         INC     SI
  104.         DEC     BX
  105.         CMP     CX,6
  106.         JC      FREP_Writeback
  107.  
  108.         CALL    FREP_FindEqual
  109.  
  110.         CMP     [relpos],0
  111.         JE      FREP_Writeback
  112.         MOV     AL,255
  113.         CALL    WriteToTemp
  114.         XOR     AL,AL
  115.         CMP     [relpos],0feffh
  116.         RCL     AL,1
  117.         CMP     [rellen],260
  118.         RCL     AL,1
  119.         XOR     AL,1
  120.         CALL    WriteToTemp
  121.         MOV     AX,[relpos]
  122.         INC     AX
  123.         CALL    WriteToTemp
  124.         MOV     AL,AH
  125.         CMP     AL,0ffh
  126.         JE      FREP_FE_RelB
  127.         CALL    WriteToTemp
  128. FREP_FE_RelB:
  129.         MOV     AX,[rellen]
  130.         SUB     AX,4
  131.         CALL    WriteToTemp
  132.         MOV     AL,AH
  133.         OR      AL,AL
  134.         JE      FREP_FE_SequenceOK
  135.         CALL    WriteToTemp
  136. FREP_FE_SequenceOK:
  137.         MOV     BP,[rellen]
  138.         DEC     BP                      ; one increment already done by
  139.         SUB     CX,BP                   ; LODSB etc.
  140.         ADD     SI,BP
  141.         SUB     BX,BP
  142.         JMP     FREP_LoopEnd
  143. FREP_Writeback:
  144.         CALL    WriteToTemp
  145.         CMP     AL,0ffh
  146.         JNE     FREP_LoopEnd
  147.         CALL    WriteToTemp
  148. FREP_LoopEnd:
  149.         LOOP    FREP_Loop
  150.         XOR     AX,AX
  151.         CMP     DX,33000
  152.         JNC     FREP_End
  153.         OR      [pckflg],1
  154.         MOV     AX,DX
  155. FREP_End:
  156.         POP     CX
  157.         POP     SI
  158.         POP     DI
  159.         POP     ES
  160.         RET
  161.  
  162. FREP_FindEqual:
  163.         MOV     [relpos],0       ; check if sequence occurred before
  164.         MOV     [rellen],0       ; search for best occurrence!
  165.         MOV     [relsave],0      ; in BX: max neg offset
  166.         PUSH    DI
  167.         PUSH    ES
  168.         PUSH    BX
  169.         PUSH    CX
  170.         PUSH    DS
  171.         POP     ES
  172.  
  173.         MOV     BP,CX
  174.         XCHG    BX,CX
  175.         MOV     BX,0ffffh
  176. FREP_FE_OffLoop:
  177.         DEC     BX
  178.         CMP     BX,0fffah
  179.         JE      FREP_FE_End
  180.         CMP     BX,CX
  181.         JC      FREP_FE_End
  182.         PUSH    BX
  183.         MOV     DI,SI
  184.         ADD     DI,BX
  185.         PUSH    CX
  186.         NEG     CX
  187.         ADD     CX,BX
  188.         SHR     CX,2
  189.         INC     CX
  190.         MOV     BX,SI
  191. FREP_FE_Loop:
  192.         JCXZ    FREP_FE_LoopEnd
  193.         STD
  194.         REPNE   SCASD
  195.         CLD
  196.         CMP     EAX,[DI+4]
  197.         JNE     FREP_FE_LoopEnd
  198.         PUSH    BX
  199.         SUB     BX,DI
  200.         SUB     BX,4
  201.         NEG     BX
  202.         CALL    FREP_GetSequenceLen
  203.         POP     BX
  204.         JMP     FREP_FE_Loop
  205. FREP_FE_LoopEnd:
  206.         POP     CX
  207.         POP     BX
  208.         JMP     FREP_FE_OffLoop
  209. FREP_FE_End:
  210.         POP     CX
  211.         POP     BX
  212.         POP     ES
  213.         POP     DI
  214.         RET
  215.  
  216. FREP_GetSequenceLen:         ; in: DI+4: start of repetition; SI-1: thisbyte
  217.         PUSH    DX           ; BX: rel pos of DI
  218.         PUSH    CX
  219.         PUSH    SI
  220.         PUSH    DI
  221.  
  222.         ADD     DI,5
  223.         MOV     CX,BP
  224.         REPE    CMPSB
  225.         NEG     CX
  226.         ADD     CX,BP
  227.         MOV     DX,CX
  228.         CMP     BX,0feffh
  229.         SBB     DX,4
  230.         JC      FREP_FE_TooShort
  231.         CMP     DX,[relsave]
  232.         JC      FREP_FE_TooShort
  233.         MOV     [relsave],DX
  234.         MOV     [relpos],BX
  235.         MOV     [rellen],CX
  236. FREP_FE_TooShort:
  237.         POP     DI
  238.         POP     SI
  239.         POP     CX
  240.         POP     DX
  241.         RET
  242.  
  243. WriteToTemp:
  244.         CMP     DX,33000
  245.         JNC     WTOT_Ret
  246.         INC     DX
  247.         STOSB
  248. WTOT_Ret:
  249.         RET
  250.  
  251. EncodeHuffman:                          ; DS:SI, ES:DI, CX: unpacked len
  252.         PUSH    DX                      ; DX: max packed len
  253.         PUSH    SI                      ; returns packed len in CX
  254.         PUSH    DI                      ; and modifies pckflg
  255.         MOV     [huffuplen],CX
  256.  
  257.         CALL    CountBytes
  258.         CALL    GenTrie
  259.         CALL    CalcLengths
  260.         CALL    MakeCodes
  261.         CALL    WriteCodes
  262.  
  263.         CMP     [Fault],0
  264.         JE      ECOH_StartEncoding
  265.         JMP     ECOH_Ooops
  266. ECOH_StartEncoding:
  267.         XOR     BX,BX
  268.         MOV     [bitpos],0
  269. ECOH_Loop:
  270.         XOR     AH,AH
  271.         LODSB
  272.         TEST    [pckflg],1
  273.         JZ      ECOH_NormByte
  274.         CMP     AL,255
  275.         JNE     ECOH_NormByte
  276.         LODSB
  277.         DEC     CX
  278.         CMP     AL,255
  279.         JE      ECOH_NormByte
  280.         MOV     AH,1
  281.         PUSH    AX
  282.         CALL    EncodeByte
  283.         POP     AX
  284.         XOR     BP,BP
  285.         RCR     AL,1
  286.         ADC     BP,1
  287.         RCR     AL,1
  288.         ADC     BP,1
  289. ECOH_ForceNorm:
  290.         XOR     AH,AH
  291.         LODSB
  292.         CALL    EncodeByte
  293.         DEC     CX
  294.         DEC     BP
  295.         JNE     ECOH_ForceNorm
  296.         JMP     ECOH_LoopEnd
  297. ECOH_NormByte:
  298.         CALL    EncodeByte
  299.  
  300. ECOH_LoopEnd:
  301.         CMP     [Fault],0
  302.         JNE     ECOH_Ooops
  303.         LOOP    ECOH_Loop
  304.         CALL    WriteLastHuffman
  305.         OR      [pckflg],80h
  306.         JMP     ECOH_Ret
  307. ECOH_Ooops:
  308.         POP     DI
  309.         POP     SI
  310.         POP     CX
  311.         MOV     CX,[huffuplen]
  312.         PUSH    CX
  313.         PUSH    SI
  314.         PUSH    DI
  315.         REP     MOVSB
  316.         XOR     DX,DX
  317. ECOH_Ret:
  318.         POP     DI
  319.         POP     SI
  320.         POP     CX
  321.         SUB     CX,DX
  322.         RET
  323.  
  324. EncodeByte:
  325.         PUSH    SI
  326.         PUSH    DS
  327.         PUSH    CX
  328.  
  329.         MOV     SI,SEG pckflg
  330.         MOV     DS,SI
  331.         MOV     SI,OFFSET code
  332.         ADD     SI,AX
  333.         ADD     SI,AX
  334.         MOV     AX,[SI]
  335.         MOV     CX,[bitpos]
  336.         PUSH    AX
  337.         SHR     AX,CL
  338.         OR      BX,AX
  339.         POP     AX
  340.         SUB     SI,OFFSET code
  341.         ADD     SI,OFFSET colen
  342.         ADD     CX,[SI]
  343.         CMP     CX,16
  344.         JC      ECOB_BitLenOK
  345.         MOV     [ES:DI],BH
  346.         MOV     [ES:DI+1],BL
  347.         ADD     DI,2
  348.         SUB     DX,2
  349.         CMP     DX,2
  350.         JC      ECOB_Fault
  351.         SUB     CX,[SI]
  352.         NEG     CX
  353.         ADD     CX,16
  354.         SHL     AX,CL
  355.         MOV     BX,AX
  356.         NEG     CX
  357.         ADD     CX,[SI]
  358.         AND     CX,15
  359.         JMP     ECOB_BitLenOK
  360. ECOB_Fault:
  361.         MOV     [Fault],1
  362. ECOB_BitLenOK:
  363.         MOV     [bitpos],CX
  364.  
  365.         POP     CX
  366.         POP     DS
  367.         POP     SI
  368.         RET
  369.  
  370. WriteLastHuffman:
  371.         PUSH    DS
  372.         MOV     AX,SEG bitpos
  373.         MOV     DS,AX
  374.         CMP     [bitpos],0
  375.         JE      WLHU_Ret
  376.         MOV     AL,BH
  377.         STOSB
  378.         DEC     DX
  379.         CMP     [bitpos],8
  380.         JC      WLHU_Ret
  381.         MOV     AL,BL
  382.         STOSB
  383.         DEC     DX
  384. WLHU_Ret:
  385.         POP     DS
  386.         RET
  387.  
  388. CountBytes:
  389.         PUSH    ES
  390.         PUSH    SI
  391.         PUSH    CX
  392.         PUSH    DX
  393.         MOV     AX,SEG tempbuf
  394.         MOV     ES,AX
  395. COBY_Loop:
  396.         XOR     AH,AH
  397.         LODSB
  398.         TEST    [pckflg],1
  399.         JZ      COBY_NormByte
  400.         CMP     AL,255
  401.         JNE     COBY_NormByte
  402.         LODSB
  403.         CMP     AL,255
  404.         JE      COBY_NormByte
  405.         MOV     AH,1
  406.         MOV     BX,OFFSET bytecnt
  407.         ADD     BX,AX
  408.         ADD     BX,AX
  409.         INC     [WORD PTR BX]
  410.         XOR     DX,DX
  411.         RCR     AL,1
  412.         ADC     DX,1
  413.         RCR     AL,1
  414.         ADC     DX,1
  415.         XOR     AH,AH
  416. COBY_ForceNorm:
  417.         LODSB
  418.         MOV     BX,OFFSET bytecnt
  419.         ADD     BX,AX
  420.         ADD     BX,AX
  421.         INC     [WORD PTR BX]
  422.         DEC     CX
  423.         DEC     DX
  424.         JNE     COBY_ForceNorm
  425.         JMP     COBY_LoopEnd
  426. COBY_NormByte:
  427.         MOV     BX,OFFSET bytecnt
  428.         ADD     BX,AX
  429.         ADD     BX,AX
  430.         INC     [WORD PTR BX]
  431. COBY_LoopEnd:
  432.         LOOP    COBY_Loop
  433.         POP     DX
  434.         POP     CX
  435.         POP     SI
  436.         POP     ES
  437.         RET
  438.  
  439. GenTrie:
  440.         PUSH    DX
  441.         PUSH    CX
  442.         PUSH    SI
  443.         PUSH    DI
  444.         PUSH    DS
  445.         MOV     AX,SEG Trie
  446.         MOV     DS,AX
  447.         MOV     DI,OFFSET Trie
  448.         MOV     SI,OFFSET bytecnt
  449.         MOV     CX,260
  450.         XOR     BX,BX
  451.         MOV     BP,0
  452. GETR_Loop1:
  453.         LODSW
  454.         OR      AX,AX
  455.         JE      GETR_CountIszero
  456.         MOV     [DI+0],BP
  457.         MOV     [WORD PTR DI+2],0
  458.         MOV     [WORD PTR DI+4],0
  459.         MOV     [DI+6],AX               ; 6: count
  460.         MOV     [DI+8],BX               ; 8: value
  461.         MOV     BP,DI
  462.         ADD     DI,10
  463. GETR_CountIsZero:
  464.         INC     BX
  465.         LOOP    GETR_Loop1
  466.         MOV     [Triestart],BP
  467.  
  468.         MOV     [FreeNodes],DI          ; initialize free node list
  469.         MOV     [WORD PTR DI],0
  470.  
  471. GETR_Loop2:                             ; build the tree
  472.         MOV     SI,[Triestart]
  473.         CMP     [WORD PTR SI],0
  474.         JNE     GETR_DoLoop2
  475.         JMP     GETR_L2Finished
  476. GETR_DoLoop2:
  477.         MOV     BX,SI
  478.         MOV     SI,[SI]
  479.         MOV     DI,SI
  480. GETR_Loop3:                             ; find the two nodes with minimum
  481.         MOV     DX,[DI+6]               ; count entries
  482.         CMP     DX,[BX+6]
  483.         JC      GETR_BXDIOK
  484.         PUSH    BX
  485.         MOV     BX,DI
  486.         POP     DI
  487. GETR_BXDIOK:
  488.         MOV     SI,[SI]
  489.         CMP     SI,0
  490.         JE      GETR_L3Finished
  491.         MOV     DX,[SI+6]
  492.         CMP     DX,[BX+6]
  493.         JNC     GETR_Loop3
  494.         MOV     BX,SI
  495.         JMP     GETR_Loop3
  496. GETR_L3Finished:
  497.         MOV     SI,OFFSET Triestart
  498. GETR_Loop4:                             ; remove these nodes from trie
  499.         CMP     [WORD PTR SI],0
  500.         JE      GETR_Loop4Finished
  501. GETR_L4_Check:
  502.         CMP     [SI],BX
  503.         JNE     GETR_L4_NotBX
  504.         MOV     BP,[BX]
  505.         MOV     [SI],BP
  506.         JMP     GETR_L4_Check
  507. GETR_L4_NotBX:
  508.         CMP     [SI],DI
  509.         JNE     GETR_L4_NotDI
  510.         MOV     BP,[DI]
  511.         MOV     [SI],BP
  512.         JMP     GETR_L4_Check
  513. GETR_L4_NotDI:
  514.         MOV     SI,[SI]
  515.         JMP     GETR_Loop4
  516. GETR_Loop4Finished:
  517.  
  518.         MOV     SI,[FreeNodes]          ; get a free node
  519.         MOV     AX,[SI]
  520.         MOV     [FreeNodes],AX
  521.  
  522.         MOV     AX,[Triestart]
  523.         MOV     [SI],AX
  524.         MOV     [Triestart],SI
  525.  
  526.         MOV     DX,[BX+6]               ; and initialize it
  527.         ADD     DX,[DI+6]
  528.         MOV     [SI+6],DX
  529.  
  530.         MOV     [WORD PTR SI+8],0ffffh
  531.  
  532.         CMP     [WORD PTR BX+8],0
  533.         JS      GETR_NewLeftBranch
  534.         MOV     AX,[FreeNodes]
  535.         MOV     [BX],AX
  536.         MOV     [FreeNodes],BX
  537.         MOV     BX,[BX+8]
  538.         XOR     [WORD PTR SI+8],4000h
  539. GETR_NewLeftBranch:
  540.         MOV     [SI+2],BX
  541.  
  542.         CMP     [WORD PTR DI+8],0
  543.         JS      GETR_NewRightBranch
  544.         MOV     AX,[FreeNodes]
  545.         MOV     [DI],AX
  546.         MOV     [FreeNodes],DI
  547.         MOV     DI,[DI+8]
  548.         XOR     [WORD PTR SI+8],2000h
  549. GETR_NewRightBranch:
  550.         MOV     [SI+4],DI
  551.         JMP     GETR_Loop2
  552. GETR_L2Finished:
  553.  
  554.         POP     DS
  555.         POP     DI
  556.         POP     SI
  557.         POP     CX
  558.         POP     DX
  559.         RET
  560.  
  561. CalcLengths:
  562.         PUSH    SI
  563.         XOR     AX,AX
  564.         MOV     SI,[TrieStart]
  565.         CMP     [WORD PTR FS:SI+8],0
  566.         JNS     CLCL_OnlyOneByte
  567.         CALL    CLCL_Recur
  568.         JMP     CLCL_Ret
  569. CLCL_OnlyOneByte:
  570.         MOV     BX,[FS:SI+6]
  571.         ADD     BX,BX
  572.         MOV     [BX+colen],1
  573. CLCL_Ret:
  574.         POP     SI
  575.         RET
  576.  
  577. CLCL_Recur:
  578.         INC     AX
  579.         PUSH    SI
  580.         TEST    [WORD PTR FS:SI+8],4000h
  581.         JNZ     CLCL_RightDeeper
  582.         MOV     BX,[FS:SI+2]
  583.         ADD     BX,BX
  584.         MOV     [BX+colen],AX
  585.         JMP     CLCL_RightEnd
  586. CLCL_RightDeeper:
  587.         MOV     SI,[FS:SI+2]
  588.         CALL    CLCL_Recur
  589. CLCL_RightEnd:
  590.         POP     SI
  591.         PUSH    SI
  592.         TEST    [WORD PTR FS:SI+8],2000h
  593.         JNZ     CLCL_LeftDeeper
  594.         MOV     BX,[FS:SI+4]
  595.         ADD     BX,BX
  596.         MOV     [BX+colen],AX
  597.         JMP     CLCL_LeftEnd
  598. CLCL_LeftDeeper:
  599.         MOV     SI,[FS:SI+4]
  600.         CALL    CLCL_Recur
  601. CLCL_LeftEnd:
  602.         POP     SI
  603.         DEC     AX
  604.         RET
  605.  
  606. MakeCodes:
  607.         PUSH    DI
  608.         PUSH    SI
  609.         PUSH    DS
  610.         PUSH    ES
  611.         PUSH    CX
  612.         PUSH    DX
  613.  
  614.         MOV     AX,SEG colen
  615.         MOV     DS,AX
  616.         MOV     ES,AX
  617.         MOV     BP,8000h                ; codeadd
  618.         MOV     DX,0                    ; code
  619.         MOV     AX,1                    ; clen
  620.         MOV     SI,0                    ; offset to codetab
  621.         MOV     BX,0                    ; mask
  622. MACO_Loop:
  623.         ADD     BX,BP
  624.         MOV     DI,OFFSET colen
  625.         MOV     CX,MAX_VAL+1
  626. MACO_InnerLoop:
  627.         REPNE   SCASW
  628.         JNE     MACO_LengthOK
  629.         PUSH    BX
  630.         MOV     BX,DI
  631.         SUB     BX,2+OFFSET colen
  632.         MOV     [BX+code],DX
  633.         POP     BX
  634.         MOV     [SI+codetab],DX
  635.         MOV     [SI+masktab],BX
  636.         ADD     SI,2
  637.         ADD     DX,BP
  638.         JCXZ    MACO_LengthOK
  639.         JMP     MACO_InnerLoop
  640. MACO_LengthOK:
  641.         ROR     BP,1
  642.         INC     AX
  643.         CMP     AX,16
  644.         JNE     MACO_Loop
  645.  
  646.         POP     DX
  647.         POP     CX
  648.         POP     ES
  649.         POP     DS
  650.         POP     SI
  651.         POP     DI
  652.         RET
  653.  
  654. WriteCodes:
  655.         PUSH    CX
  656.         PUSH    DS
  657.         MOV     BX,SEG colen
  658.         MOV     DS,BX
  659.         MOV     BX,0
  660.         MOV     CX,MAX_VAL+1
  661.         INC     CX
  662.         SHR     CX,1
  663. WRCO_Loop:
  664.         MOV     AX,[BX+colen]
  665.         SHL     AX,4
  666.         OR      AX,[BX+colen+2]
  667.         ADD     BX,4
  668.         SUB     DX,1
  669.         JNC     WRCO_Write
  670.         MOV     [Fault],1
  671.         JMP     WRCO_End
  672. WRCO_Write:
  673.         STOSB
  674.         LOOP    WRCO_Loop
  675. WRCO_End:
  676.         POP     DS
  677.         POP     CX
  678.         RET
  679.  
  680.  ; **************************************** decrunch
  681.  
  682. UnPackArea:                     ; DS:SI packed data ES:DI buffer CX buflen
  683.         PUSH    FS              ; out: CF set on error, AX unpacked len
  684.         MOV     AX,SEG bitpos
  685.         MOV     FS,AX
  686.  
  687.         CALL    Initialize
  688.  
  689.         CALL    GetUPparms
  690.         JNC     UPAC_contd
  691.         JMP     UPAC_Ret
  692. UPAC_contd:
  693.         PUSH    CX
  694.         PUSH    ES
  695.         PUSH    DI
  696.         PUSH    SEG tempbuf
  697.         POP     ES
  698.         MOV     DI,OFFSET tempbuf
  699.         TEST    [pckflg],80h
  700.         JZ      UPAC_Loop
  701.         CALL    ReadCodeLens
  702.         CALL    MakeCodes
  703. UPAC_Loop:
  704.         CALL    ReadPackedByte
  705.         TEST    [pckflg],1
  706.         JZ      UPAC_SimpleWrite
  707. UPAC_UnpackSeq:
  708.         CMP     AL,255
  709.         JNE     UPAC_SimpleWrite
  710.         CALL    ReadPackedByte
  711.         CMP     AL,255
  712.         JE      UPAC_SimpleWrite
  713.         PUSH    CX
  714.         MOV     DL,AL
  715.         CALL    JustReadPackedByte
  716.         MOV     BL,AL
  717.         MOV     BH,255
  718.         TEST    DL,2
  719.         JZ      UPAC_RelOK
  720.         CALL    JustReadPackedByte
  721.         MOV     BH,AL
  722. UPAC_RelOK:
  723.         CALL    JustReadPackedByte
  724.         MOV     CL,AL
  725.         XOR     CH,CH
  726.         TEST    DL,1
  727.         JZ      UPAC_LenOK
  728.         CALL    JustReadPackedByte
  729.         MOV     CH,AL
  730. UPAC_LenOK:
  731.         POP     DX
  732.         CMP     DX,CX
  733.         JC      UPAC_SeqFault   ; a bowl of spaghetti
  734.         PUSH    DX
  735.         PUSH    DS
  736.         PUSH    SI
  737.         PUSH    ES
  738.         POP     DS
  739.         MOV     SI,DI
  740.         ADD     SI,BX
  741.         ADD     CX,4
  742.         MOV     DX,CX
  743.         REP     MOVSB
  744.         POP     SI
  745.         POP     DS
  746.         POP     CX
  747.         SUB     CX,DX
  748.         INC     CX
  749.         JMP     UPAC_LoopEnd
  750. UPAC_SeqFault:
  751.         MOV     CX,8000h
  752.         JMP     UPAC_LoopEnd
  753. UPAC_SimpleWrite:
  754.         STOSB
  755. UPAC_LoopEnd:
  756.         DEC     CX
  757.         JS      UPAC_Unpacked
  758.         JNE     UPAC_Loop
  759. UPAC_Unpacked:
  760.         POP     DI
  761.         POP     ES
  762.         POP     DX
  763.         OR      CX,CX
  764.         JNE     UPAC_Fault
  765.         PUSH    DS
  766.         MOV     SI,SEG tempbuf
  767.         MOV     DS,SI
  768.         MOV     SI,OFFSET tempbuf
  769.         MOV     CX,DX
  770.         REP     MOVSB
  771.         MOV     AX,DX
  772.         POP     DS
  773.         CLC
  774.         JMP     UPAC_Ret
  775. UPAC_Fault:
  776.         XOR     AX,AX
  777.         STC
  778. UPAC_Ret:
  779.         POP     FS
  780.         RETF
  781.  
  782. GetUPParms:
  783.         PUSH    ES
  784.         MOV     AX,SEG tempbuf
  785.         MOV     ES,AX
  786.         CMP     [WORD PTR SI],'RC'       ; magic word: CRUXPACK
  787.         JNE     GUPA_End
  788.         CMP     [WORD PTR SI+2],'XU'
  789.         JNE     GUPA_End
  790.         CMP     [WORD PTR SI+4],'AP'
  791.         JNE     GUPA_End
  792.         CMP     [WORD PTR SI+6],'KC'
  793.         JNE     GUPA_End
  794.         MOV     AX,[SI+8]
  795.         MOV     [pckflg],AX
  796.         OR      AH,AH                   ; version 0
  797.         JNZ     GUPA_End
  798.         CMP     CX,[SI+10]
  799.         JC      GUPA_End
  800.         MOV     CX,[SI+10]
  801.         ADD     SI,12
  802.         CLC
  803.         JMP     GUPA_Ret
  804. GUPA_End:
  805.         STC
  806. GUPA_Ret:
  807.         POP     ES
  808.         RET
  809.  
  810. ReadCodeLens:
  811.         PUSH    CX
  812.         PUSH    ES
  813.         MOV     CX,SEG colen
  814.         MOV     ES,CX
  815.         MOV     [HuffSpc],0ffffh
  816.         MOV     [bitpos],0
  817.         MOV     BX,0
  818.         MOV     CX,MAX_VAL+1
  819.         INC     CX
  820.         SHR     CX,1
  821.         XOR     AX,AX
  822. RCOL_Loop:
  823.         LODSB
  824.         MOV     DX,AX
  825.         SHR     DX,4
  826.         AND     AX,15
  827.         MOV     [BX+colen],DX
  828.         MOV     [BX+colen+2],AX
  829.         ADD     BX,4
  830.         LOOP    RCOL_Loop
  831.         POP     ES
  832.         POP     CX
  833.         RET
  834.  
  835. ReadPackedByte:
  836.         TEST    [pckflg],80h
  837.         JNZ     RPAB_Huff
  838.         LODSB
  839.         RET
  840. RPAB_Huff:
  841.         CMP     [HuffSpc],0ffffh
  842.         JE      RPAB_HUFF_NoSpecial
  843.         MOV     AX,[HuffSpc]
  844.         MOV     [HuffSpc],0ffffh
  845.         RET
  846. RPAB_HUFF_NoSpecial:
  847.         PUSH    CX
  848.         PUSH    DX
  849.         PUSH    BX
  850.         MOV     AX,[SI]
  851.         ROL     AX,8
  852.         MOV     CX,[bitpos]
  853.         SHL     AX,CL
  854.         MOV     DX,[SI+2]
  855.         ROL     DX,8
  856.         NEG     CX
  857.         ADD     CX,16
  858.         SHR     DX,CL
  859.         OR      AX,DX
  860.         MOV     BX,0
  861. RPAB_HUFF_FindCode:
  862.         MOV     DX,AX
  863.         AND     DX,[BX+masktab]
  864.         CMP     DX,[BX+codetab]
  865.         JE      RPAB_Huff_FoundCode
  866.         ADD     BX,2
  867.         JMP     RPAB_HUFF_FindCode
  868. RPAB_HUFF_FoundCode:
  869.         MOV     DX,[BX+codetab]
  870.         MOV     BX,0
  871. RPAB_HUFF_FindByte:
  872.         CMP     [BX+colen],0
  873.         JZ      RPAB_HUFF_NotThis
  874.         CMP     DX,[BX+code]
  875.         JE      RPAB_HUFF_FoundByte
  876. RPAB_HUFF_NotThis:
  877.         ADD     BX,2
  878.         JMP     RPAB_HUFF_FindByte
  879. RPAB_HUFF_FoundByte:
  880.         MOV     DX,[BX+colen]
  881.         ADD     [bitpos],DX
  882.         CMP     [bitpos],16
  883.         JC      RPAB_HUFF_BPosOK
  884.         AND     [bitpos],15
  885.         ADD     SI,2
  886. RPAB_HUFF_BPosOK:
  887.         MOV     AX,BX
  888.         SHR     AX,1
  889.         CMP     AX,0ffh
  890.         JC      RPAB_HUFF_AllOK
  891.         TEST    [pckflg],1
  892.         JZ      RPAB_Huff_AllOK
  893.         XOR     AH,AH
  894.         MOV     [HuffSpc],AX
  895.         MOV     AX,0ffh
  896. RPAB_HUFF_AllOK:
  897.         POP     BX
  898.         POP     DX
  899.         POP     CX
  900.         RET
  901.  
  902. JustReadPackedByte:
  903.         TEST    [pckflg],80h
  904.         JNZ     JRPAB_Huff
  905.         LODSB
  906.         RET
  907. JRPAB_Huff:
  908.         PUSH    CX
  909.         PUSH    DX
  910.         PUSH    BX
  911.         MOV     AX,[SI]
  912.         ROL     AX,8
  913.         MOV     CX,[bitpos]
  914.         SHL     AX,CL
  915.         MOV     DX,[SI+2]
  916.         ROL     DX,8
  917.         NEG     CX
  918.         ADD     CX,16
  919.         SHR     DX,CL
  920.         OR      AX,DX
  921.         MOV     BX,0
  922. JRPAB_HUFF_FindCode:
  923.         MOV     DX,AX
  924.         AND     DX,[BX+masktab]
  925.         CMP     DX,[BX+codetab]
  926.         JE      JRPAB_Huff_FoundCode
  927.         ADD     BX,2
  928.         JMP     JRPAB_HUFF_FindCode
  929. JRPAB_HUFF_FoundCode:
  930.         MOV     DX,[BX+codetab]
  931.         MOV     BX,0
  932. JRPAB_HUFF_FindByte:
  933.         CMP     [BX+colen],0
  934.         JZ      JRPAB_HUFF_NotThis
  935.         CMP     DX,[BX+code]
  936.         JE      JRPAB_HUFF_FoundByte
  937. JRPAB_HUFF_NotThis:
  938.         ADD     BX,2
  939.         JMP     JRPAB_HUFF_FindByte
  940. JRPAB_HUFF_FoundByte:
  941.         MOV     DX,[BX+colen]
  942.         ADD     [bitpos],DX
  943.         CMP     [bitpos],16
  944.         JC      JRPAB_HUFF_BPosOK
  945.         AND     [bitpos],15
  946.         ADD     SI,2
  947. JRPAB_HUFF_BPosOK:
  948.         MOV     AX,BX
  949.         SHR     AX,1
  950.         POP     BX
  951.         POP     DX
  952.         POP     CX
  953.         RET
  954.  
  955. LoadPackedFile:
  956.         CALL    Initialize
  957.  
  958.         RETF
  959.  
  960. Initialize:
  961.         PUSH    CX
  962.         PUSH    DI
  963.         PUSH    ES
  964.  
  965.         PUSH    SEG packer_d_start
  966.         POP     ES
  967.  
  968.         MOV     DI,OFFSET packer_d_start
  969.         MOV     CX,packer_d_end-packer_d_start
  970.         XOR     AX,AX
  971.         REP     STOSB
  972.  
  973.         POP     ES
  974.         POP     DI
  975.         POP     CX
  976.         RET
  977.  
  978. ENDS
  979.  
  980. SEGMENT packer_data PRIVATE PARA 'DATEN'
  981.  
  982. LABEL packer_d_start WORD
  983.  
  984. bytecnt DW 300 DUP (0)
  985. colen   DW 300 DUP (0)
  986. code    DW 300 DUP (0)
  987. codetab DW 300 DUP (0)
  988. masktab DW 300 DUP (0)
  989.  
  990. huffuplen DW ?
  991.  
  992. pckflg  DW ?
  993.  
  994. relpos  DW ?
  995. rellen  DW ?
  996. relsave DW ?
  997.  
  998. HuffSpc DW ?
  999. bitpos  DW ?
  1000. Fault   DW ?
  1001.  
  1002. FreeNodes   DW ?
  1003. TrieStart   DW ?
  1004.  
  1005. Trie    DB  10*310 DUP (?)
  1006.  
  1007. tempbuf DB  33000 DUP (?)
  1008.  
  1009. LABEL packer_d_end WORD
  1010.  
  1011. ENDS
  1012.  
  1013. END
  1014.