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     2       ; 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.  
  102.         xchg    eax, esi
  103. ;       mov     ecx, Literal + (LZMA_LIT_SIZE shl (lc+lp))
  104.         mov     ch, (Literal + (LZMA_LIT_SIZE shl (lc+lp)) + 0xFF) shr 8
  105.         mov     eax, kBitModelTotal/2
  106.         mov     edi, p
  107.         rep     stosd
  108.  
  109.         pop     edi
  110.         push    edi
  111. loader_patch3:
  112. .main_loop:
  113.         cmp     edi, dword 0            ; will be patched: end of data to unpack
  114.         jae     .main_loop_done
  115.  
  116. if posStateMask
  117.         mov     edx, edi
  118.         and     edx, posStateMask
  119. else
  120.         xor     edx, edx
  121. end if
  122.         push    eax     ; al = previous byte
  123.         lea     eax, [ebp + ((p+IsMatch*4) shr (kNumPosBitsMax+2))]
  124.         shl     eax, kNumPosBitsMax+2
  125. if posStateMask
  126.         call    RangeDecoderBitDecode_edx
  127. else
  128.         call    RangeDecoderBitDecode
  129. end if
  130.         pop     eax
  131.         jc      .1
  132.  
  133.         movzx   eax, al
  134. if literalPosMask
  135.         mov     ah, dl
  136.         and     ah, literalPosMask
  137. end if
  138. if ((LZMA_LIT_SIZE*4) and ((1 shl (8-lc)) - 1)) <> 0
  139.         shr     eax, 8-lc
  140.         imul    eax, LZMA_LIT_SIZE*4
  141. else
  142.         and     al, not ((1 shl (8-lc)) - 1)
  143.         imul    eax, (LZMA_LIT_SIZE*4) shr (8-lc)
  144. end if
  145.         add     eax, p+Literal*4
  146.         mov     dl, 1
  147.         cmp     ebp, kNumLitStates
  148.         jb      .literal
  149.  
  150.         mov     cl, [edi + esi]
  151. ;--------------------------------------
  152. .lx0:
  153.         add     cl, cl
  154.         adc     dh, 1
  155.         call    RangeDecoderBitDecode_edx
  156.  
  157.         adc     dl, dl
  158.         jc      .lx1
  159.  
  160.         xor     dh, dl
  161.         test    dh, 1
  162.         mov     dh, 0
  163.         jnz     .lx0
  164. ;--------------------------------------
  165. .literal:
  166. @@:
  167.         call    RangeDecoderBitDecode_edx
  168.         adc     dl, dl
  169.         jnc     @b
  170. ;--------------------------------------
  171. .lx1:
  172.         mov     eax, ebp
  173.         cmp     al, 4
  174.         jb      @f
  175.  
  176.         cmp     al, 10
  177.         mov     al, 3
  178.         jb      @f
  179.  
  180.         mov     al, 6
  181. @@:
  182.         sub     ebp, eax
  183.         xchg    eax, edx
  184. ;--------------------------------------
  185. .stosb_main_loop:
  186.         stosb
  187.         jmp     .main_loop
  188. ;*********************************************************************
  189. .1:
  190.         lea     eax, [p + IsRep*4 + ebp*4]
  191.         call    RangeDecoderBitDecode
  192.         jnc     .10
  193.  
  194.         add     eax, (IsRepG0 - IsRep)*4        ;lea    eax, [p + IsRepG0*4 + ebp*4]
  195.         call    RangeDecoderBitDecode
  196.         jc      .111
  197.  
  198.         mov     eax, ebp
  199.         shl     eax, kNumPosBitsMax+2
  200.         add     eax, p + IsRep0Long*4
  201.         call    RangeDecoderBitDecode_edx
  202.         jc      .1101
  203.  
  204.         cmp     ebp, 7
  205.         sbb     ebp, ebp
  206.         lea     ebp, [ebp+ebp+11]
  207.         mov     al, [edi + esi]
  208.         jmp     .stosb_main_loop
  209. ;*********************************************************************
  210. .111:
  211.         add     eax, (IsRepG1 - IsRepG0) * 4    ;lea    eax, [p + IsRepG1*4 + ebp*4]
  212.         call    RangeDecoderBitDecode
  213.         xchg    esi, [rep1]
  214.         jnc     @f
  215.  
  216.         add     eax, (IsRepG2 - IsRepG1) * 4    ;lea    eax, [p + IsRepG2*4 + ebp*4]
  217.         call    RangeDecoderBitDecode
  218.         xchg    esi, [rep2]
  219.         jnc     @f
  220.  
  221.         xchg    esi, [rep3]
  222. ;--------------------------------------
  223. @@:
  224. .1101:
  225.         mov     eax, p + RepLencoder*4
  226.         call    LzmaLenDecode
  227.  
  228.         push    8
  229.         jmp     .rmu
  230. ;*********************************************************************
  231. .10:
  232.         xchg    esi, [rep1]
  233.         xchg    esi, [rep2]
  234.         mov     [rep3], esi
  235.         mov     eax, p + Lencoder*4
  236.         call    LzmaLenDecode
  237.  
  238.         push    kNumLenToPosStates-1
  239.         pop     edx
  240.         cmp     edx, ecx
  241.         jb      @f
  242.  
  243.         mov     edx, ecx
  244. ;--------------------------------------
  245. @@:
  246.         push    ecx
  247.         push    kNumPosSlotBits
  248.         pop     ecx
  249.         mov     eax, p+PosSlot*4
  250.         shl     edx, cl
  251.         call    RangeDecoderBitTreeDecode
  252.  
  253.         mov     esi, ecx
  254.         cmp     ecx, kStartPosModelIndex
  255.         jb      .l6
  256.  
  257.         mov     edx, ecx
  258.         xor     eax, eax
  259.         shr     ecx, 1
  260.         adc     al, 2
  261.         dec     ecx
  262.         shl     eax, cl
  263.         mov     esi, eax
  264.         sub     eax, edx
  265.         lea     eax, [p + (SpecPos - 1)*4 + eax*4]
  266.         cmp     edx, kEndPosModelIndex
  267.         jb      .l59
  268. ;       call    RangeDecoderDecodeDirectBits
  269. ;RangeDecoderDecodeDirectBits:
  270.         xor     eax, eax
  271. ;--------------------------------------
  272. .l:
  273.         shr     dword [range], 1
  274.         add     eax, eax
  275.         mov     edx, [code_]
  276.         sub     edx, [range]
  277.         jb      @f
  278.  
  279.         mov     [code_], edx
  280.         add     al, 1 shl kNumAlignBits
  281. ;--------------------------------------
  282. @@:
  283.         call    update_decoder
  284.         dec     ecx
  285.         cmp     ecx, kNumAlignBits
  286.         jnz     .l
  287. ;       ret
  288.         add     esi, eax
  289.         mov     eax, p+Align_*4
  290. ;--------------------------------------
  291. .l59:
  292. ;       call    RangeDecoderReverseBitTreeDecode_addesi
  293. ;_RangeDecoderReverseBitTreeDecode_addesi:
  294. ; in: eax->probs,ecx=numLevels
  295. ; out: esi+=length; destroys edx
  296.         push    edi
  297.         xor     edx, edx
  298.         inc     edx
  299.         mov     edi, edx
  300. ;--------------------------------------
  301. @@:
  302.         call    RangeDecoderBitDecode_edx
  303.         jnc     .591
  304.  
  305.         add     esi, edi
  306.         stc
  307. ;--------------------------------------
  308. .591:
  309.         adc     edx, edx
  310.         add     edi, edi
  311.         loop    @b
  312.  
  313.         pop     edi
  314. ;       ret
  315. ;--------------------------------------
  316. .l6:
  317.         pop     ecx
  318.         not     esi
  319.         push    7
  320. ;--------------------------------------
  321. .rmu:
  322.         cmp     ebp, 7
  323.         pop     ebp
  324.         jb      @f
  325.         add     ebp, 3
  326. ;--------------------------------------
  327. @@:
  328. .repmovsb:
  329.         inc     ecx
  330.         push    esi
  331.         add     esi, edi
  332.         rep     movsb
  333.  
  334.         lodsb
  335.         pop     esi
  336.         jmp     .stosb_main_loop
  337. ;*********************************************************************
  338. .main_loop_done:
  339. include 'calltrick2.inc'
  340.         ret
  341. ;*********************************************************************
  342. _RangeDecoderBitDecode:
  343. ; in: eax->prob
  344. ; out: CF=bit
  345.         push    edx
  346.         mov     edx, [range]
  347.         shr     edx, kNumBitModelTotalBits
  348.         imul    edx, [eax]
  349.         cmp     [code_], edx
  350.         jae     .ae
  351.  
  352.         mov     [range], edx
  353.         mov     edx, kBitModelTotal
  354.         sub     edx, [eax]
  355.         shr     edx, kNumMoveBits
  356.         add     [eax], edx
  357. ;--------------------------------------
  358. .n:
  359.         pushfd
  360.         call    update_decoder
  361.  
  362.         popfd
  363.         pop     edx
  364.         ret
  365. ;*********************************************************************
  366. .ae:
  367.         sub     [range], edx
  368.         sub     [code_], edx
  369.         mov     edx, [eax]
  370.         shr     edx, kNumMoveBits
  371.         sub     [eax], edx
  372.         stc
  373.         jmp     .n
  374. ;*********************************************************************
  375. update_decoder:
  376.         cmp     byte [range+3], 0       ;cmp    dword [range], kTopValue
  377.         jnz     @f                      ;jae    @f
  378.  
  379.         shl     dword [range], 8
  380.         shl     dword [code_], 8
  381.         push    eax
  382.         mov     eax, [inptr_ldr]
  383.         mov     al, [eax]
  384.         inc     dword [inptr_ldr]
  385.         mov     byte [code_], al
  386.         pop     eax
  387. @@:
  388.         ret
  389. ;*********************************************************************
  390. _RangeDecoderBitDecode_edx:
  391.         push    eax
  392.         lea     eax, [eax+edx*4]
  393.         call    RangeDecoderBitDecode
  394.  
  395.         pop     eax
  396.         ret
  397. ;*********************************************************************
  398. LzmaLenDecode:
  399. ; in: eax->prob, edx=posState
  400. ; out: ecx=len
  401.  
  402. ; LenChoice==0
  403. ;       add     eax, LenChoice*4
  404. if kLenNumMidBits <> kLenNumLowBits
  405. error in optimization
  406. end if
  407.         mov     cl, kLenNumMidBits
  408.         call    RangeDecoderBitDecode
  409.         jnc     .0
  410.  
  411.         add     eax, (LenChoice2-LenChoice)*4
  412.         call    RangeDecoderBitDecode
  413.         jc      @f
  414. if (kLenNumMidBits <> 3) | (LenMid-LenChoice2 > 0x7F + kLenNumMidBits)
  415.         shl     edx, cl
  416.         add     edx, LenMid-LenChoice2
  417. else
  418.         lea     edx, [ecx + edx*8 - kLenNumMidBits + LenMid-LenChoice2]
  419. end if
  420.         push    kLenNumLowSymbols
  421.         jmp     RangeDecoderBitTreeDecode.1
  422. ;*********************************************************************
  423. @@:
  424.         mov     edx, LenHigh-LenChoice2
  425.         mov     cl, kLenNumHighBits
  426.         push    kLenNumLowSymbols + kLenNumMidSymbols
  427.         jmp     RangeDecoderBitTreeDecode.1
  428. ;*********************************************************************
  429. .0:
  430.         shl     edx, cl
  431. if LenLow = 2
  432.         inc     edx
  433.         inc     edx
  434. else
  435.         add     edx, LenLow
  436. end if
  437. ;--------------------------------------
  438. RangeDecoderBitTreeDecode:
  439. ; in: eax+edx*4->probs,ecx=numLevels
  440. ; out: ecx=length; destroys edx
  441.         push    0
  442. .1:
  443.         lea     eax, [eax+edx*4]
  444.         xor     edx, edx
  445.         inc     edx
  446.         push    ecx
  447. @@:
  448.         call    RangeDecoderBitDecode_edx
  449.  
  450.         adc     edx, edx
  451.         loop    @b
  452.  
  453.         pop     ecx
  454.         btc     edx, ecx
  455.         pop     ecx
  456.         add     ecx, edx
  457.         ret
  458. loader_size = $ - loader_start
  459. ;*********************************************************************