4 ; Calling SWIs under all versions of RISC OS
6 ; © 1996-1998 Straylight
9 ;----- Licensing note -------------------------------------------------------
11 ; This file is part of Straylight's core libraries (corelib)
13 ; Corelib is free software; you can redistribute it and/or modify
14 ; it under the terms of the GNU General Public License as published by
15 ; the Free Software Foundation; either version 2, or (at your option)
18 ; Corelib is distributed in the hope that it will be useful,
19 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ; GNU General Public License for more details.
23 ; You should have received a copy of the GNU General Public License
24 ; along with Corelib. If not, write to the Free Software Foundation,
25 ; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 [ :LNOT::DEF:swihack__dfn
29 ;----- Main code ------------------------------------------------------------
33 ; On entry: Registers for SWI call
34 ; R10 == SWI number to call
36 ; On exit: As from the SWI
38 ; Use: On first call, works out the right way to call SWIs. On
39 ; subsequent calls, the vector is snapped to the right place.
41 |_swihack| DCD |__swihack|
43 ; --- Initial sorting out and dispatching routine ---
45 |__swihack| STMFD R13!,{R0,R1,R14} ;Store some registers away
46 MOV R0,#0 ;Read feature flags
47 SWI XOS_PlatformFeatures ;Read the features then
48 ADRVC R0,|_swihack_call| ;If SWI there, call directly
49 ADRVS R0,|_swihack_build| ;Otherwise build the call
50 STR R0,|_swihack| ;Store the value away
51 LDMFD R13!,{R0,R1,R14} ;Restore the registers
52 TEQP R14,#0 ;Reset flags from R14
53 LDR PC,|_swihack| ;And snap the pointer
55 ; --- Dispatch to OS_CallASWI ---
57 |_swihack_call| MOV R12,R14 ;Save the return address
58 SWI OS_CallASWI ;Just call the SWI: easy
59 |_ret_R12| MOV PC,R12 ;And return to caller
61 ; --- Dispatch by building code dynamically ---
64 STMFD R13!,{R14} ;Save the return address
65 BIC R10,R10,#&FF000000 ;Clear the opcode byte
66 ORR R10,R10,#&EF000000 ;And make it SWIAL
67 LDR R14,|_ret_R12| ;And load the return instr
68 STMFD R13!,{R10,R14} ;Save code on the stack
69 MOV R12,PC ;Set up return address
70 MOV PC,R13 ;And call the code
71 ADD R13,R13,#8 ;Reclaim stack space
72 LDMFD R13!,{PC} ;And return with SWI's flags
78 ;----- That's all, folks ----------------------------------------------------