Subversion Repositories Kolibri OS

Rev

Rev 750 | Rev 1635 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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