;
; CDDL HEADER START
;
; The contents of this file are subject to the terms of the
; Common Development and Distribution License (the "Licence").
; You may not use this file except in compliance with the Licence.
;
; You can obtain a copy of the licence at RISC OS path @.^.LICENCE
; or  http://www.riscosdev.com/lanman98/LICENCE.CDDL
; See the Licence for the specific language governing permissions
; and limitations under the Licence.
;
; When distributing Covered Code, include this CDDL HEADER in each
; file and include the Licence file. If applicable, add the
; following below this CDDL HEADER, with the fields enclosed by
; brackets "[]" replaced with your own identifying information:
; Portions Copyright [yyyy] [name of copyright owner]
; 
; CDDL HEADER END
;
 
;    Copyright 1996 Warm Silence Software Ltd.  All rights reserved.

;    PHBG  20/1/97: Initial version

	GET h.SWINames

        AREA    |C$$code|, CODE, READONLY
|x$codeseg|

        EXPORT CallBackInit
	EXPORT CallBackAfter
	EXPORT CallBacksOff

CallBackInit ;(pw)
        LDR R1, pw_ref
        LDR R12, [R10, #-536]
        STR R0, [R12, R1]
 [ ATPCS32
        MOV PC, R14
 |
        MOVS PC, R14
 ]

CallBackAfter ;(c_function, argument, delay)
	STMFD	R13!, {R4-R6, R14}
        MOV     R3, R2
	LDR	R4, table_ref
	LDR	R12, [R10, #-536]
	ADD	R4, R12, R4
        LDR     R2, pw_ref
        LDR     R2, [R12, R2]
	MOV	R5, #256
	SWI	OS_IntOff
find_empty_rec
	LDR	R6, [R4]
	CMP	R6, #0
	BEQ	found_empty_rec
	ADD	R4, R4, #(4*3)
	SUBS	R5, R5, #1
	BNE	find_empty_rec
	SWI	OS_IntOn
 [ ATPCS32
        MSR     CPSR_f,#0
	LDMFD	R13!, {R4-R6, PC}
 |
	LDMFD	R13!, {R4-R6, PC}^
 ]
found_empty_rec
	SWI	OS_IntOn
	STMIA	R4, {R0-R2}
	MOV	R0, R3
        CMP     R0, #0
        BEQ     direct_callback
	ADR	R1, call_after_handler
	MOV	R2, R4
	SWI	XOS_CallAfter
 [ ATPCS32
        MSR     CPSR_f,#0
	LDMFD	R13!, {R4-R6, PC}
 |
	LDMFD	R13!, {R4-R6, PC}^
 ]
direct_callback
        ADR     R0, call_back_handler
        MOV     R1, R4
	SWI	XOS_AddCallBack
 [ ATPCS32
        MSR     CPSR_f,#0
	LDMFD	R13!, {R4-R6, PC}
 |
	LDMFD	R13!, {R4-R6, PC}^
 ]

CallBacksOff
	STMFD	R13!, {R4-R5, R14}
	LDR	R4, table_ref
	LDR	R12, [R10, #-536]
	ADD	R4, R12, R4
	MOV	R5, #256
kill_rec
	MOV	R0, #0
	STR	R0, [R4]
	ADR	R0, call_after_handler
	MOV	R1, R4
	SWI	XOS_RemoveTickerEvent
	ADR	R0, call_back_handler
	MOV	R1, R4
	SWI	XOS_RemoveCallBack
	ADD	R4, R4, #(4*3)
	SUBS	R5, R5, #1
	BNE	kill_rec
 [ ATPCS32
        MSR     CPSR_f,#0
	LDMFD	R13!, {R4-R5, PC}
 |
	LDMFD	R13!, {R4-R5, PC}^
 ]

table_ref
	DCD table

pw_ref
        DCD pw_copy

call_after_handler
	STMFD	R13!, {R0-R1, R14}
	LDR	R0, [R12]
	CMP	R0, #0
	LDMEQFD R13!, {R0-R1, PC}
	ADR	R0, call_back_handler
	MOV	R1, R12
	SWI	XOS_AddCallBack
	LDMFD	R13!, {R0-R1, PC}

call_back_handler
	STMFD	R13!, {R0-R12, R14}
	LDMIA	R12, {R1, R2, R3}
	CMP	R1, #0
	LDMEQFD R13!, {R0-R12, PC}

	; STFE	F7, [R13, #-12]!
	; STFE	F6, [R13, #-12]!
	; STFE	F5, [R13, #-12]!
	; STFE	F4, [R13, #-12]!
	; STFE	F3, [R13, #-12]!
	; STFE	F2, [R13, #-12]!
	; STFE	F1, [R13, #-12]!
	; STFE	F0, [R13, #-12]!

	MOV	R0, #0
	STR	R0, [R12]
	MOV     R10,R13,LSR #20
	MOV     R10,R10,LSL #20
	LDMIA   R10,{R4,R5}
	LDR     R12,[R3]
	LDMIB   R12,{R11,R12}
	STMIA   R10,{R11,R12}
	ADD     R10,R10,#0x21C
	MOV     R11,#0
	MOV	R0, R2
	MOV     R14,PC
	MOV     PC, R1
	SUB     R10,R10,#0x21C
	STMIA   R10,{R4,R5}

	; LDFE	F0, [R13], #12
	; LDFE	F1, [R13], #12
	; LDFE	F2, [R13], #12
	; LDFE	F3, [R13], #12
	; LDFE	F4, [R13], #12
	; LDFE	F5, [R13], #12
	; LDFE	F6, [R13], #12
	; LDFE	F7, [R13], #12

	LDMFD	R13!, {R0-R12, PC}

	AREA	|C$$data|, DATA

|x$dataseg|

        AREA |C$$zidata|,NOINIT

pw_copy % 4

table	% (256*3*4)

	END
