
	.global asm_mix_buffer
	.global asm_downsample_mix_buffer
	.global asm_downsample_mix_buffer_looped
	.global asm_flush_work_buffer
	.section	.iwram,"ax",%progbits
	.arm
	.align
	.text

@ void asm_mix_buffer(u16* vals, const s8* data, u32 vol, u32 mix_len)
@												r0							r1				r2			r3
asm_mix_buffer:
@	mov ip, sp
	stmfd	sp!, {r4-r5}
	
1:
@ while(mix_len > 0)

	@ grab current sample
	ldrsb	r4, [r1], #1
	@ multply by volume
	mul		r5, r4, r2
	ldrsh	r4, [r0]
	add		r5, r4, r5, lsr #8
	@ and write out
	strh	r5, [r0], #2
	
	subs	r3, r3, #1
	bgt		1b

	ldmfd	sp!, {r4-r5}
	bx		lr

@ void asm_downsample_mix_buffer(u16* vals, const s8* data, u32 vol, u32 mix_len, u32 scale_low, u32 scale_high)
@																			r0							r1				r2			r3							r4				r5
asm_downsample_mix_buffer:
	mov ip, sp
	stmfd	sp!, {r4-r9}
	ldmfd	ip, {r4-r5} @ get args 5 and 6
	
	@ shift scale_low up so that overflows will trigger the carry
	mov		r4, r4, lsl #16

	mov		r6, #0	@ mix_count - fractional part
	mov		r7, #0	@ mix_pos - integer part
1:
@ while(mix_len > 0)

	@ grab current sample
	ldrsb	r8, [r1, +r7]
	@ multply by volume
	mul		r9, r8, r2
	ldrsh	r8, [r0]
	add		r9, r8, r9, lsr #8
	@ and write out
	strh	r9, [r0], #2

	@ add scale value to source position
	adds	r6, r6, r4
	adc		r7, r7, r5	@ if mix_count overflows, will add an extra 1 to mix_pos
	
	subs	r3, r3, #1
	bgt		1b

	ldmfd	sp!, {r4-r9}
	bx		lr


@ void asm_downsample_mix_buffer_looped(u16* vals, const s8* data, u32 vol, u32 mix_len, u32 scale_low, u32 scale_high, u32 cur, u32 loop_start, u32 loop_end)
@																			r0							r1				r2					r3						r4							r5						r6							r7				r8
asm_downsample_mix_buffer_looped:
	mov ip, sp
	stmfd	sp!, {r4-r12}
	ldmfd	ip, {r4-r8} @ get args 5 and 6
	
	@ shift scale_low up so that overflows will trigger the carry
	mov		r4, r4, lsl #16

	mov		r9, #0	@ mix_count - fractional part
	mov		r10, r6	@ mix_pos - integer part
1:
@ while(mix_len > 0)

	@ grab current sample
	ldrsb	r11, [r1, +r10]
	@ multply by volume
	mul		r12, r11, r2
	ldrsh	r11, [r0]
	add		r12, r11, r12, lsr #8
	@ and write out
	strh	r12, [r0], #2

	@ add scale value to source position
	adds	r9, r9, r4
	adc		r10, r10, r5	@ if mix_count overflows, will add an extra 1 to mix_pos
	
	@ check for looping
	cmp		r10, r8
	blt		2f

	@ jump back to front of loop
	add		r10, r10, r7
	sub		r10, r10, r8
2:
	subs	r3, r3, #1
	bgt		1b

	ldmfd	sp!, {r4-r12}
	bx		lr


@ void asm_flush_work_buffer(s16* in, s8* out, u32 mix_len)
@												r0							r1				r2
asm_flush_work_buffer:
	stmfd	sp!, {r4-r5}

@ set up clipping table
	ldr		r5, =cliptable
	add		r5, r5, #256
	
1:
	ldrsh	r3, [r0], #2		@ grab mixed value
	mov		r3, r3, asr #1	@ scale down a bit
	ldrsh	r4, [r5, r3]		@ load clipped value from clipping table
	strb	r4, [r1], #1		@ and store

	subs	r2, r2, #1
	bgt		1b

	ldmfd	sp!, {r4-r5}
	bx		lr

