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