Modules for Beginners, Part 5: Claiming Vectors
Most operating systems use vectors. In RISC OS quite a few of the SWIs use vectors. This means the vectored SWI does not jump directly to its routine held in the OS ROM but RISC OS looks up a memory address held in RAM (this RAM address is the vector reserved for the particular SWI), and jumps to that routine. Usually the address held in the vector is the standard ROM routine.
A designer of a module can claim a vector so that any vectored SWI can then jump to a different routine, hence altering the code for the SWI.
The new routine can do one of the following:
If the new routine replaces the ROM code this is known as intercepting the call, otherwise it is known as passing on the call.
So far I have been a little simplistic in the explanation of how vectors hold addresses. It is more accurate to visualise a vector as the start of a structure which contains pointers to the next claimant of the vector. This structure holds both the address of the start of the code and a pointer to the workspace for the code.
Because the vector is a structure, more than one routine can claim the vector. The claimant does not have to remember the previous owners address.
Vectors than be claimed and released by many pieces of software in any order. The last claimant of a vector will be the first to have its routine called, then the next most recent claimant and so on. If any of the claimants intercept a vector then all claimants more recent than this one will have there routines called, but none after this one. See the following examples.
Here there are 2 claimants both of them passing on the call.
If a 3rd claimant now intercepts the call then the following happens.
Notice how this claimants interception causes a 'short circuit' so that none of the previous claimants routines are called.
If a 4th claimant who passes on the call is added the following would occur.
How to Claim and Release Vectors
There are two SWI's to Claim and Release vectors called, not suprisingly, OS_Claim and OS_Release. They use registers R0 to R2 as follows.
So to Claim the Mouse vector (number &1A) the following code is added in the modules initialisation.
MOV R0,#&1A ;mouse vector number ADR R1,routinestartadd% ;start address of routine MOV R2,#0 ;R12 would have the value 0 in this case SWI "XOS_Claim" ;call the SWI,
To release the routine from the vector the same lines are used for R0 to R2 but then call SWI "XOS_Release".
In the following example the event vector is claimed. This vector is a little more complicated in that it is called whenever an event takes place. Events are generated by several devices, including the keyboard (whenever a key is pressed or released). So using this event we can check what key has been pressed or released.
Each event is numbered the keyboard event being 11 (another useful event is number 10 the mouse button change event). Look at PRM 1-152 onwards for the complete list of events.
To claim this event the following code is used.