
; bytekiller

; a0 = crunched data start
; a4 = decrunched data start
unpack:
	movem.l	d1-d7/a4,-(sp)
	;lea BKFile,a0				; a0 gepackte Daten/ Datei 
	movem.l	(a0),d5-d7			; d5= crunched, d6=decrunched, d7=chk
	move.l	d6,d1				; d1= unpacked data length
	;lea BK_DEST,a4				; a4 Ziel - buffer_decrunch
	move.l	a4,d6				; d6= pointer to start of decrunched area (Start entpackte Daten)
	add.l	d1,a4				; a4= pointer to end of decrunched area (Start+Länge -> vom Ende beginnen)							
	
	bsr	decrunch
	movem.l	(sp)+,d1-d7/a4
	rts

decrunch:
; a0 = crunched data start
; a4 = pointer to end of decrunched area
; d5 = crunched size
; d6 = pointer to start of decrunched area

	; init bytekiller decruncher, get first word
	lea	8(a0,d5.l),a0		; a0 ptr to current word to decrunch
	move.l	(a0),d0
	eor.l	d0,d7

bytekiller_decrunch:
	lsr.l	#1,d0
	bne	.1
	bsr	nextword
.1:	bcs	.cmd1xx
	moveq	#8-1,d4
	moveq	#1,d3
	lsr.l	#1,d0
	bne	.2
	bsr	nextword
.2:	bcs	.copy_n_from_d

	; cmd 00: nnn [dddd dddd]  -  copy n+1 times next d to *dest
	moveq	#3-1,d4
	bsr	getbits
	move.w	d2,d3

.copy_d_from_stream:
; copy n+1 times next 8-bit word from stream to *dest
; d3 = n
	moveq	#8-1,d4
.3:	lsr.l	#1,d0
	bne	.4
	bsr	nextword
.4:	roxl.l	#1,d2
	dbf	d4,.3
	move.b	d2,-(a4)
	dbf	d3,.copy_d_from_stream
	bra	check_done

.cmd111:
	; cmd 111: nnnn nnnn [dddd dddd]  -  copy n+9 times next d to *dest
	moveq	#8-1,d4
	bsr	getbits
	move.w	d2,d3
	addq.w	#8,d3			; n+8
	bra	.copy_d_from_stream

.cmd1xx:
	moveq	#2-1,d4
	bsr	getbits
	cmp.b	#2,d2
	blt	.cmd10x
	cmp.b	#3,d2
	beq	.cmd111

	; cmd 110: nnnn nnnn dddd dddd dddd
	; copy n+1 times *(dest+d) to *dest
	moveq	#8-1,d4
	bsr	getbits			; n
	move.w	d2,d3
	moveq	#12-1,d4		; 12 d-bits
	bra	.copy_n_from_d

.cmd10x:
	; cmd 100: dddd dddd d  -  copy 3 times *(dest+d) to *dest
	; cmd 101: dddd dddd dd -  copy 4 times *(dest+d) to *dest
	moveq	#9-1,d4
	add.w	d2,d4			; 9 or 10 d-bits
	addq.w	#2,d2
	move.w	d2,d3			; n = cmd&3 + 2

.copy_n_from_d:
	; copy n+1 times from *(dest+d) to *dest
	; d4 = bitcount for d -1
	; d3 = n
	bsr	getbits			; get d -> d2
	lea	(a4,d2.w),a1
.copyloop:
	move.b	-(a1),-(a4)
	dbf	d3,.copyloop

check_done:
	cmp.l	a4,d6
	blt	bytekiller_decrunch

	move.l	d7,d0			; return checksum
	rts

getbits:
; d4 = bits to get - 1
; -> d2 = result, extended to 16 bits

	clr.w	d2
.1:	lsr.l	#1,d0
	bne	.2
	bsr	nextword
.2:	roxl.l	#1,d2
	dbf	d4,.1
	rts
	
nextword:
; Get the next 32-bit word into the decrunching stream.
; Load the next block from disk when needed.
; a0 = pointer to current word in stream
; d7 = checksum
; -> d7 = new checksum
; -> d0 = next word, X/C = next bit

	move.l	-(a0),d0
	eor.l	d0,d7
	move.w	#$10,ccr
	roxr.l	#1,d0
	rts