;***********************************************
;	shuf_.asm -- extract static Huffman coding
;***********************************************
			page	0, 128

include	amscls.inc
$_init	GEN

CGROUP	GROUP	TEXT
DGROUP	GROUP	DATA,BSS

TEXT	segment byte public 'CODE'
		assume	cs:CGROUP, ds:DGROUP, ss:DGROUP
TEXT	ends

DATA	segment byte public 'DATA'
DATA	ends

BSS		segment byte public 'DATA'
np_		dw		1 dup (?)
BSS		ends

TEXT	segment byte public 'CODE'
		assume	cs:CGROUP, ds:DGROUP, ss:DGROUP

;
;void decode_start_st0(void)
;

		public	decode_start_st0_
decode_start_st0_:
		mov		word ptr DGROUP:[n_max_], 286
		mov		word ptr DGROUP:[maxmatch_], 0100h
		call	init_getbits_
		mov		word ptr DGROUP:[np_], 128
		mov		blocksize, 0
		ret


;
;void encode_p_st0(unsigned short j)
;

		public	encode_p_st0_
encode_p_st0_:
		push	cx
		push	ax
		mov		bx, ax
		mov		cl, 6
		shr		bx, cl
		mov		al, pt_len_[bx]
		shl		bx, 1
		mov		bx, pt_code_[bx]
		call	putcode_
		mov		al, 6
		pop		bx
;		and		bx, 3fh
		call	putbits_
		pop		cx
		ret
TEXT	ends

DATA	segment byte public 'DATA'
		public	fixed_
fixed_		db		3
			db		1
			db		4
			db		12
			db		24
			db		48
			db		0

fixed1_		db		2
			db		1
			db		1
			db		3
			db		6
			db		13
			db		31
			db		78
			db		0
DATA	ends

TEXT	segment byte public 'CODE'
		assume	cs:CGROUP, ds:DGROUP, ss:DGROUP

;
;static void ready_made(int method)
;

		public	ready_made_
ready_made_:
	push	cx
	push	dx
	push	si
	push	di
	cld
	mov		si, offset DGROUP:fixed_
	$_if <or ax, ax>, NZ
		mov		si, offset DGROUP:fixed1_
	$_endif
	mov		cl, [si]
	inc		si
	xor		ax, ax
	mov		dx,	ax
	mov		ch, al
	stc
	rcr		dx, cl
	mov		bx, offset DGROUP:pt_len_
	mov		di, offset DGROUP:pt_code_
	$_do
		$_while <cmp [si], ch>, E
			inc		cx
			inc		si
			shr		dx, 1
		$_enddo
		mov		[bx], cl
		inc		bx
		stosw
		add		ax, dx
		inc		ch
	$_until <cmp ch, byte ptr np_>, AE
	pop		di
	pop		si
	pop		dx
	pop		cx
	ret


;
;void encode_start_fix(void)
;

		public	encode_start_fix_
encode_start_fix_:
	mov		word ptr DGROUP:[n_max_], 314
	mov		word ptr DGROUP:[maxmatch_], 60
	mov		word ptr DGROUP:[np_], 64
	call	init_putbits_
	call	start_c_dyn_
	xor		ax, ax
	call	ready_made_
	ret


;
;static void read_tree_c(void)	/* read tree from file */
;

read_tree_c_:
	push	cx
	push	dx
	push	di
	cld
	push	ds
	pop		es
	mov		di, offset DGROUP:c_len_
	mov		cx, 3
	$_while <TRUE>
		$_do
			mov		al, 1
			call	getbits_
			$_if <or ax, ax>, NZ
				mov		al, 4
				call	getbits_
				inc		ax
			$_endif
			stosb
		$_until <LOOP>
		$_break , <cmp di, offset DGROUP:c_len_ + 286>, AE
		$_if <cmp al, 1>, E, AND
		$_c  <cmp word ptr -3[di], 0101h>, E
			xor		ax, ax
			mov		cx, 286
			sub		di, 3
			rep		stosb
			mov		ax, 9
			call	getbits_
			mov		cx, 4096
			mov		di, offset DGROUP:c_table_
			rep		stosw
			jmp		retRT_c_
		$_endif
		mov		cx, 286 - 3
	$_enddo
	mov		ax, 286
	mov		bx, offset DGROUP:c_len_
	mov		cx, 12
	mov		dx, offset DGROUP:c_table_
	call	make_table_
retRT_c_:
	pop		di
	pop		dx
	pop		cx
	ret

;
;static void read_tree_p(void)	/* read tree from file */
;

