@ apLib decruncher for ARM
@
@ Based on the M68000 version by MML 2010
@ Size optimized (164 bytes) by Franck "hitchhikr" Charlet. 
@
@ Thumb version by Mic 2010 (178 bytes)

	.section .text
	.align 
	
	.global		aplib_decrunch
	.code 16
	.thumb_func

@ r0 = packed data, r1 = dest
aplib_decrunch:
	push	{r4-r7,lr}
	mov	r6,#1
copy_byte:
	ldrb	r4,[r0]
	strb	r4,[r1]
	add	r0,#1
	add	r1,#1
next_sequence_init:
	mov	r7,#0
next_sequence:
	bl	get_bit
	bcc	copy_byte
	bl	get_bit
	bcc	code_pair
	bl	get_bit
	mov	r4,#0
	bcc	short_match
	mov	r5,#4
get_offset:
	bl	get_bit
	adc	r4,r4
	sub	r5,#1
	bne	get_offset			
	cmp	r4,#0	
	beq	write_byte
	neg	r4,r4
	ldrb	r4,[r1,r4]        
write_byte:
	strb	r4,[r1]
	add	r1,#1
	b	next_sequence_init
code_pair:
	bl	decode_gamma
	mov	r4,r2
	sub	r4,#2
	bne	normal_code_pair
	tst	r7,r7
	bne	normal_code_pair
	mov	r4,r8
	bl	decode_gamma
	b	copy_code_pair
normal_code_pair:
	add	r4,r7
	sub	r4,#1	
	ldrb	r5,[r0]
	add	r0,#1
	lsl	r4,#8
	orr	r4,r5
	bl	decode_gamma
	mov	r5,r4
	cmp	r5,#128
	bcs	cmp1
	add	r2,#2
	b	continue_short_match
cmp1:
	lsr	r5,#8
	cmp	r5,#0x7D
	bcc	cmp2
	add	r2,#1
cmp2:
	cmp	r5,#5
	bcc	continue_short_match
	add	r2,#1
	b	continue_short_match
get_bit:	
	sub	r6,#1
	bne	still_bits_left
	mov	r6,#8
	ldrb	r3,[r0]
	add	r0,#1
	lsl	r3,#24
still_bits_left:
	lsl	r3,#1
	bx	lr
decode_gamma:
	push	{lr}
	mov	r2,#1
get_more_gamma:
	bl	get_bit
	adc	r2,r2
	bl	get_bit
	bcs	get_more_gamma
	pop	{pc}
short_match:
	mov	r2,#1
	ldrb	r4,[r0]
	add	r0,#1
	lsr	r4,#1
	beq	end_decrunch
	adc	r2,r2
continue_short_match:
	mov	r8,r4
copy_code_pair:
	neg	r4,r4
loop_do_copy:		
	ldrb	r5,[r1,r4]
	strb	r5,[r1]
	add	r1,#1
	sub	r2,#1
	bne	loop_do_copy	
	mov	r7,#1	
        b   	next_sequence   
end_decrunch:
	@ In situations where it's known that this function will be called only by other Thumb functions
	@ it's possible to save 4 bytes by replacing the three below instructions with a single pop {r4-r7,pc}
	pop	{r4-r7}
	pop	{r0}
	bx	r0


	