@ table of values for clip code
cliptable:
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-127
	.byte	-126
	.byte	-125
	.byte	-124
	.byte	-123
	.byte	-122
	.byte	-121
	.byte	-120
	.byte	-119
	.byte	-118
	.byte	-117
	.byte	-116
	.byte	-115
	.byte	-114
	.byte	-113
	.byte	-112
	.byte	-111
	.byte	-110
	.byte	-109
	.byte	-108
	.byte	-107
	.byte	-106
	.byte	-105
	.byte	-104
	.byte	-103
	.byte	-102
	.byte	-101
	.byte	-100
	.byte	-99
	.byte	-98
	.byte	-97
	.byte	-96
	.byte	-95
	.byte	-94
	.byte	-93
	.byte	-92
	.byte	-91
	.byte	-90
	.byte	-89
	.byte	-88
	.byte	-87
	.byte	-86
	.byte	-85
	.byte	-84
	.byte	-83
	.byte	-82
	.byte	-81
	.byte	-80
	.byte	-79
	.byte	-78
	.byte	-77
	.byte	-76
	.byte	-75
	.byte	-74
	.byte	-73
	.byte	-72
	.byte	-71
	.byte	-70
	.byte	-69
	.byte	-68
	.byte	-67
	.byte	-66
	.byte	-65
	.byte	-64
	.byte	-63
	.byte	-62
	.byte	-61
	.byte	-60
	.byte	-59
	.byte	-58
	.byte	-57
	.byte	-56
	.byte	-55
	.byte	-54
	.byte	-53
	.byte	-52
	.byte	-51
	.byte	-50
	.byte	-49
	.byte	-48
	.byte	-47
	.byte	-46
	.byte	-45
	.byte	-44
	.byte	-43
	.byte	-42
	.byte	-41
	.byte	-40
	.byte	-39
	.byte	-38
	.byte	-37
	.byte	-36
	.byte	-35
	.byte	-34
	.byte	-33
	.byte	-32
	.byte	-31
	.byte	-30
	.byte	-29
	.byte	-28
	.byte	-27
	.byte	-26
	.byte	-25
	.byte	-24
	.byte	-23
	.byte	-22
	.byte	-21
	.byte	-20
	.byte	-19
	.byte	-18
	.byte	-17
	.byte	-16
	.byte	-15
	.byte	-14
	.byte	-13
	.byte	-12
	.byte	-11
	.byte	-10
	.byte	-9
	.byte	-8
	.byte	-7
	.byte	-6
	.byte	-5
	.byte	-4
	.byte	-3
	.byte	-2
	.byte	-1
	.byte	0
	.byte	1
	.byte	2
	.byte	3
	.byte	4
	.byte	5
	.byte	6
	.byte	7
	.byte	8
	.byte	9
	.byte	10
	.byte	11
	.byte	12
	.byte	13
	.byte	14
	.byte	15
	.byte	16
	.byte	17
	.byte	18
	.byte	19
	.byte	20
	.byte	21
	.byte	22
	.byte	23
	.byte	24
	.byte	25
	.byte	26
	.byte	27
	.byte	28
	.byte	29
	.byte	30
	.byte	31
	.byte	32
	.byte	33
	.byte	34
	.byte	35
	.byte	36
	.byte	37
	.byte	38
	.byte	39
	.byte	40
	.byte	41
	.byte	42
	.byte	43
	.byte	44
	.byte	45
	.byte	46
	.byte	47
	.byte	48
	.byte	49
	.byte	50
	.byte	51
	.byte	52
	.byte	53
	.byte	54
	.byte	55
	.byte	56
	.byte	57
	.byte	58
	.byte	59
	.byte	60
	.byte	61
	.byte	62
	.byte	63
	.byte	64
	.byte	65
	.byte	66
	.byte	67
	.byte	68
	.byte	69
	.byte	70
	.byte	71
	.byte	72
	.byte	73
	.byte	74
	.byte	75
	.byte	76
	.byte	77
	.byte	78
	.byte	79
	.byte	80
	.byte	81
	.byte	82
	.byte	83
	.byte	84
	.byte	85
	.byte	86
	.byte	87
	.byte	88
	.byte	89
	.byte	90
	.byte	91
	.byte	92
	.byte	93
	.byte	94
	.byte	95
	.byte	96
	.byte	97
	.byte	98
	.byte	99
	.byte	100
	.byte	101
	.byte	102
	.byte	103
	.byte	104
	.byte	105
	.byte	106
	.byte	107
	.byte	108
	.byte	109
	.byte	110
	.byte	111
	.byte	112
	.byte	113
	.byte	114
	.byte	115
	.byte	116
	.byte	117
	.byte	118
	.byte	119
	.byte	120
	.byte	121
	.byte	122
	.byte	123
	.byte	124
	.byte	125
	.byte	126
	.byte	127
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
	.byte	128
