; ticker.s
; Sits on TickerV and fills Replay sound buffers when necessary.

; SWI code
XOS_AddCallBack			EQU 0x20054

; Structure offsets
O_codec				EQU 0
O_mute				EQU 4
O_sfr				EQU 8
O_pw				EQU 12
O_semaphore			EQU 16
O_ticker_registered		EQU 17
O_tick_callback_registered	EQU 18
O_finished_callback_registered	EQU 19
O_fill_needed			EQU 20
O_finished			EQU 21

O_bufferA			EQU 16
O_bufferB			EQU 20

O_needs_fill			EQU 4

fill_result_Finished		EQU 4

	AREA |Replay$$Code|, CODE, READONLY

	IMPORT cmhg_tick_callback
	IMPORT cmhg_finished_callback

	EXPORT ticker_handler

 DCB	"ticker_handler", 0
 ALIGN

ticker_handler
	STMFD	sp!, {r0-r3, r8, r9, r12, lr}
	LDRB	r1, [r12, #O_semaphore]
	; Mustn't do anything if semaphore already set
	TEQ	r1, #0
	LDMNEFD	sp!, {r0-r3, r8, r9, r12, pc}
	MOV	r1, #1
	STRB	r1, [r12, #O_semaphore]
	; Read whether sample buffers need filling
	LDR	r1, [r12, #O_codec]
	LDR	r2, [r1, #O_bufferB]
	LDR	r1, [r1, #O_bufferA]
	LDR	r1, [r1, #O_needs_fill]
	LDR	r2, [r2, #O_needs_fill]
	; If finished, check whether both buffers are empty
	LDR	r0, [r12, #O_sfr]
	TEQ	r0, #fill_result_Finished
	BNE	check_if_fill_needed
	TEQ	r1, #0
	TEQNE	r2, #0
	MOVEQ	r1, #0
	STREQB	r1, [r12, #O_semaphore]
	LDMEQFD	sp!, {r0-r3, r8, r9, r12, pc}
	LDR	r0, =cmhg_finished_callback
	MOV	r2, #O_finished_callback_registered
	B	set_callback
check_if_fill_needed
	ORRS	r1, r1, r2
	STREQB	r1, [r12, #O_semaphore]
	LDMEQFD	sp!, {r0-r3, r8, r9, r12, pc}
	LDR	r0, =cmhg_tick_callback
	MOV	r2, #O_tick_callback_registered
set_callback
	LDR	r1, [r12, #O_pw]

	; Call the SWI
	SWI	XOS_AddCallBack
	MOVVC	r1, #1
	STRVCB	r1, [r12, r2]

	LDMFD	sp!, {r0-r3, r8, r9, r12, pc}


local_tick_callback
	STMFD	sp!, {r0}
	MOV	r0, #0
	STRB	r0, [r12, #O_tick_callback_registered]
	MOV	r0, #1
	STRB	r0, [r12, #O_fill_needed]
	LDMFD	sp!, {r0}
	MOV	pc, lr

local_finished_callback
	STMFD	sp!, {r0}
	MOV	r0, #0
	STRB	r0, [r12, #O_finished_callback_registered]
	MOV	r0, #1
	STRB	r0, [r12, #O_finished]
	LDMFD	sp!, {r0}
	MOV	pc, lr


	END
