; bitbuster.s
;-----------------------------------------------------------
; BitBuster v1.2 VRAM Depacker v1.1 - 16Kb version
; HL = RAM/ROM source ; DE = VRAM destination
;-----------------------------------------------------------

	.module bitbuster

	; global from this code

    .globl  _bitbuster
    ; void bitbuster (void *data, unsigned vram_offset);
	
	.area _CODE

_bitbuster:
    pop     bc
    pop     hl
    pop     de
    push    de
    push    hl
    push    bc
    
	di

; VRAM address setup
	ld	a,e
	out	(0xbf),a
	ld	a,d
	or	#0x40
	out	(0xbf),a

; Skips 4 bytes data header
;	inc	hl
;	inc	hl
;	inc	hl
;	inc	hl

; Initialization
	ld	a,#128
	exx
	ld	de,#1
	exx

; Main depack loop
Depack_loop:
	add	a,a
	jp	nz,$1
	ld	a,(hl)
	inc	hl
	rla
$1:
    jp	c,Compressed
	ld	c,#0xbe
	outi
	inc	de
	jp	Depack_loop

; Compressed data
Compressed:
	ld	c,(hl)
	inc	hl
Match:
    ld	b,#0
	bit	7,c
	jr	z,Match1
	add	a,a
	jp	nz,$2
	ld	a,(hl)
	inc	hl
	rla
$2:
    rl	b
	add	a,a
	jp	nz,$3
	ld	a,(hl)
	inc	hl
	rla
$3:
    rl	b
	add	a,a
	jp	nz,$4
	ld	a,(hl)
	inc	hl
	rla
$4:
    rl	b
	add	a,a
	jp	nz,$5
	ld	a,(hl)
	inc	hl
	rla
$5:
    jp	c,Match1
	res	7,c
Match1:
    inc	bc
	exx
	ld	h,d
	ld	l,e
	ld	b,e
Gamma_size:
	exx
	add	a,a
	jp	nz,$6
	ld	a,(hl)
	inc	hl
	rla
$6:	
    exx
	jp	nc,Gamma_size_end
	inc	b
	jp	Gamma_size
Gamma_bits:
	exx
	add	a,a
	jp	nz,$7
	ld	a,(hl)
	inc	hl
	rla
$7:
    exx
	adc	hl,hl
Gamma_size_end:
	djnz	Gamma_bits
Gamma_end:
	inc	hl
	exx
	jp	c,Depack_out
	push	hl
	exx
	push	hl
	exx
	ld	h,d
	ld	l,e
	sbc	hl,bc
	pop bc
	push	af
$8:
    ld	a,l
	out	(0xbf),a
	ld	a,h
	nop			; VDP timing
	out	(0xbf),a
	nop     		; VDP timing
	in	a,(0xbe)
	ex	af,af'
	ld	a,e
	nop			; VDP timing
	out	(0xbf),a
	ld	a,d
	or	#0x40
	out	(0xbf),a
	ex	af,af'
	nop                     ; VDP timing
	out	(0xbe),a
	inc	de
	cpi
	jp	pe,$8
	pop	af
	pop	hl
	jp	Depack_loop

; Depacker exit
Depack_out:
	ei
	ret

