OS ClaimOSSWI (Select)

RISC OS Select provides an API for other modules to intercept OS SWIs. It's intended for internal use only by RISC OS and so isn't documented. The following is understood to be the current situation, but is subject to change.

Note that this method will not provide you with a SWI name-number translation, so you'll only be able to call SWIs implemented in the way by number unless the SWI is already named.

OS_ClaimOSSWI (&77)
On entry
 * R0 = Reason code: 0 to claim, 1 to release
 * R1 = OS SWI number to claim
 * R2 = routine to call
 * R3 = private word pass to routine in R12

On exit
 * unknown

Add or remove an entry in the OS module SWI dispatch table, so that your routine is called instead of the OS' version. Note this only works for OS_ prefixed SWIs, not SWIs provided by other modules. It is not clear if it's possible to pass on calls to the previous claimant.

The routine should behave as the target SWI would. The flags should be returned in R14 (26 bit OSs) or the PSR (32 bit OSs). Thus 26 bit code should return with 'MOVS pc,r14'.

OS_ReleaseSWI (&63)
These SWIs were added to the OS SWI name table in RISC OS 3.5, but were not implemented. Under Select it seems they act as follows: This should definitely not be relied upon.
 * OS_ClaimSWI(swi,code,private) calls OS_ClaimOSSWI(0,swi,code,private)
 * OS_ReleaseSWI(swi,code,private) calls OS_ClaimOSSWI(1,swi,code,private)

It has been suggested they are also implemented by DDT, but this has not been confirmed.

Pre-Select RISC OS
On pre-Select versions of RISC OS 3/4 it is necessary to edit the kernel dispatch table directly. This begins at &1F033FC, one address word for every OS SWI. SWIs return by branching to &1F037FC. Your routine must remember the address of the previous claimant's routine and replace it in the dispatch table when releasing your chosen SWI. This isn't very robust if there are multiple claimants of a single SWI.

An example of this in action may be seen in the HAL26 module, notably in init_foundpodule and os_hardware.

RISC OS 5 implements the kernel table in the same way, but it has moved. It is possible (on RISC OS 5 only) to read its position with OS_ReadSysInfo 6.