;***********************************************************************
; Copyright Alex "Statix" Evans 1995
;
; ASSEMBLER FUNCTIONS for LZW
;
;***********************************************************************


.486
.model flat


.data

END_OF_STREAM = 256
BUMP_CODE = 257
FLUSH_CODE = 258
FIRST_CODE = 259

externdef _dict:dword;
externdef _decode_stack:byte;
externdef _next_code:dword;
externdef _current_code_bits:byte;
externdef _new_code:dword;
externdef _old_code:dword;
externdef _character:byte;
externdef _RAMPtr:dword;
externdef _RAMRack:byte;
externdef _RAMMask:byte;
externdef _numdecode:dword;


externdef asmexpand_:near;

temp dword 0

.code



;--------------------------------------------------------------------------
asmexpand_	proc	; output, amount
;--------------------------------------------------------------------------
		pushad
		mov	ecx,edx
		mov	edi,eax
		mov	esi,_RAMPtr
		mov	dl,_RAMRack
		mov	dh,_RAMMask
		mov	temp,edi
outer:
		mov	ebx,_numdecode
		or	ebx,ebx
		jz	inner
outer2:
		dec	ebx
		mov	al,_decode_stack[ebx]
		stosb
		dec	ecx
		jz	done
		or	ebx,ebx
		jnz	outer2
inner:
		call	readbit
		mov	_new_code,eax
		cmp	eax,END_OF_STREAM
		je	done
		cmp	eax,FLUSH_CODE
		je	doflush
		cmp	eax,BUMP_CODE
		je	dobump
		xor	ebp,ebp
		cmp	eax,_next_code
		jb	nofix
		mov	al,_character
		mov   _decode_stack,al
		inc	ebp
		mov	eax,_old_code
nofix:
		cmp	eax,255
		jbe	doneit
again:
		lea	ebx,[eax*8]
		add	ebx,_dict
		mov	eax,[ebx+4]
		mov	bl,[ebx]
		mov	_decode_stack[ebp],bl
		inc	ebp
		cmp	eax,255
		ja	again
doneit:
		mov	_decode_stack[ebp],al
		mov	_character,al
		inc	ebp
		mov	_numdecode,ebp
		mov	ebx,_next_code
		shl	ebx,3
		add	ebx,_dict
		mov	[ebx],al
		mov	eax,_old_code
		mov	[ebx+4],eax
		inc	_next_code
		mov	eax,_new_code
		mov	_old_code,eax
		jmp	outer

readbit:	; mask in dh, rack in dl, preserves ecx
		mov	bl,cl
		mov	cl,_current_code_bits
		xor	eax,eax
		mov	ebp,80000000h
		rol	ebp,cl
		mov	cl,bl
getloop:    cmp	dh,80h
		jne	noget
		mov	dl,[esi]
		inc	esi
noget:	test	dl,dh
		jz	noor
		or	eax,ebp
noor:		ror	dh,1
		shr	ebp,1
		jnz	getloop
		ret


done:
		mov	_numdecode,ebx
		sub	temp,edi
		mov	_RAMPtr,esi
		mov	_RAMRack,dl
		mov	_RAMMask,dh
		popad
		mov	eax,temp
		neg	eax
		ret
dobump:
		inc	_current_code_bits
		jmp	inner
doflush:
		mov	_next_code,FIRST_CODE
		mov	_current_code_bits,9
		call	readbit
		mov	_old_code,eax
		mov	_character,al
		mov	_decode_stack,al
		mov	_numdecode,1
		jmp	outer

asmexpand_	endp


end