home *** CD-ROM | disk | FTP | other *** search
/ BBS 1 / BBS#1.iso / document / compress.arj / LZU.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-05-23  |  5.3 KB  |  358 lines

  1. ; #compile /ml /w+ /t /m8 /zi
  2. ; #link    nolink
  3.  
  4.                         Include    LZ.ASI
  5. ;-------------------------------------------------------------
  6. ;
  7. ;    Project:    YAR compressor
  8. ;    Module:        LZU.ASM
  9. ;    Purpose:
  10. ;            Contains unpacker's critical code
  11. ;            for LZ.C
  12. ;
  13. ;    (C) 1991-92 Compact Soft
  14. ;    Written by: cs:dk
  15. ;
  16. ;-------------------------------------------------------------
  17.  
  18.  
  19. ; =====    Externals
  20.  
  21. .code
  22. global    p_reader : CODEPTR
  23. global    p_writer : CODEPTR
  24.  
  25.  
  26. ; =====    Local Data
  27.  
  28. .data
  29.  
  30. LenTable    db    3,    0,    1,    2
  31.         db    4,    5,    6,    9
  32.         db    10,    11,    12,    13
  33.         db    14,    15,    7,    8
  34.  
  35. DistTable    db    3,    4,    5,    0
  36.         db    1,    2,    6,    7
  37.         db    8,    9,    10,    11
  38.         db    12,    13,    14,    15
  39.  
  40.  
  41. LenStack    label    byte
  42.         i    = 1
  43.         REPT    TREESIZE
  44.             db    i
  45.             i    = i + 1
  46.         ENDM
  47.  
  48. DistStack    label    byte
  49.         i    = 0
  50.         REPT    TREESIZE
  51.             db    i
  52.             i    = i + 1
  53.         ENDM
  54.  
  55. .data?
  56.  
  57. UnpackInBuffer    label    byte
  58.         db    4096 dup (?)
  59. UnpackInBufferSafetyEnd    label    byte
  60.         db    6 dup (?)    ; max # of bytes needed in pass
  61. UnpackInBufferEnd    label    byte
  62.  
  63. ; minimum buffer size equals (MD == 4096) + ML, we use MD + ML + MD
  64. MaxDistance    equ    4096
  65.  
  66. UnpackOutBuffer    label    byte
  67.         db    (MaxDistance * 2) dup (?)
  68. SafetyEnd    label    byte
  69.         db    (254 + TREESIZE) dup (?) ; 254 'cause 255 is EOF mark
  70.  
  71.  
  72. ; =====    Unpacking routines
  73. .code
  74.  
  75. proc    FillInputBuffer
  76. ; Ensures that UnpackInBuffer is full
  77.  
  78.     ; move data left at end of buffer to beginning
  79.     push    cx di
  80.     mov    di, offset UnpackInBuffer
  81.     mov    cx, offset UnpackInBufferEnd
  82.     sub    cx, si
  83.     jcxz    @@ok
  84.     cld
  85.     rep    movsb
  86. @@ok:
  87.     mov    si, di
  88.     pop    di cx
  89.  
  90.     push    ax bx cx dx es
  91.  
  92.     mov    dx, offset UnpackInBufferEnd
  93.     sub    dx, si
  94.     ; dx = number of free bytes in buffer
  95.  
  96.     call    p_reader, ds si, dx
  97.     ; p_reader (const void *ptr, size_t size);
  98.  
  99.     pop    es dx cx bx ax
  100.  
  101.     lea    si, UnpackInBuffer
  102.     cld
  103.     ret
  104. endp    FillInputBuffer
  105.  
  106. proc    writeBuffer
  107. ; IN:
  108. ;    dx = bytes to write
  109.  
  110.     lea    bx, UnpackOutBuffer
  111.     call    p_writer, ds bx, dx
  112.     ; p_writer (const void *ptr, size_t size);
  113.  
  114.     ret
  115. endp    writeBuffer
  116.  
  117. proc    MoveUnpackBuffer
  118. ; ensures that UnpackOutBuffer is flushed except dictionary size
  119.  
  120.     push    ax bx cx dx es
  121.  
  122.     mov    dx, di        ; get ptr to UnpackOutBuffer
  123.     sub    dx, (offset UnpackOutBuffer) + MaxDistance
  124.     ; get current buffer size and left MaxDistance of it
  125.  
  126.     call    writeBuffer
  127.     pop    es dx cx bx ax
  128.  
  129.     ; move rest of buffer (MaxDistance bytes)
  130.     push    cx si
  131.     mov    si, di
  132.     sub    si, MaxDistance
  133.     mov    di, offset UnpackOutBuffer
  134.     mov    cx, MaxDistance
  135.     cld
  136.     rep    movsb
  137.     pop    si cx
  138.     ; di is set authomagically, and cld stays
  139.  
  140.     ret
  141. endp    MoveUnpackBuffer
  142.  
  143. proc    FlushUnpackBuffer
  144.  
  145.     push    ax bx cx dx es
  146.  
  147.     mov    dx, di        ; get ptr to UnpackOutBuffer
  148.     sub    dx, (offset UnpackOutBuffer)
  149.     ; get full current buffer size
  150.  
  151.     call    writeBuffer
  152.     pop    es dx cx bx ax
  153.  
  154.     ret
  155. endp    FlushUnpackBuffer
  156.  
  157.  
  158. global    _SquoUnpack : PROC
  159. ; void    _SquoUnpack (void)
  160.  
  161. proc    _SquoUnpack
  162.  
  163. ; Registers usage:
  164. ;    bp    = bit buffer
  165. ;    dx    = size of bp (in bits, 0 means empty)
  166. ;    cx    = decoded length
  167. ;    bx    = decoded distance and encoded data
  168. ;    ds:si    -> source buffer
  169. ;    es:di    -> destination buffer
  170. ;    ax    = tmp
  171.  
  172. FillBitBuffer    macro
  173.     lodsw
  174.     xchg    bp, ax        ; = 'mov bp, ax', but shorter
  175.     mov    dx, BITS
  176. endm
  177.  
  178. GetBit    macro    n
  179.     shr    bp, 1
  180.     rcl    bx, 1
  181.     dec    dx
  182.     jz    GetBit$Load&n
  183. GetBit$Cont&n:
  184.     ;; continue after filling up the bit buffer
  185. endm
  186.  
  187. LoadBit    macro    n
  188.  
  189.     even
  190. GetBit$Load&n:
  191.     FillBitBuffer
  192.     jmp    short GetBit$Cont&n
  193. endm
  194.  
  195.     uses    bp, si, di
  196.  
  197.     push    ds
  198.     pop    es
  199.  
  200.     lea    si, UnpackInBufferEnd
  201.     call    FillInputBuffer
  202.     lea    di, UnpackOutBuffer
  203.  
  204.     cld
  205.  
  206.     FillBitBuffer
  207.     jmp    @@getLength
  208.  
  209. @@saveData:
  210.     call    MoveUnpackBuffer
  211.     jmp    @@ok1
  212.  
  213. @@loadData:
  214.     call    FillInputBuffer
  215.     jmp    @@ok2
  216.  
  217.     IRP    num,    <l1, l2, l3, l4, l5, l6, l7>
  218.         LoadBit    num
  219.     ENDM
  220.  
  221. @@copyChar:
  222.     movsb
  223.     ; NOTE: implicit 'jmp @@getLength'
  224.  
  225. @@getLength:
  226.  
  227.     ; purge UnpackOutBuffer if necessary
  228.     cmp    di, offset SafetyEnd
  229.     ja    @@saveData
  230. @@ok1:
  231.  
  232.     ; fill UnpackInBuffer if necessary
  233.     cmp    si, offset UnpackInBufferSafetyEnd
  234.     ja    @@loadData
  235. @@ok2:
  236.  
  237.     xor    bx, bx
  238.  
  239.     GetBit    l1
  240.     GetBit    l2
  241.     or    bx, bx
  242.     jnz    @@decodeLength    ; do 01, 10, 11
  243.     GetBit    l3
  244.     GetBit    l4
  245.     or    bx, bx
  246.     jz    @@decodeLength    ; do 0000
  247.     GetBit    l5
  248.     cmp    bx, 00100b
  249.     jb    @@get6
  250.     cmp    bx, 00110b
  251.     jbe    @@decodeLength    ; do 00100, 00101, 00110
  252. @@get6:
  253.     GetBit    l6
  254.     cmp    bx, 000111b
  255.     jae    @@decodeLength    ; do 001110, 001111, 000111
  256.     GetBit    l7
  257.             ; do 6 others: 0001 + [000 .. 101]
  258. @@decodeLength:
  259.     mov    bl, LenTable [bx]
  260.     xor    cx, cx
  261.     mov    cl, LenStack [bx]
  262.  
  263.     IF    BookStack
  264.         push    cx
  265.         mov    cx, bx
  266.         jcxz    @@lenStackOk
  267.  
  268.         push    si di
  269.         lea    di, LenStack [bx]
  270.         lea    si, LenStack [bx - 1]
  271.         std
  272.         rep    movsb
  273.         cld
  274.         pop    di si
  275.  
  276.     @@lenStackOk:
  277.         pop    cx
  278.         mov    LenStack [0], cl
  279.     ENDIF
  280.  
  281.     cmp    cx, 1
  282.     je    @@copyChar
  283.     cmp    cx, TREESIZE
  284.     jae    @@addLen
  285.  
  286. @@getDistance:
  287.     xor    bx, bx
  288.  
  289.     GetBit    d1
  290.     GetBit    d2
  291.     cmp    bx, 11b
  292.     jae    @@decodeDistance    ; do 11
  293.     GetBit    d3
  294.     cmp    bx, 100b
  295.     jae    @@decodeDistance    ; do 100, 101
  296.     GetBit    d4
  297.     cmp    bx, 0010b
  298.     jbe    @@decodeDistance    ; do 0000, 0001, 0010
  299.     GetBit    d5
  300.             ; do 10 others: [00111 .. 01111]
  301. @@decodeDistance:
  302.     mov    bl, DistTable [bx]
  303.  
  304.     IF    BookStack
  305.         push    cx si di
  306.         lea    di, DistStack [bx]
  307.         lea    si, DistStack [bx - 1]
  308.  
  309.         mov    cx, bx
  310.         mov    bh, DistStack [bx]
  311.         jcxz    @@distStackOk
  312.  
  313.         std
  314.         rep    movsb
  315.         cld
  316.         mov    DistStack [0], bh
  317.  
  318.     @@distStackOk:
  319.         pop    di si cx
  320.     ELSE
  321.         mov    bh, DistStack [bx]
  322.     ENDIF
  323.  
  324.     lodsb
  325.     mov    bl, al        ; get low (distance)
  326.  
  327.     ; now copy string
  328.     inc    bx
  329.     push    si
  330.     mov    si, di
  331.     sub    si, bx
  332.     rep    movsb
  333.     pop    si
  334.     jmp    @@getLength
  335.  
  336. @@addLen:
  337.     lodsb
  338.     cmp    al, 0ffh    ; !!! EOF mark
  339.     je    @@exit
  340.     add    cl, al
  341.     adc    ch, 0
  342.     jmp    @@getDistance
  343.  
  344.  
  345. IRP    num,    <d1, d2, d3, d4, d5>
  346.     LoadBit    num
  347. ENDM
  348.  
  349. @@exit:
  350.     call    FlushUnpackBuffer
  351.  
  352.     ret
  353. endp    _SquoUnpack
  354.  
  355.  
  356. end    ; of LZU.ASM
  357.  
  358.