| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 | ; 32 bit version
; SWI numbers
OS_File             *  &8
OS_Module           *  &1e
XOS_AddCallBack     *  &20054
XOS_RemoveCallBack  *  &2005f
        GET     h.RegNames
        EXPORT  DMA_Handler
	EXPORT	AddSineWaves
	IMPORT |callback_entry|
	IMPORT |sound_entry|
	IMPORT |sin_tab|
        AREA   Assemb , CODE, READONLY
; pointers to data items
ADR_callback_entry
		DCD    callback_entry
ADR_sound_entry
		DCD     sound_entry
ADR_sin_tab
		DCD	sin_tab
DMA_Handler
;**********
; fill the sound buffer of the linear sound handler
; preserve r11,r12,r13 (fp,ip,sp)
	MOV	r5,ip		; need to save ip
	MOV	ip,sp		;set up a stack
	STMFD	sp!, {fp,ip,lr}
	STMFD	sp!, {r5}
	MOV	r12,r0		; put the module_data word in r12
	BL	sound_entry     ; call C function through veneer in CMHG
	; returns with r0=1 set callback,  r1=module_data address
	CMP	r0,#1
	BNE	DMA_return
;---------
	TEQ	pc,pc
	MRSEQ	r8, CPSR	; 32bit version of call SWI from IRQ mode
	MOVNE	r8,pc
	ORR	r9,r8,#3
	MSREQ	CPSR_c, r9
	TEQNEP	r9,#0
	NOP
	STR	r14, [r13,#-4]!
;---------
	; r1=module_data address
	LDR	r0,ADR_callback_entry  ; call C function through CMHG veneer
	SWI	XOS_AddCallBack
;---------
	LDR	r14, [r13],#4  ; 32bit version of 'reenter original processor mode'
	TEQ	pc,pc
	MSREQ	CPSR_c, r8
	TEQNEP	r8,#0
	NOP
;---------
DMA_return
	LDMFD	sp!,{ip}
	LDMFD   sp, {fp,sp,pc}
AddSineWaves
;total += AddSineWaves(waveph, h_switch_sign, maxh, harmspect);
; using this assembler routine increases overall speed by about 7.5%
; define the USE_ASSEMBLER_1 macro in speech.h to enable this routine
; input:  r0=waveph  r1=h_switch_sign  r2=maxh  r3=harmspect
; local:  r5=sin_tab r6=total  r7=h  r8=theta
; return(total)
	MOV	ip,sp
	STMFD	sp!, {r5-r9,ip,lr}
	LDR	r5,ADR_sin_tab
	MOV	r6,#0		; total = 0
	MOV	r0,r0,LSL #16
	MOV	r8,r0		; theta = waveph
	MOV	r7,#1
as1
	MOV	ip,r8,LSR #21
	LDR	r9,[r5,ip,LSL #1]	; sin_tab[theta >> 5]
	MOV	r9,r9,LSL #16
	MOV	r9,r9,ASR #16
	LDR	ip,[r3,r7,LSL #2]	; harmspect[h]
	MLA	r6,r9,ip,r6
	ADD	r8,r8,r0		; theta += waveph
	ADD	r7,r7,#1		; h++
	CMP	r7,r1
	BLE	as1
	RSB	r6,r6,#0		; change sign
as2
	MOV	ip,r8,LSR #21
	LDR	r9,[r5,ip,LSL #1]	; sin_tab[theta >> 5]
	MOV	r9,r9,LSL #16
	MOV	r9,r9,ASR #16
	LDR	ip,[r3,r7,LSL #2]	; harmspect[h]
	MLA	r6,r9,ip,r6
	ADD	r8,r8,r0		; theta += waveph
	ADD	r7,r7,#1		; h++
	CMP	r7,r2
	BLE	as2
	MOV	r0,r6
	LDMFD	sp, {r5-r9,sp,pc}
   END
 |