Subversion Repositories Kolibri OS

Rev

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

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