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