
	.arm
	.align		4
	
	.include	"sound_direct.i"
	
	;**** Samplebufferlänge kann beliebig geändert werden
	
	.set	SAMPLE_BUFFER_LENGTH		,1024
	.set	SAMPLE_BUFFER_LENGTH_LN2	,10
	
	.global		play_sound_irq
	.type		play_sound_irq,function
	.global		play_sound
	.type		play_sound,function
	
;*****************************************************************
;*
;* play_sound_irq
;*
;* r7 = &struct SD (S_LENGTH)	
;*	
	
play_sound_irq

	;**** stop dma

	stmfd	sp!,{r0-r7}

	mov	r0,#$4000000
	add	r1,r0,#$100
	add	r2,r0,#$200
	
	strh	r3,[r0,#$c6]		;REG_DMA1CNT_H=0; //stop DMA	
	
	;**** test against end
	
	ldr	r5,[r7,#S_SD_STOP]
	cmp	r5,#0
	bne	play_sound_irq_end
		
	;**** CNT--	
		
	ldr	r4,[r7,#S_SD_SAMPLE_CNT]
	sub	r4,r4,#1
	str	r4,[r7,#S_SD_SAMPLE_CNT]
	
	;**** wenn Null stop dma
	
	cmp	r4,#0
	moveq	r5,#1
	streq	r5,[r7,#S_SD_STOP]	
		
	;**** sample buffer + lkength
			
	ldr	r3,[r7,#S_SD_SAMPLE]
	
	;**** reload dma
	
	ldr	r4,[r7,#S_SD_CON]			;
	tst	r4,#2
	moveq	r4,r0		;zu DMA 1
	addne	r4,r0,#12	;zu DMA 2
	
	str	r3,[r4,#$bc]		;dma1=source
	add	r3,r0,#$a0
	str	r3,[r4,#$c0]		;dma1=$040000a0
	mov	r3,#$b600
	strh	r3,[r4,#$c6]		;dma1ctrl
	
	ldr	r3,[r7,#S_SD_SAMPLE]
	add	r3,r3,#SAMPLE_BUFFER_LENGTH
	str	r3,[r7,#S_SD_SAMPLE]
	
	;reload timer 1	

	mvn	r0,#0
	mov	r3,#SAMPLE_BUFFER_LENGTH		
	sub	r3,r0,r3
	
	ldr	r4,[r7,#S_SD_CON]
	tst	r1,#1
	addne	r1,r1,#4	;zu timer 2
	
	strh	r3,[r1,#$4]		
	mov	r3,#$c4
	strh	r3,[r1,#$6]		

play_sound_irq_end

	ldmfd	sp!,{r0-r7}
	bx	lr	
	
nothing	.long	0
	
;*****************************************************************
;*
;* play_sound
;*
;* r0  = sample
;* r1  = sample_length
;* r2  = $ffff-16777216/FREQ
;* r3  = dma+kanal   (0 = DMA 1, 1 = DMA 2)
;* r4  = timer (0 = timer 1, 1 = timer 2)
;* r10 = &struct SD (S_LENGTH)
;*	
	
play_sound

	stmfd	sp!,{r0-r12}

	;**** init
	
	str	r0,[r10,#S_SD_SAMPLE]
	
	and	r3,r3,#$1				;sicher ist sicher		
	and	r4,r4,#$1				;sicher ist sicher
	
	orr	r12,r4,r3,lsl #1			;
	str	r12,[r10,#S_SD_CON]			;
		
	mov	r3,r1, lsr #SAMPLE_BUFFER_LENGTH_LN2
	str	r3,[r10,#S_SD_SAMPLE_CNT]			;/
	mov	r3,r3, lsl #SAMPLE_BUFFER_LENGTH_LN2
	sub	r9,r1,r3				;Rest
	mov	r11,r2
	
	cmp	r3,#0
	moveq	r0,#1		;bei keinen weiteren durchlauf setze dma bei irq auf aus
	movne	r0,#0
	str	r0,[r10,#S_SD_STOP]
	
	;**** timer 0 sample rate, timer 1/2 irq

	mov	r6,#$4000000
	add	r7,r6,#$100
	add	r8,r6,#$200
	
	mov	r0,#$000f	
	tst	r12,#2
	orreq	r0,r0,#$0b00		;FIFOA
	orrne	r0,r0,#$b000		;FIFOB
	mov	r1,#$0080		
	mov	r2,#0			
	
	strh	r2,[r6,#$80]		
	strh	r0,[r6,#$82]		
	strh	r1,[r6,#$84]		

	ldr	r0,[r10,#S_SD_SAMPLE]
	add	r1,r6,#$a0
	mov	r2,#$b600
	
	tst	r12,#2
	moveq	r3,r6		;zu DMA 1
	addne	r3,r6,#12	;zu DMA 2
	
	str	r0,[r3,#$bc]				
	str	r1,[r3,#$c0]			
	strh	r2,[r3,#$c6]		

	mvn	r0,#0
	sub	r0,r0,r9		;spiele erst rest
	mov	r1,#$c4			;cascade
	
	tst	r12,#1
	moveq	r3,r7		;zu timer 1
	addne	r3,r7,#4	;zu timer 2
	
	strh	r0,[r3,#$4]		
	strh	r1,[r3,#$6]		

	mov	r0,#$10
	mov	r1,#$1
	
	strh	r0,[r8,#$0]		
	strh	r1,[r8,#$8]		

	mov	r1,#$80

	strh	r11,[r7,#$0]		
	strh	r1,[r7,#$2]		
	
	ldmfd	sp!,{r0-r12}
	bx	lr	
	
	.end
	
	
				