read_tree_p_:
	push	cx
	push	dx
	push	di
	cld
	push	ds
	pop		es
	mov		di, offset DGROUP:pt_len_
	mov		cx, 3
	$_while <TRUE>
		$_do
			mov		al, 4
			call	getbits_
			stosb
		$_until <LOOP>
		$_break , <cmp di, offset DGROUP:pt_len_ + 128>, AE
		$_if <cmp al, 1>, E, AND
		$_c  <cmp word ptr -3[di], 0101h>, E
			xor		ax, ax
			mov		cx, 128
			sub		di, 3
			rep		stosb
			mov		cx, 4096
			mov		di, offset DGROUP:pt_table_
			rep		stosw
			jmp		retRT_p_
		$_endif
		mov		cx, 128 - 3
	$_enddo
retRT_p_:
	pop		di
	pop		dx
	pop		cx
	ret


;
;void decode_start_fix(void)
;

		public	decode_start_fix_
decode_start_fix_:
	push	cx
	push	dx
	mov		n_max_, 314
	mov		maxmatch_, 60
	call	init_getbits_
	mov		np_, 64
	call	start_c_dyn_
	xor		ax, ax
	call	ready_made_
	mov		ax, np_
	mov		bx, offset DGROUP:pt_len_
	mov		cx, 8
	mov		dx, offset DGROUP:pt_table_
	call	make_table_
	pop		dx
	pop		cx
	ret
TEXT	ends

DATA	segment byte public 'DATA'
blocksize	dw		0
DATA	ends



TEXT	segment byte public 'CODE'
		assume	cs:CGROUP, ds:DGROUP, ss:DGROUP

;
;ushort decode_c_st0(void)
;

		public	decode_c_st0_
decode_c_st0_:
	push	cx
	push	si
	$_if <sub blocksize, 1>, C
		push	dx
		mov		al, 16
		call	getbits_
		dec		ax
		mov		blocksize, ax
		call	read_tree_c_
		mov		al, 1
		call	getbits_
		$_if <or ax, ax>, NZ
			call	read_tree_p_
		$_else
			mov		ax, 1
			call	ready_made_
		$_endif
		mov		ax, 128
		mov		bx, offset DGROUP:pt_len_
		mov		cx, 8
		mov		dx, offset DGROUP:pt_table_
		call	make_table_
		pop		dx
	$_endif
	mov		bx, bitbuf_
	mov		cl, 4
	shr		bx, cl
	shl		bx, 1
	mov		si, c_table_[bx]
	$_if <cmp si, 286>, B
		mov		al, c_len_[si]
		call	fillbuf_
	$_else
		mov		al, 12
		call	fillbuf_
		mov		ax, bitbuf_
		$_do
			$_if <shl ax, 1>, C
				mov		si, right_[si]
			$_else
				mov		si, left_[si]
			$_endif
		$_until <cmp si, 286>, B
		mov		al, c_len_[si]
		sub		al, 12
		call	fillbuf_
	$_endif
	$_if <cmp si, 285>, E
		mov		al, 8
		call	getbits_
		add		si, ax
	$_endif
	mov		ax, si
	pop		si
	pop		cx
	ret


;
;ushort decode_p_st0(void)
;{

		public	decode_p_st0_
decode_p_st0_:
	push	cx
	push	si
	mov		bl, byte ptr bitbuf_ + 1
	xor		bh, bh
	shl		bx, 1
	mov		si, pt_table_[bx]
	$_if <cmp si, np_>, B
		mov		al, pt_len_[si]
		call	fillbuf_
	$_else
		mov		al, 8
		call	fillbuf_
		mov		ax, bitbuf_
		$_do
			$_if <shl ax, 1>, C
				mov		si, right_[si]
			$_else
				mov		si, left_[si]
			$_endif
		$_until <cmp si, np_>, B
		mov		al, pt_len_[si]
		sub		al, 8
		call	fillbuf_
	$_endif
	mov		al, 6
	mov		cl, al
	call	getbits_
	shl		si, cl
	add		ax, si
	pop		si
	pop		cx
	ret

		EXTRN	init_putbits_:near
		EXTRN	putbits_:near
		EXTRN	fillbuf_:near
		EXTRN	make_table_:near
		EXTRN	start_c_dyn_:near
		EXTRN	getbits_:near
		EXTRN	init_getbits_:near
		EXTRN	putcode_:near

TEXT	ends

		EXTRN	c_table_:word
		EXTRN	c_len_:byte
		EXTRN	pt_table_:word
		EXTRN	pt_code_:word
		EXTRN	pt_len_:byte
		EXTRN	right_:word
		EXTRN	left_:word
		EXTRN	maxmatch_:word
		EXTRN	n_max_:word
		EXTRN	bitbuf_:word

		END
