;	Decrunch30.s
;	-to decrunch data compressed with BtoC v2.5
;	or uper
;	Copyright © 1992-1994 by Stefano Reksten
;

	section text,code

	xdef	_Decrunch30

_Decrunch30
	movem.l	d1-d5/a0-a1,-(sp)	; save registers

	move.l	(a1)+,d0		; compressed with
	cmp.l	#'BTOC',d0		; BtoC v2.5
	beq	ok_go			; or upper ?
	moveq	#0,d0
	bra	end			; no -> exit

ok_go
	move.l	(a1)+,d0		; d0 = data_size
					; or: how many bytes left
					; to decrunch.
	move.b	(a1)+,d1		; d1 = most_used
					; d2 = byte_counter
					; d3 = current_byte
	moveq	#0,d4
	move.b	(a1)+,d4		; d4 = max_counter
loop
	cmp.b	(a1),d1			; if ( *data_ptr!=most_used )
	beq	explode
	move.b	(a1)+,(a0)+		; *mem_ptr++=*data_ptr++;
	sub.l	#1,d0			; decrunched++;
	beq	end
	bra	loop
	
explode
	add.l	#1,a1			; data_ptr++;
	moveq	#0,d2
	move.b	(a1)+,d2		; byte_counter = *data_ptr++;
	cmp.b	d2,d4			; if ( byte_counter > max_counter )
	bhi	else
	sub.l	d4,d2			; byte_counter-=max_counter;
	beq	skip_byt
	move.b	(a1)+,d3		; current_byte = *data_ptr++;
	bra	expl
skip_byt				; exploding byte
	move.b	(a1)+,d5		; procedure.
	moveq	#7,d2
	move.b	d1,(a0)+		; puts 1 most_used
skip_loop
	btst	d2,d5
	bne	put_byte
	move.b	d1,(a0)+		; else put most_used
	bra	ok
put_byte
	move.b	(a1)+,(a0)+
ok
	dbra	d2,skip_loop
	sub.l	#9,d0
	bra	done
else
	move.b	d1,d3			; current_byte = most_used;

expl
	sub.l	d2,d0			; decrunched += byte_counter;
	sub.b	#1,d2
exploop
	move.b	d3,(a0)+		; *mem_ptr++ = current_byte
	dbra	d2,exploop		; while ( byte_counter-- )

done
	tst.l	d0
	beq	all_done
	bra	loop
all_done
	moveq	#1,d0
end
	movem.l	(sp)+,d1-d5/a0-a1
	rts

	END
