; ***************************************************************************
;
;  Arithmetic decoder (optimized for size)
;
;	esi= source
;	edi= dest
;	ecx= size
;
; ***************************************************************************

 dc	equ -12

 dmax	equ 0
 dval	equ 4
 dzero	equ 8				; zero[255] at 8, one[255] at 255*4+8

DecDoneFor:
	pop	eax
	pop	ecx
	pop	ebx
	add	al, bl
	stosb
	xchg	eax, ebx
	jmp	short DecLoop

decode:

	xor	eax, eax
	inc	eax
	mov	ecx, 510
DecStackLoop:
	push	eax
	loop	DecStackLoop
	lodsb
	mov	ah, al
	lodsb
	shl	eax, 8
	lodsb
	push	eax
	push	ecx
	mov	ebp, esp
	inc	byte ptr [ebp+3]	; max=1000000h
	inc	edx			; count
	xchg	ecx, edx		; min=0
	mov	ebx, edx		; lastch= 0

DecLoop:

	loop	DecNotDone

	lea	esp, [ebp+512*4]
	ret

DecNotDone:
	push	ebx
	push	ecx

	xor	eax,eax
	push	eax
	push	eax

DecForLoop:

	pop	ecx
	cmp	ecx, 8
	jnb	short DecDoneFor

	xor	ebx,ebx
	inc	ebx
	shl	ebx, cl
	inc	ecx
	push	ecx
	dec	ebx
	add	ebx, [ebp+dc]
	lea	ebx, [ebp+4*ebx+dzero]

	mov	eax, dword ptr [ebp+dmax]
	dec	eax
	sub	eax, edx
	mov	ecx, [ebx]			; [zero]
	push	edx
	mul	ecx
	add	ecx, [ebx+255*4]		; [one]
	div	ecx
	pop	edx
	add	eax, edx

	cmp	eax, edx
	jne	short DecNoInc
	inc	eax
DecNoInc:

	xor	ecx, ecx
	cmp	eax, [ebp+dval]
	ja	short DecVal0
	inc	ecx
	inc	dword ptr [ebx+255*4]		; [one]
	xchg	eax, edx
	jmp	short DecValDone
DecVal0:
	inc	dword ptr [ebx]			; [zero]
	mov	[ebp+dmax], eax
DecValDone:

	shl	dword ptr [ebp+dc],1
	add	[ebp+dc], ecx

DecWhile:
	mov	eax, [ebp+dmax]
	mov	ebx, eax
	sub	eax, edx
	cmp	eax, 100h
	jge	short DecForLoop

	cmp	eax, 1
	jbe	short DecNoDec
	dec	ebx
DecNoDec:

	movzx	eax, word ptr [ebp+dval]
	movzx	ebx, bx
	movzx	edx, dx
	mov	cl, 8
	shl	eax, cl
	shl	ebx, cl
	shl	edx, cl
	lodsb
	mov	[ebp+dval], eax

	cmp	edx, ebx
	jb	short DecMinOverMax
	mov	ebx, 1000000h
DecMinOverMax:
	mov	[ebp+dmax], ebx
	jmp	short DecWhile

