; PackFire 1.2e - (tiny depacker) by Neural
; 65816 version by Mic 


.DEFINE PACKFIRE_ZP_BASE 	$80

; DirectPage variables
.DEFINE PACKFIRE_CNT	PACKFIRE_ZP_BASE
.DEFINE PACKFIRE_SRC_PTR	PACKFIRE_CNT+2
.DEFINE PACKFIRE_SRC_PTR2	PACKFIRE_SRC_PTR+3
.DEFINE PACKFIRE_BITS	PACKFIRE_SRC_PTR2+3
.DEFINE PACKFIRE_OFFS	PACKFIRE_BITS+1
.DEFINE PACKFIRE_OFFS2 PACKFIRE_OFFS+2
.DEFINE PACKFIRE_LEN PACKFIRE_OFFS2+2
.DEFINE PACKFIRE_DIST PACKFIRE_LEN+2
.DEFINE PACKFIRE_TEMP PACKFIRE_DIST+2
.DEFINE PACKFIRE_TEMP2 PACKFIRE_TEMP+2

    
; In:
; A = source bank
; Y = source offset
; X = dest offset
; DBR = dest bank
unpackfire_tiny:
	php
	rep		#$10
	sep		#$20
	sta		PACKFIRE_SRC_PTR+2
	stz		PACKFIRE_SRC_PTR+1
	stz		PACKFIRE_SRC_PTR
	sta		PACKFIRE_SRC_PTR2+2
	sty		PACKFIRE_SRC_PTR2
	rep		#$20
	tya
	clc
	adc		#26			
	tay
	sep		#$20
	lda		[PACKFIRE_SRC_PTR],y
	iny
	sta		PACKFIRE_BITS
_upt_lit_copy:
	lda		[PACKFIRE_SRC_PTR],y
	sta.w	$0000,x
	iny
	inx
_upt_main_loop:
	jsr		_upt_get_bit
	bcs		_upt_lit_copy
	rep		#$20
	lda		#$FFFF
	sta		PACKFIRE_OFFS
_upt_get_index:
	inc		PACKFIRE_OFFS
	jsr		_upt_get_bit
	rep		#$20
	bcc		_upt_get_index
	lda		PACKFIRE_OFFS
	cmp		#$10
	bne		+
	jmp		_upt_depack_stop
+:
	jsr		_upt_get_pair
	lda		PACKFIRE_OFFS
	sta		PACKFIRE_OFFS2
	cmp		#3
	bcc		_upt_in_range
	stz		PACKFIRE_OFFS
_upt_in_range:
	phx
	lda		#4
	ldx		PACKFIRE_OFFS
	cpx		#1
	bne		+
	lsr		a
+:
	sta		PACKFIRE_LEN
	sep		#$20
	lda.l	_upt_table_dist,x
	rep		#$20
	sta		PACKFIRE_DIST
	plx
	jsr		_upt_get_bits
	jsr		_upt_get_pair
	phy
	txa
	sec
	sbc 	PACKFIRE_OFFS
	tay
	ldx		PACKFIRE_OFFS2
	sep		#$20
_upt_copy_bytes:
	lda.w	$0000,y
	sta 	(PACKFIRE_OFFS),y
	iny
	dex
	bne		_upt_copy_bytes
	rep 	#$20
	tya
	clc
	adc 	PACKFIRE_OFFS
	tax
	ply
	jmp		_upt_main_loop
_upt_table_dist: .db 16,48,32
_upt_get_pair:
	stz		PACKFIRE_CNT
_upt_calc_len_dist:
	lda		PACKFIRE_CNT
	and		#$0F
	sta		PACKFIRE_DIST
	bne		_upt_node
	lda		#1
	sta		PACKFIRE_TEMP2
_upt_node:
	lda		PACKFIRE_CNT
	lsr		a
	phy
	tay
	sep		#$20
	lda		[PACKFIRE_SRC_PTR2],y
	ply
	sta		PACKFIRE_LEN
	rep		#$20
	lda		#1
	sta		PACKFIRE_TEMP
	and		PACKFIRE_DIST
	beq		_upt_nibble
	lda		PACKFIRE_LEN
	lsr		a
	lsr		a
	lsr		a
	lsr		a
	sta		PACKFIRE_LEN
_upt_nibble:
	lda		PACKFIRE_TEMP2
	sta		PACKFIRE_DIST
	lda		PACKFIRE_LEN
	and		#$0F
	sta		PACKFIRE_LEN
-:
	cmp		#0
	beq		+
	asl		PACKFIRE_TEMP
	dea
	bra		-
+:
	lda		PACKFIRE_TEMP
	clc
	adc		PACKFIRE_TEMP2
	sta		PACKFIRE_TEMP2
	inc		PACKFIRE_CNT
	dec		PACKFIRE_OFFS
	bpl		_upt_calc_len_dist
_upt_get_bits:
	stz		PACKFIRE_OFFS
_upt_getting_bits:
	dec		PACKFIRE_LEN
	bpl		_upt_cont_get_bit
	lda		PACKFIRE_DIST
	clc
	adc		PACKFIRE_OFFS
	sta		PACKFIRE_OFFS
	rts
_upt_depack_stop:
	plp
	rts
_upt_cont_get_bit:
	jsr		_upt_get_bit
	rep		#$20
	rol		PACKFIRE_OFFS
	bra		_upt_getting_bits
_upt_get_bit:
	sep 	#$20
	asl		PACKFIRE_BITS
	bne		_upt_byte_done
	lda		[PACKFIRE_SRC_PTR],y
	iny
	rol		a
	sta		PACKFIRE_BITS
_upt_byte_done:
	rts
