Initial revision
[ssr] / StraySrc / Libraries / Core / s / swihack
1 ;
2 ; swihack
3 ;
4 ; Calling SWIs under all versions of RISC OS
5 ;
6 ; © 1996-1998 Straylight
7 ;
8
9 ;----- Licensing note -------------------------------------------------------
10 ;
11 ; This file is part of Straylight's core libraries (corelib)
12 ;
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)
16 ; any later version.
17 ;
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.
22 ;
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.
26
27 [ :LNOT::DEF:swihack__dfn
28
29 ;----- Main code ------------------------------------------------------------
30
31 ; --- |_swihack| ---
32 ;
33 ; On entry: Registers for SWI call
34 ; R10 == SWI number to call
35 ;
36 ; On exit: As from the SWI
37 ;
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.
40
41 |_swihack| DCD |__swihack|
42
43 ; --- Initial sorting out and dispatching routine ---
44
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
54
55 ; --- Dispatch to OS_CallASWI ---
56
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
60
61 ; --- Dispatch by building code dynamically ---
62
63 |_swihack_build|
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
73
74 LTORG
75
76 ]
77
78 ;----- That's all, folks ----------------------------------------------------
79
80 END