Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5098 clevermous 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