Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; Exports only one function:
  2. ; void __stdcall lzma_decompress(
  3. ;       const void* source,
  4. ;       void* destination,
  5. ;       unsigned dest_length);
  6.  
  7.         format COFF
  8.  
  9. section '.text' code
  10.  
  11. pb      equ     2       ; pos state bits
  12. lp      equ     0       ; literal pos state bits
  13. lc      equ     3       ; literal context bits
  14. posStateMask    equ     ((1 shl pb)-1)
  15. literalPosMask  equ     ((1 shl lp)-1)
  16.  
  17. kNumPosBitsMax  =       4
  18. kNumPosStatesMax =      (1 shl kNumPosBitsMax)
  19.  
  20. kLenNumLowBits  =       3
  21. kLenNumLowSymbols =     (1 shl kLenNumLowBits)
  22. kLenNumMidBits  =       3
  23. kLenNumMidSymbols =     (1 shl kLenNumMidBits)
  24. kLenNumHighBits =       8
  25. kLenNumHighSymbols =    (1 shl kLenNumHighBits)
  26.  
  27. LenChoice       =       0
  28. LenChoice2      =       1
  29. LenLow          =       2
  30. LenMid          =       (LenLow + (kNumPosStatesMax shl kLenNumLowBits))
  31. LenHigh         =       (LenMid + (kNumPosStatesMax shl kLenNumMidBits))
  32. kNumLenProbs    =       (LenHigh + kLenNumHighSymbols)
  33.  
  34. kNumStates      =       12
  35. kNumLitStates   =       7
  36. kStartPosModelIndex =   4
  37. kEndPosModelIndex =     14
  38. kNumFullDistances =     (1 shl (kEndPosModelIndex/2))
  39. kNumPosSlotBits =       6
  40. kNumLenToPosStates =    4
  41. kNumAlignBits   =       4
  42. kAlignTableSize =       (1 shl kNumAlignBits)
  43. kMatchMinLen    =       2
  44.  
  45. IsMatch         =       0
  46. IsRep           =       0xC0    ; (IsMatch + (kNumStates shl kNumPosBitsMax))
  47. IsRepG0         =       0xCC    ; (IsRep + kNumStates)
  48. IsRepG1         =       0xD8    ; (IsRepG0 + kNumStates)
  49. IsRepG2         =       0xE4    ; (IsRepG1 + kNumStates)
  50. IsRep0Long      =       0xF0    ; (IsRepG2 + kNumStates)
  51. PosSlot         =       0x1B0   ; (IsRep0Long + (kNumStates shl kNumPosBitsMax))
  52. SpecPos         =       0x2B0   ; (PosSlot + (kNumLenToPosStates shl kNumPosSlotBits))
  53. Align_          =       0x322   ; (SpecPos + kNumFullDistances - kEndPosModelIndex)
  54. Lencoder        =       0x332   ; (Align_ + kAlignTableSize)
  55. RepLencoder     =       0x534   ; (Lencoder + kNumLenProbs)
  56. Literal         =       0x736   ; (RepLencoder + kNumLenProbs)
  57.  
  58. LZMA_BASE_SIZE  =       1846    ; must be ==Literal
  59. LZMA_LIT_SIZE   =       768
  60.  
  61. kNumTopBits     =       24
  62. kTopValue       =       (1 shl kNumTopBits)
  63.  
  64. kNumBitModelTotalBits = 11
  65. kBitModelTotal  =       (1 shl kNumBitModelTotalBits)
  66. kNumMoveBits    =       5
  67.  
  68. RangeDecoderBitDecode:
  69. ; in: eax->prob
  70. ; out: CF=bit
  71.         push    edx
  72.         mov     edx, [range]
  73.         shr     edx, kNumBitModelTotalBits
  74.         imul    edx, [eax]
  75.         cmp     [code_], edx
  76.         jae     .ae
  77.         mov     [range], edx
  78.         mov     edx, kBitModelTotal
  79.         sub     edx, [eax]
  80.         shr     edx, kNumMoveBits
  81.         add     [eax], edx
  82. .n:
  83.         pushfd
  84.         call    update_decoder
  85.         popfd
  86.         pop     edx
  87.         ret
  88. .ae:
  89.         sub     [range], edx
  90.         sub     [code_], edx
  91.         mov     edx, [eax]
  92.         shr     edx, kNumMoveBits
  93.         sub     [eax], edx
  94.         stc
  95.         jmp     .n
  96.  
  97. update_decoder:
  98.         cmp     byte [range+3], 0       ;cmp    dword [range], kTopValue
  99.         jnz     @f                      ;jae    @f
  100.         shl     dword [range], 8
  101.         shl     dword [code_], 8
  102.         push    eax
  103.         mov     eax, [inptr]
  104.         mov     al, [eax]
  105.         inc     dword [inptr]
  106.         mov     byte [code_], al
  107.         pop     eax
  108. @@:     ret
  109.  
  110. LzmaLenDecode:
  111. ; in: eax->prob, edx=posState
  112. ; out: ecx=len
  113.  
  114. ; LenChoice==0
  115. ;       add     eax, LenChoice*4
  116.         call    RangeDecoderBitDecode
  117.         jnc     .0
  118.         add     eax, (LenChoice2-LenChoice)*4
  119.         call    RangeDecoderBitDecode
  120.         jc      @f
  121.         mov     cl, kLenNumMidBits
  122.         shl     edx, cl
  123.         lea     eax, [eax + (LenMid-LenChoice2)*4 + edx*4]
  124.         call    RangeDecoderBitTreeDecode
  125.         add     ecx, kLenNumLowSymbols
  126.         ret
  127. @@:
  128.         add     eax, (LenHigh-LenChoice2)*4
  129.         mov     cl, kLenNumHighBits
  130.         call    RangeDecoderBitTreeDecode
  131.         add     ecx, kLenNumLowSymbols + kLenNumMidSymbols
  132.         ret
  133. .0:
  134.         mov     cl, kLenNumLowBits
  135.         shl     edx, cl
  136.         lea     eax, [eax + LenLow*4 + edx*4]
  137. RangeDecoderBitTreeDecode:
  138. ; in: eax->probs,ecx=numLevels
  139. ; out: ecx=length; destroys edx
  140.         push    edi
  141.         xor     edx, edx
  142.         inc     edx
  143.         mov     edi, edx
  144.         xchg    eax, edi
  145. @@:
  146.         push    eax
  147.         lea     eax, [edi+edx*4]
  148.         call    RangeDecoderBitDecode
  149.         pop     eax
  150.         adc     dl, dl
  151.         add     al, al
  152.         loop    @b
  153.         sub     dl, al
  154.         pop     edi
  155.         mov     ecx, edx
  156.         ret
  157.  
  158. ; void __stdcall lzma_decompress(
  159. ;       const void* source,
  160. ;       void* destination,
  161. ;       unsigned dest_length);
  162. lzma_decompress equ _lzma_decompress@12
  163. public lzma_decompress
  164. lzma_decompress:
  165.         push    esi edi ebx ebp
  166.         mov     esi, [esp+4*4+4]        ; source
  167.         xor     ebp, ebp
  168.         mov     edi, code_
  169.         inc     esi
  170.         lodsd
  171.         bswap   eax
  172.         stosd
  173.         xor     eax, eax
  174.         dec     eax
  175.         stosd
  176.         stosd
  177.         stosd
  178.         stosd
  179.         xchg    eax, esi
  180.         stosd
  181.         mov     ecx, Literal + (LZMA_LIT_SIZE shl (lc+lp))
  182.         mov     eax, kBitModelTotal/2
  183.         mov     edi, p
  184.         rep     stosd
  185.         mov     edi, [esp+4*4+8]        ; destination
  186.         mov     ebx, edi
  187.         add     ebx, [esp+4*4+12]       ; dest_length
  188. .main_loop:
  189.         cmp     edi, ebx
  190.         jae     .main_loop_done
  191.         mov     edx, edi
  192.         and     edx, posStateMask
  193.         push    eax     ; al = previous byte
  194.         mov     eax, ebp
  195.         shl     eax, kNumPosBitsMax+2
  196.         lea     eax, [p + IsMatch*4 + eax + edx*4]
  197.         call    RangeDecoderBitDecode
  198.         pop     eax
  199.         jc      .1
  200.         movzx   eax, al
  201. if literalPosMask
  202.         mov     ah, dl
  203.         and     ah, literalPosMask
  204. end if
  205.         shr     eax, 8-lc
  206.         imul    eax, LZMA_LIT_SIZE*4
  207.         add     eax, p+Literal*4
  208.         mov     cl, 1
  209.         cmp     ebp, kNumLitStates
  210.         jb      .literal
  211.         mov     dl, [edi + esi]
  212. .lx0:
  213.         add     dl, dl
  214.         setc    ch
  215.         push    eax
  216.         lea     eax, [eax+ecx*4+0x100*4]
  217.         call    RangeDecoderBitDecode
  218.         pop     eax
  219.         adc     cl, cl
  220.         jc      .lx1
  221.         xor     ch, cl
  222.         test    ch, 1
  223.         mov     ch, 0
  224.         jz      .lx0
  225. .literal:
  226. @@:
  227.         push    eax
  228.         lea     eax, [eax+ecx*4]
  229.         call    RangeDecoderBitDecode
  230.         pop     eax
  231.         adc     cl, cl
  232.         jnc     @b
  233. .lx1:
  234.         mov     eax, ebp
  235.         cmp     al, 4
  236.         jb      @f
  237.         cmp     al, 10
  238.         mov     al, 3
  239.         jb      @f
  240.         mov     al, 6
  241. @@:     sub     ebp, eax
  242.         xchg    eax, ecx
  243. .stosb_main_loop:
  244.         stosb
  245.         jmp     .main_loop
  246. .1:
  247.         lea     eax, [p + IsRep*4 + ebp*4]
  248.         call    RangeDecoderBitDecode
  249.         jnc     .10
  250.         add     eax, (IsRepG0 - IsRep)*4        ;lea    eax, [p + IsRepG0*4 + ebp*4]
  251.         call    RangeDecoderBitDecode
  252.         jc      .111
  253.         mov     eax, ebp
  254.         shl     eax, kNumPosBitsMax+2
  255.         lea     eax, [p + IsRep0Long*4 + eax + edx*4]
  256.         call    RangeDecoderBitDecode
  257.         jc      .1101
  258.         cmp     ebp, 7
  259.         sbb     ebp, ebp
  260.         lea     ebp, [ebp+ebp+11]
  261.         mov     al, [edi + esi]
  262.         jmp     .stosb_main_loop
  263. .111:
  264.         add     eax, (IsRepG1 - IsRepG0) * 4    ;lea    eax, [p + IsRepG1*4 + ebp*4]
  265.         call    RangeDecoderBitDecode
  266.         xchg    esi, [rep1]
  267.         jnc     @f
  268.         add     eax, (IsRepG2 - IsRepG1) * 4    ;lea    eax, [p + IsRepG2*4 + ebp*4]
  269.         call    RangeDecoderBitDecode
  270.         xchg    esi, [rep2]
  271.         jnc     @f
  272.         xchg    esi, [rep3]
  273. @@:
  274. .1101:
  275.         mov     eax, p + RepLencoder*4
  276.         call    LzmaLenDecode
  277.         push    8
  278.         jmp     .rmu
  279. .10:
  280.         xchg    esi, [rep1]
  281.         xchg    esi, [rep2]
  282.         mov     [rep3], esi
  283.         mov     eax, p + Lencoder*4
  284.         call    LzmaLenDecode
  285.         push    kNumLenToPosStates-1
  286.         pop     eax
  287.         cmp     eax, ecx
  288.         jb      @f
  289.         mov     eax, ecx
  290. @@:
  291.         push    ecx
  292.         push    kNumPosSlotBits
  293.         pop     ecx
  294.         shl     eax, cl
  295.         shl     eax, 2
  296.         add     eax, p+PosSlot*4
  297.         call    RangeDecoderBitTreeDecode
  298.         mov     esi, ecx
  299.         cmp     ecx, kStartPosModelIndex
  300.         jb      .l6
  301.         push    ecx
  302.         xor     eax, eax
  303.         inc     eax
  304.         shr     ecx, 1
  305.         adc     al, al
  306.         dec     ecx
  307.         shl     eax, cl
  308.         mov     esi, eax
  309.         pop     edx
  310.         cmp     edx, kEndPosModelIndex
  311.         jae     .l5
  312.         sub     eax, edx
  313.         shl     eax, 2
  314.         add     eax, p + (SpecPos - 1)*4
  315.         jmp     .l59
  316. .l5:
  317.         sub     ecx, kNumAlignBits
  318. ;       call    RangeDecoderDecodeDirectBits
  319. ;RangeDecoderDecodeDirectBits:
  320.         xor     eax, eax
  321. .l:
  322.         shr     dword [range], 1
  323.         add     eax, eax
  324.         mov     edx, [code_]
  325.         sub     edx, [range]
  326.         jb      @f
  327.         mov     [code_], edx
  328.         inc     eax
  329. @@:
  330.         call    update_decoder
  331.         loop    .l
  332. ;       ret
  333.         mov     cl, kNumAlignBits
  334.         shl     eax, cl
  335.         add     esi, eax
  336.         mov     eax, p+Align_*4
  337. .l59:
  338. ;       call    RangeDecoderReverseBitTreeDecode_addesi
  339. ;_RangeDecoderReverseBitTreeDecode_addesi:
  340. ; in: eax->probs,ecx=numLevels
  341. ; out: esi+=length; destroys edx
  342.         push    edi ecx
  343.         xor     edx, edx
  344.         inc     edx
  345.         xor     edi, edi
  346. @@:
  347.         push    eax
  348.         lea     eax, [eax+edx*4]
  349.         call    RangeDecoderBitDecode
  350.         lahf
  351.         adc     edx, edx
  352.         sahf
  353.         rcr     edi, 1
  354.         pop     eax
  355.         loop    @b
  356.         pop     ecx
  357.         rol     edi, cl
  358.         add     esi, edi
  359.         pop     edi
  360. ;       ret
  361. .l6:
  362.         pop     ecx
  363.         not     esi
  364.         push    7
  365. .rmu:
  366.         cmp     ebp, 7
  367.         pop     ebp
  368.         jb      @f
  369.         inc     ebp
  370.         inc     ebp
  371.         inc     ebp
  372. @@:
  373. .repmovsb:
  374.         inc     ecx
  375.         push    esi
  376.         add     esi, edi
  377.         rep     movsb
  378.         lodsb
  379.         pop     esi
  380.         jmp     .stosb_main_loop
  381. .main_loop_done:
  382.         pop     ebp ebx edi esi
  383.         ret     12
  384.  
  385. section '.bss' data
  386. p       rd      LZMA_BASE_SIZE + (LZMA_LIT_SIZE shl (lc+lp))
  387. code_   dd      ?
  388. range   dd      ?
  389. rep1    dd      ?
  390. rep2    dd      ?
  391. rep3    dd      ?
  392. inptr   dd      ?
  393. previousByte db ?
  394.