Subversion Repositories Kolibri OS

Rev

Rev 183 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; void __stdcall unpack(void* packed_data, void* unpacked_data);
  2. unpack:
  3.         pushad
  4.         mov     esi, [esp+32+4]
  5.         mov     edi, [esp+32+8]
  6.         mov     eax, [esi+8]
  7.         and     al, 0xC0
  8.         cmp     al, 0xC0
  9.         jz      .failed
  10.         mov     eax, [esi+8]
  11.         push    eax
  12.         add     esi, 12
  13.         and     al, not 0xC0
  14.         dec     eax
  15.         jz      .lzma
  16. .failed:
  17.         pop     eax
  18.         popad
  19.         ret     8
  20. .lzma:
  21.         call    .lzma_unpack
  22. .common:
  23.         pop     eax
  24.         test    al, 0x80
  25.         jnz     .ctr1
  26.         test    al, 0x40
  27.         jz      .ok
  28.         lodsd
  29.         mov     ecx, eax
  30.         jecxz   .ok
  31.         mov     dl, [esi]
  32.         mov     esi, [esp+32+8]
  33. .c1:
  34.         lodsb
  35.         sub     al, 0E8h
  36.         cmp     al, 1
  37.         ja      .c1
  38.         cmp     byte [esi], dl
  39.         jnz     .c1
  40.         lodsd
  41. ; "bswap eax" is not supported on i386
  42.         shr     ax, 8
  43.         ror     eax, 16
  44.         xchg    al, ah
  45.         sub     eax, esi
  46.         add     eax, [esp+32+8]
  47.         mov     [esi-4], eax
  48.         loop    .c1
  49. .ok:
  50.         popad
  51.         ret     8
  52. .ctr1:
  53.         lodsd
  54.         mov     ecx, eax
  55.         jecxz   .ok
  56.         mov     dl, [esi]
  57.         mov     esi, [esp+32+8]
  58. .c2:
  59.         lodsb
  60. @@:
  61.         cmp     al, 0xF
  62.         jnz     .f
  63.         lodsb
  64.         cmp     al, 80h
  65.         jb      @b
  66.         cmp     al, 90h
  67.         jb      @f
  68. .f:
  69.         sub     al, 0E8h
  70.         cmp     al, 1
  71.         ja      .c2
  72. @@:
  73.         cmp     byte [esi], dl
  74.         jnz     .c2
  75.         lodsd
  76.         shr     ax, 8
  77.         ror     eax, 16
  78.         xchg    al, ah
  79.         sub     eax, esi
  80.         add     eax, [esp+32+8]
  81.         mov     [esi-4], eax
  82.         loop    .c2
  83.         jmp     .ok
  84.  
  85. .lzma_unpack:
  86.  
  87. .pb     =       2       ; pos state bits
  88. .lp     =       0       ; literal pos state bits
  89. .lc     =       3       ; literal context bits
  90. .posStateMask   =       ((1 shl .pb)-1)
  91. .literalPosMask =       ((1 shl .lp)-1)
  92.  
  93. .kNumPosBitsMax =       4
  94. .kNumPosStatesMax =     (1 shl .kNumPosBitsMax)
  95.  
  96. .kLenNumLowBits         =       3
  97. .kLenNumLowSymbols      =       (1 shl .kLenNumLowBits)
  98. .kLenNumMidBits         =       3
  99. .kLenNumMidSymbols      =       (1 shl .kLenNumMidBits)
  100. .kLenNumHighBits        =       8
  101. .kLenNumHighSymbols     =       (1 shl .kLenNumHighBits)
  102.  
  103. .LenChoice      =       0
  104. .LenChoice2     =       1
  105. .LenLow         =       2
  106. .LenMid         =       (.LenLow + (.kNumPosStatesMax shl .kLenNumLowBits))
  107. .LenHigh        =       (.LenMid + (.kNumPosStatesMax shl .kLenNumMidBits))
  108. .kNumLenProbs   =       (.LenHigh + .kLenNumHighSymbols)
  109.  
  110. .kNumStates     =       12
  111. .kNumLitStates  =       7
  112. .kStartPosModelIndex =  4
  113. .kEndPosModelIndex =    14
  114. .kNumFullDistances =    (1 shl (.kEndPosModelIndex/2))
  115. .kNumPosSlotBits =      6
  116. .kNumLenToPosStates =   4
  117. .kNumAlignBits  =       4
  118. .kAlignTableSize =      (1 shl .kNumAlignBits)
  119. .kMatchMinLen   =       2
  120.  
  121. .IsMatch        =       0
  122. .IsRep          =       (.IsMatch + (.kNumStates shl .kNumPosBitsMax))
  123. .IsRepG0        =       (.IsRep + .kNumStates)
  124. .IsRepG1        =       (.IsRepG0 + .kNumStates)
  125. .IsRepG2        =       (.IsRepG1 + .kNumStates)
  126. .IsRep0Long     =       (.IsRepG2 + .kNumStates)
  127. .PosSlot        =       (.IsRep0Long + (.kNumStates shl .kNumPosBitsMax))
  128. .SpecPos        =       (.PosSlot + (.kNumLenToPosStates shl .kNumPosSlotBits))
  129. .Align_         =       (.SpecPos + .kNumFullDistances - .kEndPosModelIndex)
  130. .Lencoder       =       (.Align_ + .kAlignTableSize)
  131. .RepLencoder    =       (.Lencoder + .kNumLenProbs)
  132. .Literal        =       (.RepLencoder + .kNumLenProbs)
  133.  
  134. .LZMA_BASE_SIZE =       1846    ; must be ==Literal
  135. .LZMA_LIT_SIZE  =       768
  136.  
  137. .kNumTopBits    =       24
  138. .kTopValue      =       (1 shl .kNumTopBits)
  139.  
  140. .kNumBitModelTotalBits =        11
  141. .kBitModelTotal =       (1 shl .kNumBitModelTotalBits)
  142. .kNumMoveBits   =       5
  143.  
  144.         push    edi
  145. ; int state=0;
  146.         xor     ebx, ebx
  147.         mov     [.previousByte], bl
  148. ; unsigned rep0=1,rep1=1,rep2=1,rep3=1;
  149.         mov     eax, 1
  150.         mov     edi, .rep0
  151.         stosd
  152.         stosd
  153.         stosd
  154.         stosd
  155. ; int len=0;
  156. ; result=0;
  157.         mov     ecx, .Literal + (.LZMA_LIT_SIZE shl (.lc+.lp))
  158.         mov     eax, .kBitModelTotal/2
  159.         mov     edi, .p
  160.         rep     stosd
  161. ; RangeDecoderInit
  162. ; rd->ExtraBytes = 0
  163. ; rd->Buffer = stream
  164. ; rd->BufferLim = stream+bufferSize
  165. ; rd->Range = 0xFFFFFFFF
  166.         pop     edi
  167.         mov     ebp, [esi-8]    ; dest_length
  168.         add     ebp, edi        ; ebp = destination limit
  169.         lodsd
  170. ; rd->code_ = eax
  171.         mov     [.code_], eax
  172.         or      [.range], -1
  173. .main_loop:
  174.         cmp     edi, ebp
  175.         jae     .main_loop_done
  176.         mov     edx, edi
  177.         and     edx, .posStateMask
  178.         mov     eax, ebx
  179.         shl     eax, .kNumPosBitsMax+2
  180.         lea     eax, [.p + .IsMatch*4 + eax + edx*4]
  181.         call    .RangeDecoderBitDecode
  182.         jc      .1
  183.         movzx   eax, [.previousByte]
  184. if .literalPosMask
  185.         mov     ah, dl
  186.         and     ah, .literalPosMask
  187. end if
  188.         shr     eax, 8-.lc
  189.         imul    eax, .LZMA_LIT_SIZE*4
  190.         add     eax, .p+.Literal*4
  191.         cmp     ebx, .kNumLitStates
  192.         jb      .literal
  193.         xor     edx, edx
  194.         sub     edx, [.rep0]
  195.         mov     dl, [edi + edx]
  196.         call    .LzmaLiteralDecodeMatch
  197.         jmp     @f
  198. .literal:
  199.         call    .LzmaLiteralDecode
  200. @@:
  201.         mov     [.previousByte], al
  202.         stosb
  203.         mov     al, bl
  204.         cmp     bl, 4
  205.         jb      @f
  206.         mov     al, 3
  207.         cmp     bl, 10
  208.         jb      @f
  209.         mov     al, 6
  210. @@:     sub     bl, al
  211.         jmp     .main_loop
  212. .1:
  213.         lea     eax, [.p + .IsRep*4 + ebx*4]
  214.         call    .RangeDecoderBitDecode
  215.         jnc     .10
  216.         lea     eax, [.p + .IsRepG0*4 + ebx*4]
  217.         call    .RangeDecoderBitDecode
  218.         jc      .111
  219.         mov     eax, ebx
  220.         shl     eax, .kNumPosBitsMax+2
  221.         lea     eax, [.p + .IsRep0Long*4 + eax + edx*4]
  222.         call    .RangeDecoderBitDecode
  223.         jc      .1101
  224.         cmp     bl, 7
  225.         setae   bl
  226.         lea     ebx, [9 + ebx + ebx]
  227.         xor     edx, edx
  228.         sub     edx, [.rep0]
  229.         mov     al, [edi + edx]
  230.         stosb
  231.         mov     [.previousByte], al
  232.         jmp     .main_loop
  233. .111:
  234.         lea     eax, [.p + .IsRepG1*4 + ebx*4]
  235.         call    .RangeDecoderBitDecode
  236.         mov     eax, [.rep1]
  237.         jnc     .l3
  238. .l1:
  239.         lea     eax, [.p + .IsRepG2*4 + ebx*4]
  240.         call    .RangeDecoderBitDecode
  241.         mov     eax, [.rep2]
  242.         jnc     .l2
  243.         xchg    [.rep3], eax
  244. .l2:
  245.         push    [.rep1]
  246.         pop     [.rep2]
  247. .l3:
  248.         xchg    eax, [.rep0]
  249.         mov     [.rep1], eax
  250. .1101:
  251.         mov     eax, .p + .RepLencoder*4
  252.         call    .LzmaLenDecode
  253.         cmp     bl, 7
  254.         setc    bl
  255.         adc     bl, bl
  256.         xor     bl, 3
  257.         add     bl, 8
  258.         jmp     .repmovsb
  259. .10:
  260.         mov     eax, [.rep0]
  261.         xchg    eax, [.rep1]
  262.         xchg    eax, [.rep2]
  263.         xchg    eax, [.rep3]
  264.         cmp     bl, 7
  265.         setc    bl
  266.         adc     bl, bl
  267.         xor     bl, 3
  268.         add     bl, 7
  269.         mov     eax, .p + .Lencoder*4
  270.         call    .LzmaLenDecode
  271.         mov     eax, .kNumLenToPosStates-1
  272.         cmp     eax, ecx
  273.         jb      @f
  274.         mov     eax, ecx
  275. @@:
  276.         push    ecx
  277.         mov     ecx, .kNumPosSlotBits
  278.         shl     eax, cl
  279.         shl     eax, 2
  280.         add     eax, .p+.PosSlot*4
  281.         call    .RangeDecoderBitTreeDecode
  282.         mov     [.rep0], ecx
  283.         cmp     ecx, .kStartPosModelIndex
  284.         jb      .l6
  285.         push    ecx
  286.         mov     eax, ecx
  287.         and     eax, 1
  288.         shr     ecx, 1
  289.         or      eax, 2
  290.         dec     ecx
  291.         shl     eax, cl
  292.         mov     [.rep0], eax
  293.         pop     edx
  294.         cmp     edx, .kEndPosModelIndex
  295.         jae     .l5
  296.         sub     eax, edx
  297.         shl     eax, 2
  298.         add     eax, .p + (.SpecPos - 1)*4
  299.         call    .RangeDecoderReverseBitTreeDecode
  300.         add     [.rep0], ecx
  301.         jmp     .l6
  302. .l5:
  303.         sub     ecx, .kNumAlignBits
  304.         call    .RangeDecoderDecodeDirectBits
  305.         mov     ecx, .kNumAlignBits
  306.         shl     eax, cl
  307.         add     [.rep0], eax
  308.         mov     eax, .p+.Align_*4
  309.         call    .RangeDecoderReverseBitTreeDecode
  310.         add     [.rep0], ecx
  311. .l6:
  312.         pop     ecx
  313.         inc     [.rep0]
  314.         jz      .main_loop_done
  315. .repmovsb:
  316.         add     ecx, .kMatchMinLen
  317.         push    esi
  318.         mov     esi, edi
  319.         sub     esi, [.rep0]
  320.         rep     movsb
  321.         pop     esi
  322.         mov     al, [edi-1]
  323.         mov     [.previousByte], al
  324.         jmp     .main_loop
  325. .main_loop_done:
  326.         ret
  327.  
  328. .RangeDecoderBitDecode:
  329. ; in: eax->prob
  330. ; out: CF=bit; destroys eax
  331.         push    edx
  332.         mov     edx, [.range]
  333.         shr     edx, .kNumBitModelTotalBits
  334.         imul    edx, [eax]
  335.         cmp     [.code_], edx
  336.         jae     .ae
  337.         mov     [.range], edx
  338.         mov     edx, .kBitModelTotal
  339.         sub     edx, [eax]
  340.         shr     edx, .kNumMoveBits
  341.         add     [eax], edx
  342.         clc
  343. .n:
  344.         lahf
  345.         cmp     [.range], .kTopValue
  346.         jae     @f
  347.         shl     [.range], 8
  348.         shl     [.code_], 8
  349.         lodsb
  350.         mov     byte [.code_], al
  351. @@:
  352.         sahf
  353.         pop     edx
  354.         ret
  355. .ae:
  356.         sub     [.range], edx
  357.         sub     [.code_], edx
  358.         mov     edx, [eax]
  359.         shr     edx, .kNumMoveBits
  360.         sub     [eax], edx
  361.         stc
  362.         jmp     .n
  363.  
  364. .RangeDecoderDecodeDirectBits:
  365. ; in: ecx=numTotalBits
  366. ; out: eax=result; destroys edx
  367.         xor     eax, eax
  368. .l:
  369.         shr     [.range], 1
  370.         shl     eax, 1
  371.         mov     edx, [.code_]
  372.         sub     edx, [.range]
  373.         jb      @f
  374.         mov     [.code_], edx
  375.         or      eax, 1
  376. @@:
  377.         cmp     [.range], .kTopValue
  378.         jae     @f
  379.         shl     [.range], 8
  380.         shl     [.code_], 8
  381.         push    eax
  382.         lodsb
  383.         mov     byte [.code_], al
  384.         pop     eax
  385. @@:
  386.         loop    .l
  387.         ret
  388.  
  389. .LzmaLiteralDecode:
  390. ; in: eax->probs
  391. ; out: al=byte; destroys edx
  392.         push    ecx
  393.         mov     ecx, 1
  394. @@:
  395.         push    eax
  396.         lea     eax, [eax+ecx*4]
  397.         call    .RangeDecoderBitDecode
  398.         pop     eax
  399.         adc     cl, cl
  400.         jnc     @b
  401. .LzmaLiteralDecode.ret:
  402.         mov     al, cl
  403.         pop     ecx
  404.         ret
  405. .LzmaLiteralDecodeMatch:
  406. ; in: eax->probs, dl=matchByte
  407. ; out: al=byte; destroys edx
  408.         push    ecx
  409.         mov     ecx, 1
  410. .LzmaLiteralDecodeMatch.1:
  411.         add     dl, dl
  412.         setc    ch
  413.         push    eax
  414.         lea     eax, [eax+ecx*4+0x100*4]
  415.         call    .RangeDecoderBitDecode
  416.         pop     eax
  417.         adc     cl, cl
  418.         jc      .LzmaLiteralDecode.ret
  419.         xor     ch, cl
  420.         test    ch, 1
  421.         mov     ch, 0
  422.         jnz     @b
  423.         jmp     .LzmaLiteralDecodeMatch.1
  424.  
  425. .LzmaLenDecode:
  426. ; in: eax->prob, edx=posState
  427. ; out: ecx=len
  428.         push    eax
  429.         add     eax, .LenChoice*4
  430.         call    .RangeDecoderBitDecode
  431.         pop     eax
  432.         jnc     .0
  433.         push    eax
  434.         add     eax, .LenChoice2*4
  435.         call    .RangeDecoderBitDecode
  436.         pop     eax
  437.         jc      @f
  438.         mov     ecx, .kLenNumMidBits
  439.         shl     edx, cl
  440.         lea     eax, [eax + .LenMid*4 + edx*4]
  441.         call    .RangeDecoderBitTreeDecode
  442.         add     ecx, .kLenNumLowSymbols
  443.         ret
  444. @@:
  445.         add     eax, .LenHigh*4
  446.         mov     ecx, .kLenNumHighBits
  447.         call    .RangeDecoderBitTreeDecode
  448.         add     ecx, .kLenNumLowSymbols + .kLenNumMidSymbols
  449.         ret
  450. .0:
  451.         mov     ecx, .kLenNumLowBits
  452.         shl     edx, cl
  453.         lea     eax, [eax + .LenLow*4 + edx*4]
  454. .RangeDecoderBitTreeDecode:
  455. ; in: eax->probs,ecx=numLevels
  456. ; out: ecx=length; destroys edx
  457.         push    ebx
  458.         mov     edx, 1
  459.         mov     ebx, edx
  460. @@:
  461.         push    eax
  462.         lea     eax, [eax+edx*4]
  463.         call    .RangeDecoderBitDecode
  464.         pop     eax
  465.         adc     dl, dl
  466.         add     bl, bl
  467.         loop    @b
  468.         sub     dl, bl
  469.         pop     ebx
  470.         mov     ecx, edx
  471.         ret
  472. .RangeDecoderReverseBitTreeDecode:
  473. ; in: eax->probs,ecx=numLevels
  474. ; out: ecx=length; destroys edx
  475.         push    ebx ecx
  476.         mov     edx, 1
  477.         xor     ebx, ebx
  478. @@:
  479.         push    eax
  480.         lea     eax, [eax+edx*4]
  481.         call    .RangeDecoderBitDecode
  482.         lahf
  483.         adc     edx, edx
  484.         sahf
  485.         rcr     ebx, 1
  486.         pop     eax
  487.         loop    @b
  488.         pop     ecx
  489.         rol     ebx, cl
  490.         mov     ecx, ebx
  491.         pop     ebx
  492.         ret
  493.  
  494. uglobal
  495. align 4
  496. unpack.p        rd      unpack.LZMA_BASE_SIZE + (unpack.LZMA_LIT_SIZE shl (unpack.lc+unpack.lp))
  497. unpack.code_    dd      ?
  498. unpack.range    dd      ?
  499. unpack.rep0     dd      ?
  500. unpack.rep1     dd      ?
  501. unpack.rep2     dd      ?
  502. unpack.rep3     dd      ?
  503. unpack.previousByte db  ?
  504. endg
  505.