Subversion Repositories Kolibri OS

Rev

Rev 9029 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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