summaryrefslogtreecommitdiff
path: root/asmcall.s
diff options
context:
space:
mode:
Diffstat (limited to 'asmcall.s')
-rw-r--r--asmcall.s63
1 files changed, 63 insertions, 0 deletions
diff --git a/asmcall.s b/asmcall.s
new file mode 100644
index 0000000..1523187
--- /dev/null
+++ b/asmcall.s
@@ -0,0 +1,63 @@
+; This source code in this file is licensed to You by Castle Technology
+; Limited ("Castle") and its licensors on contractual terms and conditions
+; ("Licence") which entitle you freely to modify and/or to distribute this
+; source code subject to Your compliance with the terms of the Licence.
+;
+; This source code has been made available to You without any warranties
+; whatsoever. Consequently, Your use, modification and distribution of this
+; source code is entirely at Your own risk and neither Castle, its licensors
+; nor any other person who has contributed to this source code shall be
+; liable to You for any loss or damage which You may suffer as a result of
+; Your use, modification or distribution of this source code.
+;
+; Full details of Your rights and obligations are set out in the Licence.
+; You should have received a copy of the Licence with this source code file.
+; If You have not received a copy, the text of the Licence is available
+; online at www.castle-technology.co.uk/riscosbaselicence.htm
+;
+; > s.asmcall RCC 24-Mar-88
+;
+; This makes it possible to call code which scribbles on all the
+; registers with a standard ARM procedure call, e.g. from C.
+;
+; If the code called also scribbles on lk, you must regain control
+; by forcing it to branch to asmcall_exit.
+;
+; NB it relies on scribbling on memory addressed pc-relative, so it
+; won't work if the code area is not writable.
+;
+
+r0 RN 0
+r1 RN 1
+r2 RN 2
+r3 RN 3
+r4 RN 4
+ip RN 12
+lk RN 14
+pc RN 15
+
+ AREA |C$$code|, CODE, READONLY
+ EXPORT asmcall_call
+ EXPORT asmcall_exit
+
+asmcall_savedregs
+ DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 11 words for registers
+asmcall_call
+ ; Enter with r0: thing to call
+ ; r1, r2, r3: parameters for it
+
+ ADR ip, asmcall_savedregs
+ STMIA ip, {r4-lk}
+ MOV ip, r0
+ MOV r0, r1
+ MOV r1, r2
+ MOV r2, r3
+ MOV lk, pc
+ MOV pc, ip
+asmcall_exit
+ NOP ; 2 spurious instructions here in case the caller
+ NOP ; forgets to allow for prefetch ...
+ ADR ip, asmcall_savedregs
+ LDMIA ip, {r4-lk}
+ MOV pc, lk
+ END