home *** CD-ROM | disk | FTP | other *** search
/ PC World 1997 November / PCWorld_1997-11_cd.bin / software / sharware / utility / PACKERS / LZH / LHASRC.EXE / SLIDE_.ASM < prev    next >
Assembly Source File  |  1991-03-03  |  22KB  |  1,149 lines

  1. ;***********************************************
  2. ;    slide_.asm -- sliding dictionary with 
  3. ;                  percolating update
  4. ;***********************************************
  5.             page    0, 128
  6.  
  7. include    amscls.inc
  8. $_init    GEN
  9.  
  10. N            =    2000h
  11. N2            =    N * 2
  12. N4            =    N * 4
  13.  
  14. MAXMATCH    =    256
  15. THRESHOLD    =    3
  16.  
  17. s1        segment at 0
  18. next        label    word
  19. s1        ends
  20.  
  21. s2        segment at 0
  22. parent        dw        N2 dup(?)
  23. position    dw        (N + 256) dup(?)
  24. s2        ends
  25.  
  26. s3        segment at 0
  27. prev        dw        N2 dup(?)
  28. level        label    byte
  29. childcount    equ        level + 1
  30.             dw        (N + 256) dup(?)
  31. s3        ends
  32.  
  33. extrn    error_:near
  34. extrn    fwrite_crc_:near
  35. extrn    fread_crc_:near
  36.  
  37. EncodeOption    struc
  38.     output            dw        ?
  39.     encode_start    dw        ?
  40.     encode_end        dw        ?
  41. EncodeOption    ends
  42.  
  43. DecodeOption    struc
  44.     decode_c        dw        ?
  45.     decode_p        dw        ?
  46.     decode_start    dw        ?
  47. DecodeOption    ends
  48.  
  49. interfacing        struc
  50.     infile            dw        ?
  51.     outfile            dw        ?
  52.     original        dd        ?
  53.     packed            dd        ?
  54.     dicbit            dw        ?
  55.     method            dw        ?
  56.     blkcnt            dw        ?
  57.     internal        dw        ?
  58. interfacing        ends
  59.  
  60. TEXT    segment byte public 'CODE'
  61. extrn    encode_start_fix_:near
  62. extrn    encode_start_st1_:near
  63. extrn    output_dyn_:near
  64. extrn    output_st1_:near
  65. extrn    encode_end_dyn_:near
  66. extrn    encode_end_st1_:near
  67.  
  68. extrn    decode_start_dyn_:near
  69. extrn    decode_start_fix_:near
  70. extrn    decode_start_lz5_:near
  71. extrn    decode_start_lzs_:near
  72. extrn    decode_start_st0_:near
  73. extrn    decode_start_st1_:near
  74. extrn    decode_c_dyn_:near
  75. extrn    decode_c_lz5_:near
  76. extrn    decode_c_lzs_:near
  77. extrn    decode_c_st0_:near
  78. extrn    decode_c_st1_:near
  79. extrn    decode_p_dyn_:near
  80. extrn    decode_p_lz5_:near
  81. extrn    decode_p_lzs_:near
  82. extrn    decode_p_st0_:near
  83. extrn    decode_p_st1_:near
  84. TEXT    ends
  85.  
  86. DATA    segment word public 'DATA'
  87.     public        encode_define_
  88. encode_define_    DW    output_dyn_
  89.                 DW    encode_start_fix_
  90.                 DW    encode_end_dyn_
  91.  
  92.                 DW    output_st1_
  93.                 DW    encode_start_st1_
  94.                 DW    encode_end_st1_
  95.  
  96.     public        decode_define_
  97. decode_define_    DW    decode_c_dyn_
  98.                 DW    decode_p_st0_
  99.                 DW    decode_start_fix_
  100.  
  101.                 DW    decode_c_dyn_
  102.                 DW    decode_p_dyn_
  103.                 DW    decode_start_dyn_
  104.  
  105.                 DW    decode_c_st0_
  106.                 DW    decode_p_st0_
  107.                 DW    decode_start_st0_
  108.  
  109.                 DW    decode_c_st1_
  110.                 DW    decode_p_st1_
  111.                 DW    decode_start_st1_
  112.  
  113.                 DW    decode_c_st1_
  114.                 DW    decode_p_st1_
  115.                 DW    decode_start_st1_
  116.  
  117.                 DW    decode_c_lzs_
  118.                 DW    decode_p_lzs_
  119.                 DW    decode_start_lzs_
  120.  
  121.                 DW    decode_c_lz5_
  122.                 DW    decode_p_lz5_
  123.                 DW    decode_start_lz5_
  124. DATA    ends
  125.  
  126.  
  127. BSS       segment word public 'DATA'
  128.         public    encode_set_
  129.         public    decode_set_
  130. encode_set_        dw        3 dup (?)
  131. decode_set_        dw        3 dup (?)
  132. count_            dw        2 dup(?)
  133. origsize_        dd        1 dup(?)
  134. compsize_        dd        1 dup(?)
  135. maxmatch_        dw        1 dup(?)
  136. dicbit_            dw        1 dup(?)
  137. unpackable_        dw        1 dup(?)
  138. matchlen        dw        1 dup(?)
  139. matchpos        dw        1 dup(?)
  140. lastmatchlen    dw        1 dup(?)
  141. lastmatchpos    dw        1 dup(?)
  142. seg1            dw        1 dup(?)
  143. seg2            dw        1 dup(?)
  144. seg3            dw        1 dup(?)
  145. avail            dw        1 dup(?)
  146. pos                dw        1 dup(?)
  147. remainder        dw        1 dup(?)
  148. dicsiz            dw        1 dup(?)
  149. dicsiz1            dw        1 dup(?)
  150. dicsiz2            dw        1 dup(?)
  151. dicsiz4            dw        1 dup(?)
  152. textend            dw        1 dup(?)
  153.  
  154. public        maxmatch_
  155. public        count_
  156. public        matchlen
  157. public        matchpos
  158. public        lastmatchlen
  159. public        lastmatchpos
  160. public        seg1
  161. public        seg2
  162. public        seg3
  163. public        avail
  164. public        pos
  165. public        remainder
  166. public        dicbit_
  167. public        origsize_
  168. public        compsize_
  169. public        unpackable_
  170.  
  171. extrn        text_:byte
  172. extrn        buf_:dword
  173. extrn        buf_limit_:word
  174. extrn        MEMOVRERR_:byte
  175. extrn        infile_:word
  176. extrn        outfile_:word
  177. extrn        crc_:word
  178.  
  179. BSS       ends
  180.  
  181. CGROUP    group    TEXT
  182. DGROUP    group    DATA, BSS
  183.  
  184. s0        equ        DGROUP
  185. HASH1    equ        (13 - 8 + 1)
  186.  
  187. assume    cs:TEXT, ds:DGROUP, es:nothing, ss:DGROUP
  188.  
  189. TEXT    segment byte public 'CODE'
  190.  
  191. ;    int encode_alloc(int method)
  192.     public        encode_alloc_
  193. encode_alloc_    proc    near
  194.     cld
  195.     push    ds
  196.     pop        es
  197.  
  198.     push    cx
  199.     push    si
  200.     push    di
  201.  
  202.     push    ax
  203.     mov        si, offset encode_define_ + 6;
  204.     mov        maxmatch_, 256
  205.     mov        dicbit_, 13
  206.     mov        dicsiz, 2000h
  207.     $_if <cmp ax, 1>, E
  208.         sub        si, 6
  209.         mov        maxmatch_, 60
  210.         dec        dicbit_
  211.         shr        dicsiz, 1
  212.     $_endif
  213.     mov        di, offset DGROUP:encode_set_
  214.     mov        cx, 3
  215.     rep        movsw
  216.     $_if <cmp dicbit_, 13>, E
  217.  
  218. SEG_SIZE1    =        2000h * 3 * 2 / 16
  219. SEG_SIZE2    =        (2000h * 3 + 256) * 2 / 16
  220. SEG_SIZE3    =        (2000h * 3 + 256) * 2 / 16
  221.  
  222.         mov        bx, 0ffffh
  223.         mov        ah, 48h        ; AllocMem
  224.         int        21h
  225.         $_if <cmp bx, SEG_SIZE1 + SEG_SIZE2 + SEG_SIZE3 + 256>, AE
  226.             $_if <cmp bx, SEG_SIZE1 + SEG_SIZE2 + SEG_SIZE3 + 1024>, A
  227.                 mov        bx, SEG_SIZE1 + SEG_SIZE2 + SEG_SIZE3 + 1024
  228.             $_endif
  229.             mov        ah, 48h        ; AllocMem
  230.             int        21h
  231.             mov        seg1, ax
  232.             add        ax, SEG_SIZE1
  233.             mov        seg2, ax
  234.             add        ax, SEG_SIZE2
  235.             mov        seg3, ax
  236.             add        ax, SEG_SIZE3
  237.             mov        word ptr buf_ + 2, ax
  238.             mov        word ptr buf_, 0
  239.             sub        bx, SEG_SIZE1 + SEG_SIZE2 + SEG_SIZE3
  240.             mov        cl, 4
  241.             shl        bx, cl
  242.             sub        bx, 24
  243.             mov        buf_limit_, bx
  244.             pop        ax
  245.  
  246.             pop        di
  247.             pop        si
  248.             pop        cx
  249.             ret
  250.         $_endif
  251.         dec        dicbit_
  252.         shr        dicsiz, 1
  253.     $_endif
  254.  
  255. SEG_SIZE14    =        1000h * 4 * 2 / 16
  256. SEG_SIZE24    =        0e20h
  257.  
  258.     mov        bx, SEG_SIZE14 + SEG_SIZE24
  259.     mov        ah, 48h        ; AllocMem
  260.     int        21h
  261.     $_if , C
  262.         mov        ax, offset DGROUP:MEMOVRERR_
  263.         xor        bx, bx
  264.         call    error_
  265.     $_endif
  266.     mov        seg1, ax
  267.     add        ax, SEG_SIZE14
  268.     mov        seg2, ax
  269.     add        ax, 0400h
  270.     mov        seg3, ax
  271.     add        ax, 0620h
  272.     mov        word ptr buf_ + 2, ax
  273.     mov        word ptr buf_, 0
  274.  
  275.     mov        buf_limit_, 1e00h - 24
  276.     pop        ax
  277.     $_if <cmp ax, 5>, E
  278.         dec        ax
  279.     $_endif
  280.     pop        di
  281.     pop        si
  282.     pop        cx
  283.     ret
  284. encode_alloc_    endp
  285.  
  286. init_slide_     proc     near
  287.     cld
  288.     push    ds
  289.     pop        ds
  290.  
  291.     push    cx
  292.     push    dx
  293.     push    di
  294.  
  295.     mov        es, seg3
  296.     mov        di, dicsiz
  297.     mov        dx, di                        ; dx = dicsiz
  298.     shl        di, 1
  299.     mov        bx, di                        ; bx = dicsiz * 2
  300.     mov        dicsiz2, bx
  301.     lea        ax, text_[bx]
  302.     mov        textend, ax
  303.  
  304.     add        di, offset s3:level
  305.     mov        cx, 256
  306.     mov        ax, 1
  307.     rep        stosw
  308.  
  309.     mov        es, seg2
  310.     mov        di, bx
  311.     add        di, offset s2:position
  312.     mov        cx, 256
  313.     xor        ax, ax
  314.     rep        stosw
  315.  
  316.     mov        avail, 2
  317.  
  318.     mov        di, bx
  319. ;    add        di, offset s2:parent
  320.     mov        cx, dx
  321.     rep        stosw
  322.  
  323.     mov        es, seg1
  324.     shl        bx, 1
  325.     mov        dicsiz4, bx                    ; bx = dicsiz * 4
  326.     mov        di, bx
  327. ;    add        di, offset s1:next
  328.     mov        cx, N
  329.     rep        stosw
  330.  
  331. ;    mov        di, offset s1:next
  332.     mov        di, ax
  333.     mov        cx, dicsiz
  334.     $_do
  335.         add        ax, 2
  336.         stosw
  337.     $_until <LOOP>
  338.  
  339.  
  340.     pop        di
  341.     pop        dx
  342.     pop        cx
  343.     ret
  344. init_slide_     endp
  345.  
  346. ReadBuffer:
  347. ;===============================
  348.     assume    ds:s0, es:s0
  349. ;===============================
  350.     push    ds
  351.     pop        es
  352.  
  353.     push    bx
  354.     mov        di, offset DGROUP:text_
  355.     mov        bx, dicsiz
  356.     lea        si, [di + bx]
  357.     mov        bp, si
  358.     mov        cx, maxmatch_
  359.     add        cx, bx
  360.     shr        cx, 1
  361.     rep        movsw
  362.  
  363.     mov        ax, di
  364.     mov        cx, infile_
  365.     call    fread_crc_
  366.  
  367.     add        remainder, ax
  368.     $_if <or ax, ax>, NZ
  369.         call    dispmark1_
  370.     $_endif
  371.     pop        bx
  372.     mov        ax, dicsiz
  373.     shl        ax, 1
  374.     mov        s0:pos, ax
  375.     jmp        DeleteInsert
  376.  
  377. GetNextMatch    proc    near
  378. ;===============================
  379.     assume    ds:s0, es:nothing
  380. ;===============================
  381.     dec        remainder
  382.     add        s0:pos, 2
  383.     inc        bp
  384.     cmp        bp, textend
  385.     je        ReadBuffer
  386. GetNextMatch    endp
  387.  
  388. DeleteInsert  proc      near
  389. DeleteNode:
  390.     public    DeleteNode
  391. ;=======================================
  392.     assume    ds:s0, es:nothing, ss:s0
  393. ;=======================================
  394.     push    ds
  395.     mov        di, s0:pos
  396. ;===============================
  397.     mov        ds, s0:seg2
  398.     assume    ds:s2, es:nothing
  399. ;===============================
  400.     cmp        word ptr s2:[di], 0
  401.     je        ToInsertNode
  402.  
  403. ;===============================
  404.     mov        es, s0:seg1
  405.     mov        ds, s0:seg3
  406.     assume    ds:s3, es:s1
  407. ;===============================
  408.     mov        si, s3:[di]
  409.     mov        bx, s1:[di]                    ; bx = s, si = r, di = p
  410.  
  411.     mov        s1:[si], bx
  412.     mov        s3:[bx], si
  413.  
  414.     xor        si, si
  415. ;===============================
  416.     mov        ds, s0:seg2
  417.     assume    ds:s2, es:s1
  418. ;===============================
  419.     xchg    si, s2:[di]
  420. ;===============================
  421.     mov        es, s0:seg3
  422.     assume    ds:s2, es:s3
  423. ;===============================
  424.     dec        s3:childcount[si]
  425.     cmp        si, dicsiz2
  426.     jae        ToInsertNode
  427.     mov        al, s3:childcount[si]
  428.     cmp        al, 1
  429.     $_if , A
  430. ToInsertNode:
  431.         jmp        InsertNode
  432.     $_endif
  433.  
  434.     mov        di, s2:position[si]                    ; bx = s, si = r, di = t
  435.     and        di, 7fffh
  436.     push    di
  437.     $_if <cmp di, s0:pos>, AE
  438.         sub        di, dicsiz2
  439.     $_endif
  440.     mov        bx, di
  441.     mov        di, s2:[si]                ; bx = s, q = di
  442.     mov        cx, s2:position[di]            ; cx = u
  443.     $_if <or cx, cx>, S
  444.         shl        cx, 1
  445.         $_do
  446.             shr        cx, 1
  447.             $_if <cmp cx, s0:pos>, AE
  448.                 sub        cx, dicsiz2
  449.             $_endif
  450.             $_if <cmp cx, bx>, A
  451.                 mov        bx, cx
  452.             $_endif
  453.             mov        cx, bx
  454.             or        cx, dicsiz2
  455.             mov        s2:position[di], cx
  456.             mov        di, s2:[di]
  457.             mov        cx, s2:position[di]            ; cx = u
  458.         $_until <shl cx, 1>, NC
  459.         shr        cx, 1
  460.     $_endif
  461.     $_if <cmp di, dicsiz2>, B
  462.         $_if <cmp cx, s0:pos>, AE
  463.             sub        cx, dicsiz2
  464.         $_endif
  465.         $_if <cmp cx, bx>, A
  466.             mov        bx, cx
  467.         $_endif
  468.         or        bx, dicsiz2
  469.         or        bx, 8000h
  470.         mov        s2:position[di], bx
  471.     $_endif
  472.     pop        di
  473.     mov        dx, di
  474. ;===============================
  475.     mov        es, s0:seg1
  476.     assume    ds:s2, es:s1
  477. ;===============================
  478.     $_if <cmp word ptr s2:[di], 0>, E
  479.         $_do
  480.             mov        di, s1:[di]
  481.         $_until <cmp word ptr s2:[di], 0>, NE
  482.     $_endif
  483.     $_do
  484.         mov        bx, di
  485.         mov        di, s2:[bx]
  486.     $_until <cmp di, si>, E
  487.  
  488. ;===============================
  489.     mov        ds, s0:seg3
  490.     assume    ds:s3, es:s1
  491. ;===============================
  492.     mov        dx, si
  493.     mov        si, s3:[bx]                    ; si = t, bx = s
  494.     mov        di, s1:[bx]                    ; di = u
  495.     mov        s1:[si], di
  496.     mov        s3:[di], si
  497.     mov        si, dx
  498.  
  499.     mov        di, s3:[si]                    ; bx = s, si = r, di = t
  500.     mov        s1:[di], bx
  501.     mov        s3:[bx], di
  502.  
  503.     mov        di, s1:[si]
  504.     mov        s3:[di], bx
  505.     mov        s1:[bx], di
  506.  
  507. ;===============================
  508.     mov        ds, s0:seg2
  509.     assume    ds:s2, es:s1
  510. ;===============================
  511. if 0
  512.     xor        di, di
  513.     xchg    di, s2:[si]
  514.     mov        s2:[bx], di
  515. else
  516.     mov        di, s2:[si]
  517.     mov        s2:[bx], di
  518.     mov        word ptr s2:[si], 0
  519. endif
  520.  
  521.     mov        dx, s0:avail
  522.     mov        s1:[si], dx
  523.     mov        s0:avail, si
  524.  
  525. InsertNode:
  526. ;===============================
  527.     assume    ds:s2, es:nothing
  528. ;===============================
  529.     mov        dl, s0:[bp]
  530.     xor        dh, dh
  531.     shl        dx, 1
  532.     or        dx, dicsiz2
  533.  
  534.     mov        ax, s0:matchlen
  535.     $_if <cmp ax, 4>, GE                ; LIMITLEN
  536.         dec        ax
  537.         mov        si, s0:matchpos
  538.         sub        si, offset s0:text_ - 1
  539.         shl        si, 1
  540.         or        si, dicsiz2
  541.  
  542.     ;===============================
  543.         mov        es, s0:seg1
  544.         assume    ds:s2, es:s1
  545.     ;===============================
  546.         mov        di, s2:[si]
  547.         $_if <or di, di>, Z
  548.             $_do
  549.                 mov        si, s1:[si]
  550.                 mov        di, s2:[si]
  551.             $_until <or di, di>, NZ
  552.         $_endif
  553.     ;===============================
  554.         mov        es, s0:seg3
  555.         assume    ds:s2, es:s3
  556.     ;===============================
  557.         $_if <cmp al, s3:level[di]>, NA
  558.             $_do
  559.                 mov        si, di
  560.                 mov        di, s2:[si]
  561.             $_until <cmp al, s3:level[di]>, A
  562.         $_endif
  563.         mov        dx, di
  564.  
  565.         mov        bx, di
  566.         mov        cx, s0:pos
  567.         $_if <cmp word ptr s2:position[bx], 0>, L
  568.             $_do
  569.                 mov        s2:position[bx], cx
  570.                 mov        bx, s2:[bx]
  571.             $_until <cmp word ptr s2:position[bx], 0>, NL
  572.         $_endif
  573.         $_if <cmp bx, dicsiz2>, B
  574.             or        cx, 8000h
  575.             mov        s2:position[bx], cx
  576.         $_endif
  577.         jmp        MatchNext
  578.  
  579.     $_endif
  580. ;===============================
  581.     assume    ds:s2, es:nothing
  582. ;===============================
  583.     mov        ax, 1
  584.     mov        s0:matchlen, ax
  585.  
  586. InsertLoop:
  587. ;===============================
  588.     assume    ds:s2, es:nothing
  589. ;===============================
  590.     mov        si, ax
  591.     mov        bl, s0:[bp + si]
  592. ;    xor        bh, bh
  593.     mov        cl, HASH1
  594.     shl        bx, cl
  595.     add        bx, dx
  596.     and        bx, N2 - 2
  597.     or        bx, dicsiz4                ; bx = h, si = r, di = s
  598.  
  599. ;===============================
  600.     mov        es, s0:seg1
  601.     assume    ds:s2, es:s1
  602. ;===============================
  603.     mov        s2:parent, dx
  604.  
  605.     mov        si, bx
  606.     $_do
  607.         mov si, s1:[si]
  608.     $_until <cmp s2:[si], dx>, E
  609.  
  610.     $_if <or si, si>, Z
  611. ;===============================
  612.     assume    ds:s2, es:s1
  613. ;===============================
  614.         mov        di, s0:pos
  615.         mov        s2:[di], dx
  616.  
  617.         mov        si, di
  618.         xchg    si, s1:[bx]            ; bx = h, si = s, di = p
  619.         mov        s1:[di], si
  620.     ;===============================
  621.         mov        es, s0:seg3
  622.         assume    ds:s2, es:s3
  623.     ;===============================
  624.         mov        s3:[di], bx
  625.         mov        s3:[si], di
  626.         mov        di, dx
  627.         inc        s3:childcount[di]
  628.  
  629.         pop        ds
  630.         ret
  631.     $_endif
  632.     inc        ax
  633.  
  634. ;===============================
  635.     assume    ds:s2, es:nothing
  636. ;===============================
  637. MatchNext:
  638.     push    si                            ; si = r
  639.     mov        cx, s0:maxmatch_
  640.     cmp        si, dicsiz2
  641.     $_if , B
  642.     ;===============================
  643.         mov        es, s0:seg3
  644.         assume    ds:s2, es:s3
  645.     ;===============================
  646.         mov        cl, s3:level[si]
  647.         xor        ch, ch
  648.         mov        si, s2:position[si]                ; si = matchpos, ax = matchlen
  649.         and        si, 7fffh
  650.     $_endif
  651. ;===============================
  652.     mov        bx, ss
  653.     mov        ds, bx
  654.     assume    ds:s0, es:nothing
  655. ;===============================
  656.     shr        si, 1
  657.     add        si, offset s0:text_
  658.     $_if <cmp si, bp>, AE
  659.         sub        si, dicsiz
  660.     $_endif
  661.     mov        s0:matchpos, si
  662.  
  663.     sub        cx, ax
  664.     $_if ,NE
  665.     ;===============================
  666.         mov        es, bx
  667.         assume    ds:s0, es:s0
  668.     ;===============================
  669.         mov        di, bp
  670.         add        di, ax
  671.         add        si, ax
  672.         add        ax, cx
  673.         repe    cmpsb
  674.     $_endif
  675. ;===============================
  676.     assume    ds:s0, es:nothing
  677. ;===============================
  678.     pop        si
  679.     $_if , NE
  680.         inc        cx
  681.         sub        ax, cx
  682.     $_endif
  683.     mov        s0:matchlen, ax
  684.  
  685.     jne        divnode
  686.  
  687.     $_if <cmp ax, maxmatch_>, NE
  688.         mov        cx, s0:pos
  689.     ;===============================
  690.         mov        ds, s0:seg2
  691.         assume    ds:s2, es:nothing
  692.     ;===============================
  693.         mov        s2:position[si], cx
  694.         mov        dx, si
  695.         jmp        InsertLoop
  696.  
  697.     $_endif
  698.  
  699. ;===============================
  700.     mov        es, s0:seg3
  701.     assume    ds:s0, es:s3
  702. ;===============================
  703.     mov        di, s0:pos                 ; bx = t, si = r, di = p
  704.     mov        bx, s3:[si]
  705.     mov        s3:[di], bx
  706. ;===============================
  707.     mov        ds, s0:seg1
  708.     assume    ds:s1, es:s3
  709. ;===============================
  710.     mov        s1:[bx], di
  711.  
  712.     mov        bx, s1:[si]
  713.     mov        s1:[di], bx
  714.     mov        s3:[bx], di
  715.  
  716. ;===============================
  717.     mov        es, s0:seg2
  718.     assume    ds:s1, es:s2
  719. ;===============================
  720.     mov        s2:[di], dx
  721.     mov        word ptr s2:[si], 0
  722.     mov        s1:[si], di
  723.  
  724.     pop        ds
  725.     ret
  726.  
  727. ;===============================
  728.     assume    ds:s0, es:nothing
  729. ;===============================
  730. divnode:
  731.     mov        di, s0:avail
  732.     mov        cx, s0:pos
  733. ;===============================
  734.     mov        es, s0:seg1
  735.     assume    ds:s0, es:s1
  736. ;===============================
  737.     mov        bx, s1:[di]
  738.     mov        s0:avail, bx            ; di = s, si = r, ax = matchlen
  739.  
  740. ;===============================
  741.     mov        ds, s0:seg2
  742.     assume    ds:s2, es:s1
  743. ;===============================
  744.     mov        s2:position[di], cx
  745.     mov        s2:[di], dx
  746.  
  747.     mov        bl, al
  748.     mov        bh, 2
  749. ;===============================
  750.     mov        ds, s0:seg3
  751.     assume    ds:s3, es:s1
  752. ;===============================
  753.     mov        word ptr s3:level[di], bx
  754.  
  755.     mov        bx, s3:[si]            ; di = s, si = r, bx = t
  756.     mov        s3:[di], bx
  757.     mov        s1:[bx], di
  758.  
  759.     mov        bx, s1:[si]
  760.     mov        s1:[di], bx
  761.     mov        s3:[bx], di
  762.  
  763.     mov        bx, s0:matchpos            ; di = s
  764.     add        bx, ax
  765.     mov        bl, s0:[bx]
  766. ;    xor        bh, bh
  767.     mov        cl, HASH1
  768.     shl        bx, cl
  769.     add        bx, di
  770.     and        bx, N2 - 2
  771.     or        bx, dicsiz4            ; bx = h, si = r, di = s
  772.  
  773.     push    di
  774. if 0
  775.     mov        di, si
  776.     xchg    di, s1:[bx]            ; di = t
  777.     mov        s1:[si], di
  778. else
  779.     mov        di, s1:[bx]            ; di = t
  780.     mov        s1:[bx], si
  781.     mov        s1:[si], di
  782. endif
  783.  
  784.     mov        s3:[si], bx
  785.     mov        s3:[di], si
  786.     pop        di
  787. ;===============================
  788.     mov        ds, s0:seg2
  789.     assume    ds:s2, es:s1
  790. ;===============================
  791.     mov        s2:[si], di
  792.  
  793.     mov        si, ax
  794.     mov        bl, s0:[bp + si]
  795. ;    xor        bh, bh
  796.     mov        cl, HASH1
  797.     shl        bx, cl
  798.     add        bx, di
  799.     and        bx, N2 - 2
  800.     or        bx, dicsiz4            ; bx = h, di = s
  801.  
  802.     mov        si, s0:pos                ; si = pos
  803.     mov        s2:[si], di                ; = s
  804.  
  805.     mov        dx, di
  806.  
  807. ;===============================
  808.     mov        ds, s0:seg3
  809.     assume    ds:s3, es:s1
  810. ;===============================
  811.     mov        di, si
  812.     xchg    di, s1:[bx]
  813.     mov        s1:[si], di            ; bx = h, si = pos, di = t
  814.  
  815.     mov        s3:[si], bx
  816.     mov        s3:[di], si
  817.  
  818.     pop        ds
  819.     ret
  820. DeleteInsert  endp
  821.  
  822. assume    ds:DGROUP, es:nothing
  823.  
  824. ;=======================================
  825.         public    encode_
  826. encode_ proc    near
  827.     push    cx
  828.     push    dx
  829.     push    si
  830.     push    di
  831.     push    bp
  832.  
  833.     push    ax
  834.     mov        di, ax
  835.     mov        ax, infile[di]
  836.     mov        infile_, ax
  837.  
  838.     mov        ax, outfile[di]
  839.     mov        outfile_, ax
  840.  
  841.     mov        ax, word ptr original[di]
  842.     mov        bx, word ptr original + 2[di]
  843.     mov        word ptr origsize_, ax
  844.     mov        word ptr origsize_ + 2, bx
  845.  
  846.     mov        word ptr compsize_, ax
  847.     mov        word ptr compsize_ + 2, bx
  848.  
  849.     xor        ax, ax
  850.     mov        unpackable_, ax
  851.     mov        crc_, ax
  852.  
  853.     call    init_slide_
  854.     call    word ptr encode_set_[encode_start]
  855.  
  856.     mov        cx, dicsiz
  857.     mov        ax, cx
  858.     dec        ax
  859.     mov        dicsiz1, ax
  860.  
  861.     mov        ax, cx
  862.     add        ax, maxmatch_
  863.     mov        bp, offset DGROUP:text_
  864.     add        bp, ax
  865.     shl        ax, 1
  866.     mov        pos, ax
  867.  
  868.     push    ds
  869.     pop        es
  870.  
  871.     mov        bx, cx
  872.     mov        di, bp
  873.     shr        cx, 1
  874.     mov        ax, '  '
  875.     rep        stosw
  876.     
  877.     mov        ax, bp
  878.     mov        cx, infile_
  879.     call    fread_crc_
  880.     mov        remainder, ax
  881.     $_if <or ax, ax>, NZ
  882.         call    dispmark1_
  883.     $_endif
  884.  
  885.     mov        matchlen, 0
  886.     call    DeleteInsert
  887.  
  888.     mov        ax, remainder
  889.     $_if <cmp matchlen, ax>, A
  890.         mov        matchlen, ax
  891.     $_endif
  892.     $_do
  893.         $_break , <cmp remainder, 0>, E
  894.         mov        ax, matchlen
  895.         mov        lastmatchlen, ax
  896.         mov        ax, matchpos
  897.         mov        lastmatchpos, ax
  898.         call    GetNextMatch
  899.         mov        ax, remainder
  900.         $_if <cmp matchlen, ax>, A
  901.             mov        matchlen, ax
  902.         $_endif
  903.  
  904.         mov        ax, lastmatchlen
  905.         $_if <cmp matchlen, ax>, A, OR
  906.         $_c     <cmp ax, THRESHOLD>, B
  907.             mov        al, ss:[bp - 1]
  908.             xor        ah, ah
  909.             call    word ptr encode_set_[output]
  910.         $_else
  911.             mov        bx, bp
  912.             sub        bx, lastmatchpos
  913.             sub        bx, 2
  914.             and        bx, dicsiz1
  915.             add        ax, 256 - THRESHOLD
  916.             call    word ptr encode_set_[output]
  917.             dec        lastmatchlen
  918.             $_do
  919.                 call    GetNextMatch
  920.             $_until <dec lastmatchlen>, Z
  921.             mov        ax, remainder
  922.             $_if <cmp matchlen, ax>, A
  923.                 mov        matchlen, ax
  924.             $_endif
  925.         $_endif
  926.     $_until <cmp unpackable_, 0>, NE
  927.     call    word ptr encode_set_[encode_end]
  928.  
  929.     pop        di
  930.     mov        ax, word ptr origsize_
  931.     mov        bx, word ptr origsize_ + 2
  932.     sub        ax, word ptr compsize_
  933.     sbb        bx, word ptr compsize_ + 2
  934.     mov        word ptr packed[di], ax
  935.     mov        word ptr packed + 2[di], bx
  936.     pop        bp
  937.     pop        di
  938.     pop        si
  939.     pop        dx
  940.     pop        cx
  941.     ret
  942. encode_ endp
  943.  
  944.  
  945. ;=======================================
  946.         public    decode_
  947. decode_ proc    near
  948.     cld
  949.     push    ds
  950.     pop        es
  951.  
  952.     push    cx
  953.     push    dx
  954.     push    si
  955.     push    di
  956.     push    bp
  957.  
  958. FILE        struc
  959. mode        db        ?
  960. ptr            dw        ?
  961. rcount        dw        ?
  962. wcount        dw        ?
  963. base        dw        ?
  964. bufsiz        dw        ?
  965. fd            dw        ?
  966. smallbuf    db        ?
  967. FILE        ends
  968.  
  969. extrn        _iob_:byte
  970. extrn        use_:byte
  971.  
  972.     mov        di, ax
  973.  
  974.     mov        bx, infile[di]
  975.     $_if <or bx, bx>, Z
  976.         mov        bx, offset DGROUP:_iob_ + 14 * 19
  977.         mov        mode[bx], 0b1h
  978.         mov        ax, internal[di]
  979.         mov        ptr[bx], ax
  980.         mov        rcount[bx], 1000h
  981.     $_endif
  982.     mov        infile_, bx
  983.  
  984.     mov        ax, outfile[di]
  985.     mov        outfile_, ax
  986.  
  987.     mov        cx, dicbit[di]
  988.     mov        dicbit_, cx
  989.     mov        ax, 1
  990.     shl        ax, cl
  991.     mov        dicsiz, ax
  992.  
  993.     mov        ax, word ptr original[di]
  994.     mov        word ptr origsize_, ax
  995.  
  996.     mov        ax, word ptr original + 2[di]
  997.     mov        word ptr origsize_ + 2, ax
  998.  
  999.     mov        ax, word ptr packed[di]
  1000.     mov        word ptr compsize_, ax
  1001.  
  1002.     mov        ax, word ptr packed + 2[di]
  1003.     mov        word ptr compsize_ + 2, ax
  1004.  
  1005.     xor        ax, ax
  1006.     mov        count_, ax
  1007.     mov        count_ + 2, ax
  1008.     mov        crc_, ax
  1009.  
  1010.     mov        si, method[di]
  1011.     mov        dx, 100h - 3
  1012.     $_if <cmp si, 6>, E
  1013.         inc        dx
  1014.     $_endif
  1015.  
  1016.     dec        si
  1017.     mov        di, si
  1018.     shl        si, 1
  1019.     add        si, di
  1020.     shl        si, 1
  1021.     add        si, offset DGROUP:decode_define_
  1022.     mov        di, offset DGROUP:decode_set_
  1023.     mov        cx, 3
  1024.     rep        movsw
  1025.  
  1026.     mov        di, offset DGROUP:text_
  1027.     mov        cx, N
  1028.     mov        ax, '  '
  1029.     rep        stosw
  1030.  
  1031.     call    word ptr decode_set_[decode_start]
  1032.  
  1033.     mov        di, offset DGROUP:text_
  1034.     mov        bp, dicsiz
  1035.     jmp        $entry
  1036.  
  1037.     $_while <TRUE>
  1038.     $loop:
  1039.         call    word ptr decode_set_[decode_c]
  1040.  
  1041.         $_if <or ah, ah>, Z
  1042.             stosb
  1043.             $_if <cmp    di, offset DGROUP:text_[N2]>, E
  1044.                 mov        di, offset DGROUP:text_
  1045.                 mov        ax, di
  1046.                 mov        bx, N2
  1047.                 mov        cx, outfile_
  1048.                 call    fwrite_crc_
  1049.             $_endif
  1050.             add        word ptr count_, 1
  1051.             adc        word ptr count_ + 2, 0
  1052.     $entry:
  1053.             sub        word ptr origsize_, 1
  1054.             sbb        word ptr origsize_ + 2, 0
  1055.             dec        bp
  1056.             jc        $endloop
  1057.             jns        $loop
  1058.  
  1059.             call    dispmark2_
  1060.         $_else
  1061.             mov        cx, ax
  1062.             sub        cx, dx
  1063.             mov        ax, di
  1064.             sub        ax, offset DGROUP:text_
  1065.             call    word ptr decode_set_[decode_p]
  1066.             mov        si, di
  1067.             sub        si, ax
  1068.             dec        si
  1069.             add        word ptr count_, cx
  1070.             adc        word ptr count_ + 2, 0
  1071.             sub        bp, cx
  1072.             $_if , S
  1073.                 call    dispmark2_
  1074.             $_endif
  1075.             mov        ax, di
  1076.             add        ax, cx
  1077.             push    cx
  1078.             $_if <sub ax, offset s0:text_[N2]>, AE
  1079.                 sub        cx, ax
  1080.                 rep        movsb
  1081.                 push    ax
  1082.                 mov        di, offset DGROUP:text_
  1083.                 mov        ax, di
  1084.                 mov        bx, N2
  1085.                 mov        cx, outfile_
  1086.                 call    fwrite_crc_
  1087.                 pop        cx
  1088.             $_else
  1089.                 $_if <cmp si, offset s0:text_>, B
  1090.                     add        si, N2
  1091.                 $_endif
  1092.             $_endif
  1093.             mov        ax, si
  1094.             add        ax, cx
  1095.             $_if <sub ax, offset s0:text_[N2]>, AE
  1096.                 sub        cx, ax
  1097.                 rep        movsb
  1098.                 mov        cx, ax
  1099.                 mov        si, offset s0:text_
  1100.             $_endif
  1101.             rep        movsb
  1102.             pop        cx
  1103.             sub        word ptr origsize_, cx
  1104.             sbb        word ptr origsize_ + 2, 0
  1105.             jc        $endloop
  1106.         $_endif
  1107.     $_enddo
  1108.     $endloop:
  1109.  
  1110.     mov        ax, offset DGROUP:text_
  1111.     mov        bx, di
  1112.     sub        bx, ax
  1113.     mov        cx, outfile_
  1114.     call    fwrite_crc_
  1115.  
  1116.     inc        bp
  1117.     $_if <cmp bp, dicsiz>, NE
  1118.         call    dispmark2_
  1119.     $_endif
  1120.     pop        bp
  1121.     pop        di
  1122.     pop        si
  1123.     pop        dx
  1124.     pop        cx
  1125.     ret
  1126. decode_ endp
  1127.  
  1128.             public    dispmark2_
  1129. dispmark2_    proc    near
  1130.     add        bp, dicsiz
  1131. dispmark2_    endp
  1132.  
  1133.             public    dispmark1_
  1134. dispmark1_    proc    near
  1135.     mov        al, 'o'
  1136.     jmp        dispmark_
  1137. dispmark1_    endp
  1138.  
  1139. extrn    dispmark_:near
  1140. TEXT   ends
  1141.  
  1142. public    init_slide_
  1143. public    DeleteInsert
  1144. public    GetNextMatch
  1145. public    encode_
  1146. public    decode_
  1147.  
  1148.         end
  1149.