RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Modules


Introduction

A relocatable module is a piece of software which, when loaded into the machine acts as either an extension to the operating system or a replacement to an existing module in the operating system. Modules can contain programming languages or filing systems; they can be used to add new SWIs and * Commands.

Relocatable modules run in an area of memory known as the Relocatable Module Area (RMA) which is maintained by RISC OS. They are 'relocatable' because they can be loaded at any particular location in memory. Their code must therefore be relocatable.

RISC OS provides facilities for integrating modules in such a way that, to the user, they appear to be a full part of the system. For instance, the operating system responds to the *Help command, extracting automatically any relevant help text.

Several SWIs and * Commands are provided by the operating system for handling modules, such as one to load a module file from the filing system.

A major piece of software written for RISC OS should only be designed as a module if it fulfils the following requirements:

  • it is an extension to RISC OS or an enhancement to an existing RISC OS module
  • it is shared by many applications; for example the shared C library
  • it needs to be persistently RAM resident over many invocations (even then you should try to do this another way)
  • it is small enough

or if:

  • it is a desktop application - or part of one - which cannot be paged out (eg it has Econet control blocks active).

Such programs must use RMA for workspace, and are hence easiest to write as modules.

This chapter describes what is needed to write a module.

Overview

This chapter is divided into two basic areas; using modules and writing them.

Using modules

Use of modules is centralised around the SWI OS_Module. This contains a number of operations that can:

  • load, initialise, run and remove a module
  • examine and change the amount of RMA space used by a module
  • examine module details
  • modify instantiations of modules.

All of the operations that a program is likely to need to operate with modules are in this SWI. You could treat the RMA as a kind of filing system, since there are commands to load things into it, remove them and run them.

Some modules are supplied with the computer in ROM. These may be 'unplugged' and upgraded versions of them loaded into RMA. They may also be deliberately copied from ROM into RMA, since modules in RAM will execute significantly quicker than in ROM.

There are a number of * Commands that replicate several OS_Module commands at a command line level. You can also obtain convenient lists of all modules currently in the RMA and the system ROM using a * Command.

Instantiation

A module may be initialised more than once. This means that whilst only a single copy of the code is kept in memory, multiple copies of its workspace are created. The workspace is the area where all the data used by the module for dynamic storage is kept. Note that constant data, such as lookup tables is kept inside the main body of the module, with the code. Changing which workspace is used changes the context of the module and allows it to be used for several purposes concurrently. Each copy of the workspace, coupled with the code, is referred to as an instantiation. A module is deemed to be reincarnated when a new instantiation is created.

Only a single copy of the code is needed because it is not changed by being used concurrently. The data is the only thing that provides the context for an initialised module.

An example of the use of instantiations is in the module FileCore. This module provides a core of commands that are common to all filing systems with an ADFS structure, ie ADFS and RAMFS. It appears in one instantiation for each filing system that is using it.

For example, typing *Modules, you can see all the modules that are currently loaded, including the various instantiations of the FileCore module:

*Modules
...
28 03839698  018114C4  FileCore%RAM
   03839698  01804374  FileCore%ADFS
   03839698  00000000  FileCore%Base
...

This enables you to refer to particular instantiations of a module. For example:

*RMKill WaveSynth%Base

Writing a module

The core of all modules is the module header. It is a table of 11 entries, each a word in length. These are called by RISC OS to communicate with the module.

Module header

The entries in the header table describe the following things in the module. All but one are offsets to code or some larger piece of data, such as a string, or table:

  • Where to start executing in the module. This is used by languages and applications.
  • Where to call initialisation code. This has to be called before all the others.
  • Where to call finalisation code. This is called before removing the module. It allows the module to shutdown any hardware it is using and generally tidy up.
  • A title for the module.
  • A help string. This is used automatically by RISC OS when help is requested.
  • Detailed help on * Commands.
  • Entry points for * Commands. RISC OS will decode the * Commands and call the right entry point for a command for you.
  • A table to convert to and from SWI names and numbers.
  • Entry points for all the SWIs in the module.
  • The chunk number for the module. This is the number that is the base for SWI numbers. There can be up to 64 SWIs in a module, all offsets from this chunk number. This is the only entry in the header that isn't an offset.
  • Service call entry (see below).

All communication from RISC OS to a module takes place through this table. As you can see, several features are used by RISC OS without you having to write code to deal with them, such as the help text, and SWI names to numbers conversion.

Service calls

A number of special occurrences in RISC OS are passed around all the modules by RISC OS. Some of these can be claimed. This means that if a module decides that it wants to take control of that occurrence then it stops it being passed on to the rest of the modules. Others cannot be claimed and are used by RISC OS to broadcast some occurrence to all modules. Here is a brief list of the kinds of things that can be sent as service calls. The first part are claimable service calls:

  • Unknown command, OS_Byte, OS_Word, *Configure or *Status.
  • *Help has been called. This allows you to replace this command when you detect a particular help call being made.
  • Memory controller about to be remapped. This allows an application to stop a memory remapping if it doesn't want it to happen.
  • Application is about to start. This allows a module to prevent an application from starting. With this, a module could prevent any other tasks running.
  • Lookup file type. This converts the 3 byte file type into a string, such as 'BASIC' or 'Text'.
  • Various international services, such as handling different alphabets and keyboards.
  • The fast interrupt handler has been claimed/released. This is used by device drivers for high data rate devices that depend on the state of the fast interrupt system.

These are the service calls that cannot be claimed and are used to allow modules to perform some action to cope with the occurrence, without stopping it being passed on to all modules:

  • An error has occurred. This is called before the error handler, but is only for module's information, not claiming.
  • Reset is about to happen/has just happened.
  • Filing system re-initialise. This is called when FileSwitch has been re-initialised and this is broadcast to all filing systems that use it to do the same. This is necessary, because otherwise a filing system could get out of sync with the context in FileSwitch.
  • A screen mode change has occurred. This means that all modules can be aware of the screen state and re-read VDU variables, for instance.

By monitoring these service calls, a module can be aware of many things that are occurring outside its control in the system.

Technical Details

Module initialisation

When RISC OS is started it automatically initialises all modules in the computer. In RISC OS 2 it does so in the order it finds modules, omitting any that are unplugged.

The way in which the kernel initialises modules has been changed in later versions of RISC OS. If there is more than one version of the same module present in the main ROM, expansion cards or extension ROMs then only the newest version of the module is initialised, where newest means the version with the highest version number.

If there are two copies of the same version, then directly executable versions (ie in main ROM or in a 32-bit wide extension ROM) are considered newer. If they are equal in this respect, then the later one in scanning order is considered to be newer.

  1. The kernel first scans all modules in ROM (whether they be in the system ROM, expansion cards or extension modules), building a list of modules and their version numbers. It uses this list to determine which is the newest version of a particular module.
  2. The kernel then scans down the list of modules in the system ROM. For each module in this list, the kernel initialises the newest version of that module.

    Hence if an expansion card or extension ROM contains a newer version of a module in the main ROM, the kernel initialises that newer version at the point where the main ROM version would have been initialised. This allows main ROM modules to be replaced without any problems associated with initialisation order.

  3. The kernel next scans down the list of modules in expansion cards. For each module in this list, the kernel initialises the newest version of that module, but with the hardware address (in R11) corresponding to that of the expansion card.

    If a module is present both in the main ROM and in an expansion card, the kernel therefore initialises the newest version of that module when scanning the main ROM (as above), and then reinitialises the same module when scanning the expansion cards.

  4. The kernel finally scans down the list of modules in extension ROMs. For each module in this list, the kernel checks that it is the newest version of that module, and that it has not already been initialised in lieu of a module in the main ROM or on an expansion card. If a module meets both these criteria the kernel initialises it.

Using modules

OS_Module is the main application interface to modules. In its description you will find a complete list of its calls, and details of each of them.

A number of * Commands exist, most of which use OS_Module directly. Below is a table summarising OS_Module entries and the *Command equivalent.

Entry Meaning *Command equivalent
0 Run *RMRun
1 Load *RMLoad
2 Enter module-dependent - usually provided by the module, eg *BASIC
3 ReInit *RMReInit
4 Delete *RMKill
5 Describe RMA
6 Claim RMA space
7 Free RMA space
8 Tidy modules *RMTidy
9 Clear *RMClear
10 Insert module from memory
11 As above, and move to RMA *RMFaster (if in ROM)
12 Extract module information *Modules & *ROMModules
13 Extend block in RMA
14 Create new instantiation
15 Rename instantiation
16 Make preferred instantiation
17 Add expansion card module
18 Look-up module name
19 Enumerate ROM modules
20 Enumerate ROM modules with version

Tidying - as mentioned above - refers to finalising all the modules, moving them together so that free RMA space is in a single block, and then re-initialising them. This solves problems with memory fragmentation.

*RMEnsure is a command that will check that a given module and version number is loaded into memory, and will execute a specified command if it is not - such as loading a module from disc (which replaces the currently loaded version, if any), or generating an error.

*Unplug will disable the ROM version of a given module. This is useful, for example, to save the RAM workspace claimed by a module you do not need to use.

*RMInsert will reverse the action of *Unplug, without initialising any modules.

Workspace

The operating system allocates one word of private workspace to each module instantiation. Normally, the module will require more and it is expected that it will use this private word as a pointer to the workspace which it claims from the RMA using OS_Module 6. Whenever the system calls a module through one of its header fields, it sets R12 to point at this private word. Hence, if this word is a pointer to workspace, the module can obtain a pointer to its true workspace by performing the instruction:

LDR R12,[R12]

The system works on the assumption that the private word is a pointer to workspace claimed in the RMA. It therefore provides suitable default actions on that basis. For example, when a module is killed the system will attempt to free any workspace claimed using this pointer, after it has called the finalisation code.

Also, the system relocates the value held in a module's workspace pointer when the RMA is 'shuffled' as a result of an RMTidy call.

Note that workspace allocated through XOS_Module will always lie on an address &xxxxxxx4. This enables code written for time-critical software (eg sound voice generators and FIQ handlers) to be aligned within the module body.

Errors in module code

Any module code which provides system extensions (SWIs and * Commands) must behave in a manner which is compatible with the operating system if an error occurs. This means that only X SWIs are called, and if anything goes wrong, the module must:

  • set up R0 to point to the error block
  • preserve all appropriate registers
  • return with V set.

If no error has been encountered, V must be clear, and appropriate registers preserved on exit.

The above does not apply to application code within the module; this can follow any convention it wishes.

Module header format

The module indicates to the system if and where it wishes to be called by a module header. This contains offsets from the start of the module to code and information within the body of the module.

Offset Type Contains
&00 offset to code start code
&04 offset to code initialisation code
&08 offset to code finalisation code
&0C offset to code service call handler
&10 offset to string title string
&14 offset to string help string
&18 offset to table help and command keyword table
&1C number SWI chunk base number (optional)
&20 offset to code SWI handler code (optional)
&24 offset to table SWI decoding table (optional)
&28 offset to codet SWI decoding code (optional)

All modules must have fields up to &18. However, any of these offsets can be zero, (which means don't use this entry since the module does not contain the relevant data/code), apart from the title string. This is the offset to the zero-terminated name and if it is zero, the module cannot be referenced.

All code entries must be word aligned and inside the module code area, otherwise the checking performed by RISC OS will consider it invalid. All tables and strings must similarly be within the module or else it will be rejected.

The SWI handler fields are optional and are only used if they contain valid values.

The module header entries are described in detail in the following section of this chapter.

Service calls

Service calls are made from RISC OS to a module to indicate an occurrence of some kind. Some are claimable, and some are intended as broadcasts of the occurrence only. See the description in OS_ServiceCall for a complete list of all service calls. It is followed by details of each call. Some of these service calls will also be relevant to other parts of this manual that describe modules. For example, there are service calls that are provided explicitly to serve the International module.

OS_Byte 143 is an obsolete way of calling OS_ServiceCall. It is documented, but must not be used, as it is here only for compatibility with earlier Acorn operating systems.

Module entry points

Start code

Start executing at the start point of code in a module

Offset in header

&00

On entry

R0 = pointer to command string, including module name
R12 = pointer to private word for currently preferred instantiation of the module

On exit

Doesn't return unless error occurs.

Interrupts

Interrupts are enabled on entry
Fast interrupts are enabled

Processor Mode

Processor is in USR mode

Re-entrancy

Entry point is not re-entrant

Use

This is the offset to the code to call if the module is to be entered as the current application. An offset of zero implies that the module cannot be started up as an application, ie it is purely a service module and contains only a filing system or * Commands, etc.

This field need not actually be an offset. If it cannot be interpreted as such, ie it is not a multiple of four, or any bits are set in the top byte, then calling this field will actually execute what is assumed to be an instruction at word 0 in the module. This allows applications to have a branch at this position and hence be run directly, eg for testing. Once entered, a module may get the command line using OS_GetEnv.

Whenever the module is entered via this field, it becomes the preferred instantiation. Therefore R11 does not refer to the instantiation number.

You must exit using OS_Exit, or by starting another application without setting up an exit handler.

Start code is used by OS_Module with Run or Enter reason codes.

Initialisation Code

Set up the module, so that all other entry points are operating

Offset in header

&04

On entry

R10 = pointer to environment string (ie initialisation parameters supplied by caller of OS_Module)
R11 = I/O base or instantiation number (see below)
R12 = pointer to private word for this instantiation of the module.
If the private word [NOT EQUAL] 0, this implies reinitialisation after an OS_Module 8.
R13 = supervisor stack pointer

On exit

Must preserve processor mode and interrupt state
Must preserve R7 - R11 and R13
R0 - R6, R12, R14 and the flags (except V of course) can be corrupted

Interrupts

Interrupts are enabled
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Entry point is not re-entrant

Use

This code is called when the module is loaded and also after the RMA has been tidied (OS_Module with Tidy reason code). The module will not be called via any other entry point until this entry point has been called. Thus the initialisation code is expected to set up enough information to make all other entry points safe.

An offset of zero means that the module does not need any initialisation. The system does not provide any default actions.

The Initialisation code is used by OS_Module with Run, Load, ReInit and Tidy reason codes.

If the module is being re-entered after a OS_Module 'tidy', the private word may contain a non-zero value. This is the contents of the private word after the finalisation, relocated (if necessary) by the system.

Typical actions are claiming workspace (via OS_Module) and storing the workspace pointer in the private word. Other actions may include linking onto vectors, declaring the module as a filing system, etc. During initialisation, your module is not on the active module list, and so you cannot call SWIs in your own SWI chunk. Instead you must directly enter your own code.

You must not generate errors in your initialisation code. In particular, this means that you must call the error-returning (or 'X') form of SWIs, and must not call OS_GenerateError. For more details, see the chapter entitled Generating and handling errors.

If your module is unable to function - perhaps because of an error returned from a SWI it called - it can refuse to be initialised by returning an error in the usual way (ie by setting the V flag, and returning with R0 as an error pointer). The system removes the module and any workspace pointed to by its private word from the RMA. Note that in this case it does not call your module's finalisation code.

The module is also passed an 'environment string' pointer in R10 on initialisation. This points at any string passed after the module name given to the SWI.

R11 indicates where the module has come from: if R11 = 0, then the module was loaded from the filing system or ROM or is already in memory; if R11 is > &03000000, then the module was loaded from an expansion card and R11 points at the synchronous base of the expansion card. Other values of R11 mean that the module is being reincarnated and there are <R11> other instantiations of the module.

On exit (whether or not you are returning an error), use the link register passed in R14 to return:

MOV PC,R14

Finalisation Code

Called before killing the module

Offset in header

&08

On entry

R10 = fatality indication: 0 is non-fatal, 1 is fatal
R11 = instantiation number
R12 = pointer to private word for this instantiation of the module.
R13 = supervisor stack

On exit

Must preserve processor mode and interrupt state
Must preserve R7 - R11 and R13
R0 - R6, R12, R14 and the flags can be corrupted

Interrupts

Interrupt status is not altered
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Entry point is not re-entrant

Use

This is the reverse of initialisation. This code is called when the system is about to kill an instantiation of the module - either completely, or temporarily whilst it tidies the RMA.

If the call is fatal, the module's workspace is freed, and the workspace pointer is set to zero. If the call is non-fatal (eg the call is due to a tidy operation), the workspace (and the pointer) will be relocated by the module handler, assuming they were allocated using OS_Module's 'claim' entry.

The module is told whether the call is fatal or not by the contents of R10 as follows:

    R10 = 0 means a non-fatal finalisation
    R10 = 1 means a fatal finalisation

R11 contains the dynamic instantiation number: ie the position of the instantiation in the instantiation list. This will not be the same as the R11 given to initialisation. Position in the chain can vary and the length of the instantiation list can also change.

If the module generates an error on finalisation, then it remains in the RMA, and is assumed to still be initialised. The only way to remove the module from RMA in this state is by a hard reset.

If the module has no finalisation entry, its workspace is freed automatically, if the pointer contains a non-zero value.

Use link register given for normal exit. Set R0 and return with V set if refusing to die.

The module is (possibly temporarily) 'de-linked' when called, so you can't, for example, execute SWIs that you recognise yourself.

Used on OS_Module with ReInit, Delete, Tidy and Clear reason codes. Also when a module of the same name is loaded the old one is killed.

Service call handler

Called when a service call is issued

Offset in header

&0C

On entry

R1 = service number
R12 = pointer to private word for this instantiation of the module
R13 = a full, descending stack

On exit

R1 can be set to zero if the service is being claimed
R0, R2 - R8 can be altered to pass back a result, depending on the service call
Registers must not be corrupted unless they are returning values.
R12 may be corrupted

Interrupts

Interrupt status is unaltered
Fast interrupts are enabled

Processor Mode

Processor is in SVC or IRQ mode

Re-entrancy

Entry point may be re-entered by RISC OS, and so must be able to handle this

Use

This allows service calls to be recognised and acted upon. If the module does not wish to provide the service it should exit with R1 preserved. If it wishes to perform the service and to prevent other modules also performing it, it should set R1 to zero before returning, otherwise it should preserve the registers in order that other modules may have a chance to deal with the call. An offset of zero means that the module is not interested in any service calls.

It is important that you reject unrecognised service calls as quickly as possible. This example shows the recommended code to do so. It assumes the module recognises three service calls, but you can easily adapt it for other cases:

        TEQ R1,#Service_<1>
        TEQNE R1,#Service_<2>
        TEQNE R1,#Service_<3>
        MOVNES PC,LR                            ; reject unrecognised calls asap
        STMFD R13!,{ registers, LR }
        LDR R12,[R12]                           ; if workspace pointer required
        TEQ R1,#Service_<3>                     ; now find which call we've got
        BEQ svc_3
        TEQ R1,#Service_<2>
        BEQ svc_2
svc_1   code to handle service call 1          ; if not 3 or 2, then must be 1
        LDMFD R13!,{ registers, PC }^          ; and return
svc_2   code to handle service call 2        LDMFD R13!,{ registers, PC }^          ; and return
svc_3   code to handle service call 3        LDMFD R13!,{ registers, PC }^          ; and return

Some service calls can indicate an error condition by the contents of registers on exit (the V set convention cannot be used). Others, like unknown OS_Byte, can either claim the service, in which case there is no way of indicating an error, or ignore it, in which case an error will be given (if all modules ignore it). If you want to provide things like unknown OS_Bytes, and be able to generate an error for, say, invalid parameters, you should use the OS_Byte vector instead.

Note that only R0 - R8 can be passed into a service call.

The service call handler is used when a service call is issued or via an OS_Byte 143 or OS_ServiceCall. The service calls are described in the section on OS_ServiceCall.

Title string

Offset of a null-terminated module name

Offset in header

&10

Use

This is the offset of a null-terminated string which is used to refer to the module when OS_Module is called. The module name should be made up of alphanumeric characters and should not contain any spaces or control characters. This must be present for the module to be recognised.

Module names which contain more than one word should follow the convention of the system modules, eg 'FileSwitch', 'SpriteUtils'. The case of the letters in a module name isn't significant for the purposes of matching.

The string should be fairly short and descriptive, eg WindowManager or DiscToolkit.

The string is used by OS_Module with reason codes Delete, Enter and ReInit, and also by the *Modules, *RMEnsure and *ROMModules commands.

Help string

Used when *Help prints information from the module

Offset in header

&14

Use

This is the offset of a null-terminated string printed out by *Help before any information from the module, eg *Help Modules, *Help Commands. It is advisable that this string is present to avoid confusion. The string must not contain any control characters (except Tab, which tabs to the next multiple of eight column, or character 31 which acts as a 'hard' space) but may contain spaces.

To make the output of *Help Modules look neat, you should adopt the same spacing and naming conventions as the system modules. The format is as follows:

module_name Tab[Tab] v.vv (DD MMM YYYY)

The module name is followed by one or two Tab characters to make it appear sixteen characters long. The version number contains three digits and a full stop, eg '1.00'. The creation date is of the form 06 Jun 1987.

Help and command keyword table

Get help on * Commands or enter them

Offset in header

&18

Use

This table contains a list of keywords with associated help text and, in the case of commands, an entry address to the command code. Other associated data provides information on the type of command, the limits on the number of parameters it can take, etc.

It is used when OSCLI, *Status, *Configure and *Help wish to look for user-supplied keywords.

The string to match should contain only the valid characters for its entry type. For example, commands matched by OSCLI cannot contain any characters that have a special meaning in filenames. In general it is best to stick to alphanumeric characters and the '_' character. The case of the letters does not matter in command matching, but should be chosen for neat output from *Help. The standard adopted by the system modules is the form 'Echo', 'SetType' etc

The table consists of a sequence of entries, terminated by a zero byte. Each entry has the following format:


Format of entries in help and command keyword table

Code offset

The code offset is used for commands. A zero entry means that the string has help text only associated with it. The code is entered with these conditions:

On entry

R0 = pointer to the command tail, which you may not overwrite
R1 = number of parameters (as counted by OSCLI, which means space(s) separate parameters except within double quotation marks)
R12 = pointer to private word for this instantiation of the module
R13 = pointer to a full descending stack
R14 = return address

On exit

R0 = error pointer if anything goes wrong
R7 - R11 must be preserved

Interrupts

Interrupts are enabled on entry
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Entry point is not re-entrant

Information word

The information word contains limits on the number of parameters accepted by the command, and also 16 flags. The format is:

    Byte Contents
    0 Minimum number of parameters (0 - 255)
    1 OS_GSTrans map for first 8 parameters
    2 Maximum number of parameters (0 - 255)
    3 Flags

The command can, therefore, accept between zero and 255 parameters. OSCLI counts parameters by starting at the start of the command tail and looking for items (quoted strings or continuous characters) separated by spaces. This is why it is advisable to use spaces as parameter separators and not commas, as in commands which are compatible with the BBC series of microcomputers.

Byte 1 works as follows. Each bit corresponds to one parameter (bit zero of the byte equals the first parameter and so on). If the bit is set, the parameter is GSTrans'd before being passed on to the module. If the bit is clear, the parameter is passed directly to the module. This is useful for filing system commands which need to do filename transformations that are normally done by FileSwitch.

Note: If byte 1 is such that the final parameter is GSTrans'd, the command tail passed to the module will have a trailing space.

The flags are as follows:

Bit 31 = 1

The match string is a filing system command and is therefore only matched after OSCLI has failed to find the command in any of the module tables as a 'normal' command. OSCLI only looks at filing system commands in the filing system currently active. Commands that need this flag set are, therefore, the filing system-specific ones such as *Bye, *Logon, etc.

Bit 30 = 1

The string is to be matched by *Status and *Configure. The code in this case should scan the command tail and return a status string or set non-volatile memory as appropriate. The code is called with R0 set as follows:

    R0 = 0 *Configure has been issued with no option. The module prints a syntax string and returns.
    R0 = 1 *Status option has been issued. The module should print the currently configured status for this configuration option.

If R0 is neither of the above, it means that *Configure option has been issued; R0 is a pointer to the command tail with leading spaces skipped. The module must decode the arguments and set the configuration accordingly. If the command tail is incorrect, the module should return with V set and R0 indicating the error as follows:

    R0 = 0 Bad configure option
    R0 = 1 Numeric parameter needed
    R0 = 2 Configure parameter too large
    R0 = 3 Too many parameters
    R0 > 3 R0 is a pointer to an error block for *Configure to return

Note that this facility duplicates two of the service code entries. You should use this method in preference, as the OS performs decoding of the option keywords for you.

Bit 29 = 1

*Help offset refers to a piece of code to call for that keyword, instead of the offset of a text string. The code is called with the following entry conditions:

    R0 points at a buffer
    R1 is the buffer length
    R1 - R6 and R12 can be corrupted

On return, if R0 is non-zero, it is assumed to point at a zero-terminated string to pretty-print (see below).

Other flags

Other flags should be zero for upwards compatibility.

Invalid syntax message

The invalid syntax message is used by OSCLI as the text of an error message. If the parameters, which are given, fall outside the range specified. If a zero offset is given, a default 'Invalid number of parameters' error is given instead. See also Service_SyntaxError on Service_SyntaxError (Service Call &8C).

Help text

The help text is used by *Help. If a keyword in the *Help command tail matches the match string, then the help text is pretty-printed using the RISC OS internal token dictionary. Refer to OS_PrettyPrint for a full list of the token dictionary.

A zero offset means no help text is to be printed. The string may contain carriage returns to force newlines. Tab (ASCII 9) is also a special character; it forces alignment to the next multiple of eight columns. Finally, ASCII 31 is a 'hard space', around which words lines will not be split.

SWI chunk base number

The base of chunk numbers for the module

Offset in header

&1C

Use

This offset contains the base of chunk numbers for the module. Note that it is the only offset that does not contain a pointer. RISC OS reads this offset to enable it to call the module when a SWI using its chunk range is issued.

SWI handler code

Called to handle SWIs belonging to the module

Offset in header

&20

On entry

R0 - R9 are passed from the SWI caller by RISC OS
R11 = SWI number modulo Chunk Size (ie 0 - 63)
R12 = private word pointer
R13 = supervisor stack
R14 contains the flags of the SWI caller

On exit

R0 - R9 are returned to SWI caller by RISC OS
R10 - R12 may be corrupted

Interrupts

Interrupts on entry are in the same state as when the SWI instruction was issued
Fast interrupts are enabled

Your code should not explicitly enable interrupts, as if they are disabled on entry, there is likely to be a good reason for this - such as your SWI being called from an interrupt handling routine. If you do need to disable IRQs during an atomic operation, you should only do so for the minimum time possible, and should afterwards restore them to their previous state. Recommended code to do so is:

MOV     Rn, PC
ORR     Rm, Rn, #I_bit                   ; #I_bit is 1<<27
TEQP    Rm, #0                           ; disable interrupts
...
Your code for short atomic operation     ; must preserve Rn...
TEQP    Rn, #0                           ; restore interrupts

The TEQP instructions are not changing processor mode, but merely disabling IRQs in the current mode, so need not be followed by a no-op.

Processor Mode

Processor is in SVC mode

Re-entrancy

Your module may issue SWIs to itself; if it does, it must handle them

Use

These entries allow a module to ask to be given a range of otherwise unrecognized SWIs. The SWI chunk number is the base of the range to be intercepted. SWIs in the range:

base to (base + SWI chunk size - 1)

are passed to the handler code. The module SWI chunk size is defined by the operating system to be &40 (64). For example, this entry in the Wimp module is &400C0, implying that it can accept SWIs in the range &400C0 - &400FF.

These fields are optional; if they contain implausible values, the system will ignore them. The checks made are:

  • base is a multiple of the chunk size and has a 0 top byte
  • code offset is a multiple of four with the top six bits zero.

See the chapter entitled SWI numbers in detail for more details on SWI and chunk numbers.

When the SWI handler code is called, the SWI number reduced to the range 0 to (chunk size - 1) is passed in R11. The module then checks whether it is one which it recognises and if so, deals with it appropriately. The suggested code for doing this is:

.SWIentry
   LDR     R12, [R12]                            ; get workspace pointer
   CMP     R11, #(EndOfJumpTable - JumpTable)/4
   ADDLO   PC, PC, R11, LSL #2                   ; dispatch if in range
   B       UnknownSWIerror                       ; unknown SWI
.JumpTable
   B       MySWI_0
   B       MySWI_1
   ...............
   B       MySWI_n
.EndOfJumpTable
.UnknownSWIError
   STMFD   R13!, {R14}                           ; Push R14 to call SWI in SVC
   ADR     R0, ErrToken
   MOV     R1, #0
   MOV     R2, #0
   ADR     R4, ModuleTitle                       ; From module header
   SWI     "XMessageTrans_ErrorLookup"
   LDMFD   R13, {R14}                            ; Pull R14
   ORRS    PC, R14, #Overflow_Flag
.ErrToken
   EQUD    &1E6                                  ; Same as system message
   EQUS    "BadSWI"                              ; Token to look up
   EQUB    0
   ALIGN

Note that the address calculation on the PC to jump to the appropriate branch instruction relies on there being exactly one instruction between the ADDLO and the B MySWI_0 instruction.

The R14 given to the SWI code contains the flags of the SWI caller, except that V has been cleared. So, to return without updating the flags, use

MOVS PC, R14

Otherwise alter the link register, for example by executing

ORRS PC, R14, #Overflow_Flag

Note that all the flags returned to the system are returned to the caller, so user's conditional code must be written with this in mind.

Bit 17 in the given SWI number is not significant. The code is called on the assumption that it is the 'bit 17 set' version of the SWI. This means that the code must set R0 and return V set on encountering an error. Any error is then automatically dealt with by the system if the user actually asked for the 'bit 17 clear' version.

Warning

In versions of RISC OS prior to 4.0, the SWI handler code is not passed the value of R9 specified by the caller. The RISC OS SWI despatcher corrupts R9 before calling a module's SWI handler code, and on exit from the handler restores R9 to the value specified by the caller.

In RISC OS 4, the SWI despatcher passes R9 uncorrupted to and from the SWI handler code.

SWI decoding table

Pointer to table of SWI names

Offset in header

&24

Use

When the SWIs OS_SWINumberFromString and OS_SWINumberToString are called, there are two ways that the conversion can occur. If the table pointed to by this offset contains the string for the required entry, then that is used. If it isn't there and the table pointer is 0, then the following offset is called, to allow the module code to perform the conversion.

The table format is:

SWI group prefix
Name of 0th SWI
Name of 1st SWI
...
...
Name of nth SWI
0 byte to terminate

All names are null terminated. The group prefix is the first part of the full SWI name: ie the first SWI's full name is GroupPrefix_NameOf1st. For example, ShellCLI's table is:

EQUS "Shell"
EQUB 0
EQUS "Create"
EQUB 0
EQUS "Destroy"
EQUB 0

EQUB 0

In this example, the chunk base number is &405C0. The SWI &405C1 would therefore be converted into 'Shell_Destroy' if passed to OS_SWINumberToString.

The OS adds an 'X' if the SWI has bit 17 set, followed by the group prefix, followed by '_', then the individual SWI name. If the table does not contain enough entries, then the SWI name field is filled in by the offset from the chunk base (in decimal).

If the table field is zero, then the code field is used (see below). This field is also used when converting from strings to numbers.

SWI decoding code

Entry for code to convert to and from SWI number and string

Offset in header

&28

On entry

R12 = private word pointer
R13 = supervisor stack
R14 = return address

Text to number
R0 = any number less than zero
R1 = pointer to the string to convert (terminated by a control character)

Number to text
R0 = SWI number ANDed with 63: ie offset within module's chunk
R1 = pointer to output buffer
R2 = offset within output buffer at which to place the text
R3 = size of buffer

On exit

R12 preserved

Text to number
R0 = offset into chunk (0 - 63) if SWI recognised, <0 otherwise
R1 - R6 preserved

Number to text
R0 preserved
R1 preserved
R2 = updated by length of text
R3 - R6 preserved

Interrupts

Interrupts are enabled on entry
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Entry point is not re-entrant

Use

This entry is used where a SWI name is not defined in the SWI decode table. If it cannot be decoded, and the table pointer is 0, then return with the registers unchanged and RISC OS will provide a suitable default.

When converting from number to text, RISC OS will append a null at the position after the length you returned.

SWI Calls


OS_Byte 143
(SWI &06)

Issue module service call

On entry

R0 = 143
R1 = service type
R2 = argument for service

On exit

R0, R1 preserved
R2 = may contain a return argument

Interrupts

Interrupt status is not altered
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call is provided for compatibility with the BBC series of microcomputers, and is used for calling the modules' service entries. Only OS_ServiceCall should be used in new code.

Related SWIs

OS_ServiceCall

Related vectors

ByteV


OS_Module
(SWI &1E)

Perform a module operation

On entry

R0 = reason code
other registers are parameters and depend upon the reason code

On exit

R0 preserved
other register states depends on the reason code

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This SWI provides a number of calls to manipulate modules. The value in R0 describes the operation to perform as below:

R0

Meaning

Page

0

Run

OS_Module 0

1

Load

OS_Module 1

2

Enter

OS_Module 2

3

ReInit

OS_Module 3

4

Delete

OS_Module 4

5

Describe RMA

OS_Module 5

6

Claim

OS_Module 6

7

Free

OS_Module 7

8

Tidy

OS_Module 8

9

Clear

OS_Module 9

10

Insert module from memory

OS_Module 10

11

Insert module from memory and move into RMA

OS_Module 11

12

Extract module information

OS_Module 12

13

Extend block

OS_Module 13

14

Create new instantiation

OS_Module 14

15

Rename instantiation

OS_Module 15

16

Make preferred instantiation

OS_Module 16

17

Add expansion card module

OS_Module 17

18

Lookup module name

OS_Module 18

19

Enumerate ROM modules

OS_Module 19

20

Enumerate ROM modules with version

OS_Module 20

This call performs simple checks when deleting and moving modules. These actions give an error if the system 'thinks' you are applying them to a module currently active, for example, if you try to *RMKill BASIC from within BASIC.

This check is applied whenever the system is about to call a module's finalise entry. Hence simple applications need not keep checks on this explicitly. More complex modules which, for example, run subtasks, need to keep their own state checks in order to avoid being removed when they are due to be returned to at some point.

Many of the OS_Module calls refer to a module title. This has some general restrictions. The name passed is terminated by any control character or space and can be abbreviated with a full stop. For example, 'Eco.' is an abbreviation for 'Econet'. The title field in the module is similarly terminated by control characters and spaces. The pattern matching ignores the case of both strings, and allows any characters other than space or full stop. You should restrict your titles, however, to alphanumerics and '_' for future compatibility.

As usual, errors are indicated by V being set and an error pointer in R0. These errors may be generated by one of the modules, and the error block addressed by R0 might reside in a module's code. You should therefore not rely on the error block remaining in the same place across calls to OS_Module.

As the checks within this call cannot tell which instantiation of a module is active, no instantiation may die when one of them is the current application. The module name can also have an instantiation postfix. This consists of '%' followed by the instantiation name. This name field can be abbreviated in the same way as the module name. If no instantiation is given, the currently preferred instantiation is referenced.

In the following pages, the reason codes for this command are fully explained. The details of general SWI operation are as per this description.

Related SWIs

None

Related vectors

None


OS_Module 0
(SWI &1E)

Run

On entry

R0 = 0 (reason code)
R1 = pointer to pathname plus optional parameters

On exit

Does not return unless error occurs

Use

This call is equivalent to loading, initialising, and then entering the module. If the module can be started as an application, it will be, and so the call will not return.

Possible errors from RISC OS are 'File 'filename' not found', 'Not enough memory in module area' (or, under RISC OS 2, 'No room in RMA'), 'This is not a relocatable module'. The module itself may return errors such as 'Duplicate module refused to die', and 'Module refuses to initialise'.

Related reason codes

1, 2


OS_Module 1
(SWI &1E)

Load

On entry

R0 = 1 (reason code)
R1 = pointer to pathname and optional parameters

On exit

R0, R1 preserved

Use

This reason code attempts to claim a block of the RMA and *Loads the file if it has the correct file type of &FFA. The header fields of the module are then checked for validity.

If another module has the same name, it attempts to kill the duplicate module. This will give an error if the module refuses to die. Note that this allows system modules to be upgraded with new versions simply by loading the new version. All instantiations of the duplicate are killed.

It sets the private workspace word to 0, calls the module through its initialise address and links it to the end of the module list, or replaces the old module of the same name. The module is initialised as instantiation 'Base'.

The filename should be terminated suitably for OS_File. The terminator can be space, in which case there can be a parameter string after the filename to pass to the module initialisation.

Possible errors are 'File 'filename' not found', 'Not enough memory in module area' (or, under RISC OS 2, 'No room in RMA'), 'This is not a relocatable module', and other errors dependent on the module, such as 'Duplicate module refused to die', and 'Module refuses to initialise'.

Related reason codes

0, 2


OS_Module 2
(SWI &1E)

Enter

On entry

R0 = 2 (reason code)
R1 = pointer to module name
R2 = pointer to parameters

On exit

Does not return unless error occurs

Use

If the module doesn't have a start address, then this call simply returns. If it does, this call resets the supervisor stack pointer to the top of the stack, sets user mode and enters the module, hence making it the current application. Any specified instantiation will become the preferred instantiation. The possible error is 'Module 'modulename' not found'.

For a description of how a module is started up as an application, refer to OS_FSControl 2.

Related reason codes

0


OS_Module 3
(SWI &1E)

Reinitialise

On entry

R0 = 3 (reason code)
R1 = pointer to module name plus any parameters for initialisation

On exit

R0, R1 preserved

Use

This is equivalent to reloading the module. It is intended for use in forcing modules that have become confused into a sensible state, without having to reload them explicitly from the filing system. The instruction calls the module through its finalise address and deletes any workspace. It then calls it through its initialisation address to reinitialise it. If the module fails to initialise it is removed from the RMA. Possible errors are 'Module 'modulename' not found', and others dependent on the module.

Related reason codes

8, 9


OS_Module 4
(SWI &1E)

Delete

On entry

R0 = 4 (reason code)
R1 = pointer to module name

On exit

R0, R1 preserved

Use

This reason code (and *RMKill) kill off the currently preferred instantiation of the module or the one specified in the name. For example:

*RMKill FileCore%Base

This calls the module through its finalise address, frees any workspace pointed at by the private word, delinks the module from the module list and frees the space it was occupying. Possible errors are 'Module not found' and others dependent on the module.

Related reason codes

None


OS_Module 5
(SWI &1E)

Describe RMA

On entry

R0 = 5 (reason code)

On exit

R0 preserved
R2 = size of largest block available in bytes
R3 = total amount free in RMA in bytes

Use

This call returns information on the state of the RMA. It does this by calling OS_Heap with the appropriate descriptor.

Related reason codes

6


OS_Module 6
(SWI &1E)

Claim

On entry

R0 = 6 (reason code)
R3 = required size

On exit

R0 preserved
R2 = pointer to claimed block
R3 preserved

Use

This calls the heap manager to claim workspace in the RMA. If it fails and application workspace is not currently being used then it will attempt to reallocate this memory and retry. It returns with V set if it is still unsuccessful. This call is useful for claiming workspace during the module's initialisation, but may also be used from other module entries.

The possible error is 'Not enough memory in module area' (or, under RISC OS 2, 'No room in RMA').

Related reason codes

5, 7


OS_Module 7
(SWI &1E)

Free

On entry

R0 = 7 (reason code)
R2 = pointer to block

On exit

R0 preserved
R2 preserved

Use

This calls the heap manager to free a block of workspace claimed from the RMA.

The possible error is 'Not a heap block'.

Related reason codes

6


OS_Module 8
(SWI &1E)

Tidy

On entry

R0 = 8 (reason code)

On exit

R0 preserved

Use

This gives each instantiation of all modules in turn, from the end of the module list and working backwards, a non-fatal finalisation call. Instantiations of a particular module are killed in the order they appear on the current instantiation list.

Should any instantiation of any module refuse to die, then any modules which have already been killed are re-initialised. Should any of these give an error during re-initialisation, they are then deleted from the system. The SWI then exits with the original error returned by the module that first refused to die.

If all modules die successfully, this call then collects the RMA together into one large unfragmented block, and reinitialises the modules again. Any private words containing pointers to workspace blocks in the RMA are relocated. This should enlarge application space.

Related reason codes

3, 9


OS_Module 9
(SWI &1E)

Clear

On entry

R0 = 9 (reason code)

On exit

R0 preserved

Use

This deals with each module in turn, removing it from the module list and calling it through its finalise address, if it isn't a ROM module. Errors are generated if modules fail to die.

Related reason codes

3, 8


OS_Module 10
(SWI &1E)

Insert module from memory

On entry

R0 = 10 (reason code)
R1 = pointer to start of module

On exit

R0, R1 preserved

Use

This takes a pointer to a block of memory and links it into the module chain, without moving it. Header fields are checked for validity. All duplicate modules are killed. If it is successful, then the module is called at its initialisation entry.

Possible errors are 'Duplicate module refuses to die' and 'Module refuses to initialise'.

The word immediately before the module start (ie at address R1-4) must contain the length of the module in bytes.

Related reason codes

11


OS_Module 11
(SWI &1E)

Insert module from memory and move into RMA

On entry

R0 = (reason code)
R1 = pointer to start of module
R2 = length of module in bytes

On exit

R0 - R2 preserved

Use

This takes a pointer to a block of memory, and checks its header fields for validity. It then kills any duplicate module, copies the block into the RMA, initialises it and links it into the module chain.

Possible errors are 'Duplicate module refuses to die', 'No room in RMA' and 'Module refuses to initialise'.

Related reason codes

10


OS_Module 12
(SWI &1E)

Extract module information

On entry

R0 = 12 (reason code)
R1 = module number, or 0 for first call
R2 = instantiation number, or 0 for all

On exit

R0 preserved
R1 = updated module number
R2 = updated instantiation number
R3 = module base
R4 = private word (usually workspace pointer)
R5 = pointer to instantiation postfix

Use

This returns pointers to modules and the contents of their private word. It searches the list of modules to see if the module pointer given in R1 is valid. If it is valid, the next descriptor in the module chain is referenced, otherwise the first module descriptor is referenced. Information from the referenced descriptor is then returned. The information returned is exactly that printed by the *Modules command.

Specifying the instantiation number and index in the module list allows all module instantiations to be enumerated. Enumeration can be started with 0 in R1 and R2. This call will:

  • count down the module list to find the R1th entry; error if list runs out
  • count down the instantiation list to R2th entry; error if list runs out
  • set up return information

If the module has more instantiations, R2 += 1 else R1 += 1, R2 = 0

Possible errors are 'No more modules' or 'No more incarnations of that module'.

Related reason codes

13


OS_Module 13
(SWI &1E)

Extend block

On entry

R0 = 13 (reason code)
R2 = pointer to workspace block
R3 = change in size in bytes

On exit

R0 preserved
R2 = pointer to new allocated block
R3 preserved

Use

This allows modules to extend workspace blocks claimed in the RMA. It calls OS_Heap with the appropriate descriptor and attempts to enlarge the RMA if this fails.

The possible error is 'No room in RMA'.

Related reason codes

12


OS_Module 14
(SWI &1E)

Create new instantiation

On entry

R0 = 14 (reason code)
R1 = pointer to new instantiation name and any parameters for initialisation

On exit

R0, R1 preserved

Use

This creates new instantiations of existing modules, using the syntax:

module_title%instantiation

For example:

FileCore%RAM

Related reason codes

15, 16


OS_Module 15
(SWI &1E)

Rename instantiation

On entry

R0 = 15 (reason code)
R1 = pointer to current module%instantiation name
R2 = pointer to new instantiation name

On exit

R0 - R2 preserved

Use

This renames an existing instantiation of a module. For example:

FileCore%RAM

to

FileCore%ADFS

Related reason codes

14, 16


OS_Module 16
(SWI &1E)

Make preferred instantiation

On entry

R0 = 16 (reason code)
R1 = pointer to module%instantiation name

On exit

R0, R1 preserved

Use

This enables you to select the preferred instantiation of a particular module.

Related reason codes

14, 15


OS_Module 17
(SWI &1E)

Add expansion card module

On entry

R0 = 17 (reason code)
R1 = pointer to environment string
R2 = chunk number
R3 = ROM section

On exit

R0 - R3 preserved

Use

This allows expansion card and extension ROM modules to be added to the module list. Note that extension ROMs are not supported in RISC OS 2.

Valid ROM sections are:

ROM section Meaning
-1 System ROM
0 Expansion card 0
1 Expansion card 1
2 Expansion card 2
3 Expansion card 3
-2 Extension ROM 1 (not in RISC OS 2)
-3 Extension ROM 2 (not in RISC OS 2)
-4 Extension ROM 3 (etc) (not in RISC OS 2)
Related reason codes

10


OS_Module 18
(SWI &1E)

Look-up module name

On entry

R0 = 18 (reason code)
R1 = pointer to full module_title%instantiation name

On exit

R0 preserved
R1 = module number
R2 = instantiation number
R3 = pointer to module code
R4 = private word contents
R5 = pointer to postfix string

Use

This returns pointers to modules and the contents of their private word. It searches the list of modules to see if the module pointer given in R1 is valid. If it is valid, the module descriptor is referenced. Information from the referenced descriptor is then returned.

Related reason codes

12, 19, 20


OS_Module 19
(SWI &1E)

Enumerate ROM modules

On entry

R0 = 19 (reason code)
R1 = module number (0 to start full enumeration)
R2 = ROM section (-1 to start full enumeration)

On exit

R0 preserved
R1 = module number of found module + 1
R2 = ROM section of found module
R3 = pointer to module name
R4 = state:

    -1 unplugged
    0 inserted but not in the module chain ie dormant
    1 active
    2 running
R5 = chunk number of expansion card or extension ROM module

Use

This call returns information on one module that is currently in ROM, along with its status. The module found is the given number of modules on from the start of the given ROM section. If there are insufficient modules in the ROM section then the search continues with the next section; so the fifth module in a four module section would in fact be the first module of the next section.

The ROM sections are scanned in this order:

ROM section Meaning
-1 System ROM
0 Expansion card 0
1 Expansion card 1
2 Expansion card 2
3 Expansion card 3
-2 Extension ROM 1 (not in RISC OS 2)
-3 Extension ROM 2 (not in RISC OS 2)
-4 Extension ROM 3 (etc) (not in RISC OS 2)

The values returned in R0 - R2 are the correct ones to use this call to enumerate the next module; hence repeated calls will give a full enumeration of all ROM modules.

The call returns the error 'No more modules' (error number &107) if there are no more modules from the point specified in the ordering.

Related reason codes

12, 18, 20


OS_Module 20
(SWI &1E)

Enumerate ROM modules with version

On entry

R0 = 20 (reason code)
R1 = module number (0 to start full enumeration)
R2 = ROM section (-1 to start full enumeration)

On exit

R0 preserved
R1 = module number of found module + 1
R2 = ROM section of found module
R3 = pointer to module name
R4 = state:

    -1 unplugged
    0 inserted but not in the module chain ie dormant
    1 active
    2 running
R5 = chunk number of expansion card or extension module
R6 = BCD version number (derived from module's help string)

Use

This call returns information on one module that is currently in ROM, along with its status. The call is identical to OS_Module 19, except that on exit R6 holds a BCD (binary coded decimal) form of the module's version number, as derived from the module's help string. The top 16 bits of this value hold the integer part of the version number, and the bottom 16 bits hold the fractional part: eg if the version number of the module is '3.14' then the value returned would be &00031400.

The module found is the given number of modules on from the start of the given ROM section. If there are insufficient modules in the ROM section then the search continues with the next section; so the fifth module in a four module section would in fact be the first module of the next section.

The ROM sections are scanned in this order:

ROM section Meaning
-1 System ROM
0 Expansion card 0
1 Expansion card 1
2 Expansion card 2
3 Expansion card 3
-2 Extension ROM 1 (not in RISC OS 2)
-3 Extension ROM 2 (not in RISC OS 2)
-4 Extension ROM 3 (etc) (not in RISC OS 2)

The values returned in R0 - R2 are the correct ones to use this call to enumerate the next module; hence repeated calls will give a full enumeration of all ROM modules.

The call returns the error 'No more modules' (error number &107) if there are no more modules from the point specified in the ordering.

This reason code is not available in RISC OS 2

Related reason codes

12, 18, 19

Service Calls


OS_ServiceCall
(SWI &30)

Issue a service call to a module

On entry

R1 = service number
other registers are parameters and depend upon the service number

On exit

R1 = 0 if service was claimed, preserved otherwise
other registers up to R8 may be modified if the service was claimed

Interrupts

Interrupt status is not altered
Fast interrupts are enabled

Processor Mode

Processor is in SVC mode

Re-entrancy

SWI is re-entrant

Use

OS_ServiceCall is used to issue a service call. It can be used by any program (including a module) which wishes to pass a service around the current module list. For example, someone wishing to use FIQs might issue the claim/release service calls.

A module may claim a service call by setting R1 to 0 on exit; this prevents the service call from being passed to any further modules. There are some service calls that you must not claim, since it is essential that all modules receive them; such cases are clearly documented.

Here is a list of the service calls available to application writers, the details of which can be found on the specified pages. The names given below omit the initial 'Service_' for clarity:

No

Name

Meaning

Page

&04

UKCommand

Unknown command

Service_UKCommand (Service Call &04)

&06

Error

Error has occurred

Service_Error (Service Call &06)

&07

UKByte

Unknown OS_Byte

Service_UKByte (Service Call &07)

&08

UKWord

Unknown OS_Word

Service_UKWord (Service Call &08)

&09

Help

*Help has been called

Service_Help (Service Call &09)

&0B

ReleaseFIQ

Release FIQ

Service_ReleaseFIQ (Service Call &0B)

&0C

ClaimFIQ

Claim FIQ

Service_ClaimFIQ (Service Call &0C)

&11

Memory

Memory controller about to be remapped

Service_Memory (Service Call &11)

&12

StartUpFS

Start up filing system

Service_StartUpFS (Service Call &12)

&27

Reset

Post-Reset

Service_Reset (Service Call &27)

&28

UKConfig

Unknown *Configure

Service_UKConfig (Service Call &28)

&29

UKStatus

Unknown *Status

Service_UKStatus (Service Call &29)

&2A

NewApplication

Application about to start

Service_NewApplication (Service Call &2A)

&40

FSRedeclare

Start up filing system

Service_FSRedeclare (Service Call &40)

&41

Print

For internal use only

Service_Print (Service Call &41)

&42

LookupFileType

Look up file type

Service_LookupFileType (Service Call &42)

&43

International

International service

Service_International (Service Call &43)

&44

Keyhandler

Keyboard handler

Service_KeyHandler (Service Call &44)

&45

PreReset

Pre-reset

Service_PreReset (Service Call &45)

&46

ModeChange

Mode change

Service_ModeChange (Service Call &46)

&47

ClaimFIQinBackground

Claim FIQ in background

Service_ClaimFIQinBackground (Service Call &47)

&48

ReAllocatePorts

Econet restarting

Service_ReAllocatePorts (Service Call &48)

&49

StartWimp

Start up any resident module tasks using Wimp_StartTask

Service_StartWimp (Service Call &49)

&4A

StartedWimp

Request to task modules to set taskHandle variable to zero

Service_StartedWimp (Service Call &4A)

&4B

StartFiler

Request to filing-system-specific desktop filers to start up

Service_StartFiler (Service Call &4B)

&4C

StartedFiler

Request to filing-system-specific desktop filers to set taskHandle variable to zero

Service_StartedFiler (Service Call &4C)

&4D

PreModeChange

Mode change

Service_PreModeChange (Service Call &4D)

&4E

MemoryMoved

OS_ChangeDynamicArea has just finished

Service_MemoryMoved (Service Call &4E)

&4F

FilerDying

Notification that the Filer module is about to close down

Service_FilerDying (Service Call &4F)

&50

ModeExtension

Allow soft modes

Service_ModeExtension (Service Call &50)

&51

ModeTranslation

Translate modes for unknown monitor types

Service_ModeTranslation (Service Call &51)

&52

MouseTrap

The Wimp has detected a significant mouse movement

Service_MouseTrap (Service Call &52)

&53

WimpCloseDown

Notification that the Window Manager is about to close down a task

Service_WimpCloseDown (Service Call &53)

&54

Sound

Parts of the Sound system are starting or dying

Service_Sound (Service Call &54)

&55

NetFS

Either a *Logon, a *Bye or a *SDisc/*Mount has occurred

Service_NetFS (Service Call &55)

&56

EconetDying

Econet is about to leave

Service_EconetDying (Service Call &56)

&57

WimpReportError

Request to suspend trapping of VDU output so an error can be displayed

Service_WimpReportError (Service Call &57)

&59

ResourceFSStarted

The file structure inside ResourceFS has changed

Service_ResourceFSStarted (Service Call &59)

&5A

ResourceFSDying

ResourceFS is killed

Service_ResourceFSDying (Service Call &5A)

&5B

CalibrationChanged

Screen calibration is changed

Service_CalibrationChanged (Service Call &5B)

&5C

WimpSaveDesktop

Save some state to a desktop boot file

Service_WimpSaveDesktop (Service Call &5C)

&5D

WimpPalette

Palette change

Service_WimpPalette (Service Call &5D)

&5E

MessageFileClosed

Message files have been closed

Service_MessageFileClosed (Service Call &5E)

&5F

NetFSDying

NetFS is dying

Service_NetFSDying (Service Call &5F)

&60

ResourceFSStarting

ResourceFS module is reloaded or reinitialised

Service_ResourceFSStarting (Service Call &60)

&64

TerritoryManagerLoaded

Tell territory modules to register themselves.

Service_TerritoryManagerLoaded (Service Call &64)

&65

PDriverStarting

PDriver sharer module started

Service_PDriverStarting (Service Call &65)

&66

PDumperStarting

PDriverDP module starting up

Service_PDumperStarting (Service Call &66)

&67

PDumperDying

PDriverDP module dying

Service_PDumperDying (Service Call &67)

&68

CloseFile

Close an object, and any children of that object

Service_CloseFile (Service Call &68)

&69

IdentifyDisc

Identify disc format

Service_IdentifyDisc (Service Call &69)

&6A

EnumerateFormats

Enumerate available disc formats

Service_EnumerateFormats (Service Call &6A)

&6B

IdentifyFormat

Identify disc format name

Service_IdentifyFormat (Service Call &6B)

&6C

DisplayFormatHelp

Display list of available formats

Service_DisplayFormatHelp (Service Call &6C)

&6D

ValidateAddress

OS_ValidateAddress has been called with an unrecognised area

Service_ValidateAddress (Service Call &6D)

&6E

FontsChanged

New Font$Path detected

Service_FontsChanged (Service Call &6E)

&6F

BufferStarting

Notifies modules that the buffer manager is starting

Service_BufferStarting (Service Call &6F)

&70

DeviceFSStarting

DeviceFS is starting

Service_DeviceFSStarting (Service Call &70)

&71

DeviceFSDying

DeviceFS is dying

Service_DeviceFSDying (Service Call &71)

&72

SwitchingOutputToSprite

Output switched to sprite, mask or screen

Service_SwitchingOutputToSprite (Service Call &72)

&73

PostInit

All modules have been initialised

Service_PostInit (Service Call &73)

&75

TerritoryStarted

New territory starting

Service_TerritoryStarted (Service Call &75)

&76

MonitorLeadTranslation

Translate monitor lead ID

Service_MonitorLeadTranslation (Service Call &76)

&78

PDriverGetMessage

Get common messages file

Service_PDriverGetMessages (Service Call &78)

&79

DeviceDead

Device has been killed by DeviceFS

Service_DeviceDead (Service Call &79)

&7A

ScreenBlanked

Screen blanked by screen blanker

Service_ScreenBlanked (Service Call &7A)

&7B

ScreenRestored

Screen restored by screen blanker

Service_ScreenRestored (Service Call &7B)

&7C

DesktopWelcome

Desktop starting

Service_DesktopWelcome (Service Call &7C)

&7D

DiscDismounted

Disc dismounted

Service_DiscDismounted (Service Call &7D)

&7E

ShutDown

Switcher shutting down

Service_ShutDown (Service Call &7E)

&7F

PDriverChanged

Currently selected printer driver has changed

Service_PDriverChanged (Service Call &7F)

$80

ShutdownComplete

Shutdown completed

Service_ShutdownComplete (Service Call &80)

&81

DeviceFSCloseRequest

Opening a device which already has the maximum number of streams open

Service_DeviceFSCloseRequest (Service Call &81)

&82

InvalidateCache

Broadcast whenever the cache is flushed within ColourTrans

Service_InvalidateCache (Service Call &82)

&83

ProtocolDying

Part of the AUN Driver Control Interface

Service_ProtocolDying (Service Call &83)

&84

FindNetworkDriver

Part of the AUN Driver Control Interface

Service_FindNetworkDriver (Service Call &84)

&85

WimpSpritesMoved

Wimp sprite pools have moved

Service_WimpReportError (Service Call &57)

&86

WimpRegisterFilters

Allows the Filter Manager to install filters with the Window Manager

Service_WimpReportError (Service Call &57)

&87

FilterManagerInstalled

Filter Manager starting up

Service_FilterManagerInstalled (Service Call &87)

&88

FilterManagerDying

Filter Manager dying

Service_FilterManagerDying (Service Call &88)

&89

ModeChanging

Mode change

Service_ModeChanging (Service Call &89)

&8A

Portable

Power down or up

Service_Portable (Service Call &8A)

&8B

NetworkDriverStatus

Part of the AUN Driver Control Interface

Service_NetworkDriverStatus (Service Call &8B)

&8C

SyntaxError

Syntax error translation

Service_SyntaxError (Service Call &8C)

&10800

ADFSPodule

Issued by ADFS to locate an ST506 expansion card

Service_ADFSPodule (Service Call &10800)

&10801

ADFSPoduleIDE

Issued by ADFS to locate an IDE expansion card

Service_ADFSPoduleIDE (Service Call &10801)

&10802

ADFSPoduleIDEDying

IDE expansion card dying

Service_ADFSPoduleIDEDying (Service Call &10802)

Related SWIs

OS_Byte 143

Related vectors

None


Service_UKCommand
(Service Call &04)

Unknown command

On entry

R0 = pointer to command
R1 = &04 (reason code)

On exit

R0 = 0 if command performed with no error, or error pointer if command performed with error, or preserved to pass on
R1 = 0 to claim the command, or preserved to pass on

Use

This service call is issued when a command is unknown. It is issued after OSCLI has searched modules, but before the filing system is called to try to *Run the command. It is also used to implement NetFS file server commands.

If your module recognises the command, you should try to execute it, claiming the service call by setting R1 to 0 as usual. If the command was successful you should set R0 to 0 when claiming the call; if an error occurred you should instead set R0 to point to the error buffer.

Note that this is the 'historical' way of dealing with unknown commands. You should, in preference, use the command string entry point.


Service_Error
(Service Call &06)

Error has occurred

On entry

R0 = pointer to error block
R1 = &06 (reason code)

On exit

R0 preserved
R1 preserved to pass on (must never be claimed)

Use

This call is issued after an error has occurred but before the error handler is called. It is included 'for your information', and must not be claimed.


Service_UKByte
(Service Call &07)

Unknown OS_Byte

On entry

R1 = &07 (reason code)
R2 = OS_Byte number (ie value in R0 when OS_Byte was called)
R3 = first parameter (ie value in R1 when OS_Byte was called)
R4 = second parameter (ie value in R2 when OS_Byte was called)

On exit

R1 = 0 to claim, else preserved to pass on
R3 = value to return in R1 to caller
R4 = value to return in R2 to caller
Errors cannot be returned

Use

If the OS_Byte number is one used by your module, you should execute it and claim the call by setting R1 to zero.

If you don't recognise the OS_Byte number, pass the call on by returning with the registers preserved.

This method of adding OS_Byte calls is deprecated, and you should instead claim the ByteV software vector. See the chapter entitled Software vectors.


Service_UKWord
(Service Call &08)

Unknown OS_Word

On entry

R1 = &08 (reason code)
R2 = OS_Word number (ie value in R0 when OS_Word was called)
R3 = pointer to OS_Word parameter block (ie value in R1 when OS_Word was called)

On exit

R1 = 0 to claim, else preserved to pass on
Errors cannot be returned

Use

If the OS_Word number is one used by the module it is passing through, you should execute it and claim the call by setting R1 to zero.

If you don't recognise the OS_Word number, pass the call on by returning with the registers preserved.

This method of adding OS_Word calls is deprecated, and you should instead claim the WordV software vector. See the chapter entitled Software vectors.


Service_Help
(Service Call &09)

*Help has been called

On entry

R0 = pointer to command
R1 = &09 (reason code)

On exit

R0 preserved
R1 = 0 to claim, else preserved to pass on

Use

This is issued at the start of *Help. You should claim this call only if you wish to replace *Help completely. The usual way for a module to provide help is through its help text table.


Service_UKConfig
(Service Call &28)

Unknown *Configure

On entry

R0 = pointer to command tail, or 0 if none given
R1 = &28 (reason code)

On exit

R0 < 0 for no error, or a small integer for errors described below, or error pointer for other errors
R1 = 0 if configure option recognised and no error, else preserved to pass on

Use

If R0 = 0 on entry, you should print your *Configure syntax line(s), if any, and exit with registers preserved.

If R0 [NOT EQUAL] 0, then R0 is a pointer to the command tail. If you decode the command tail, and recognise it, you should claim the call by setting R1 to 0. If an error is detected, should also return with V set and return the error in R0 as follows:

    Value Meaning
    0 Bad *Configure option
    1 Numeric parameter needed
    2 Parameter too large
    3 Too many parameters
    >3 R0 is an error pointer returned by *Configure

If you don't recognise the command tail, you should exit with registers preserved.

Note that it is also possible to trap unknown *Configure commands through the module's command table (see the chapter entitled Help and command keyword table) - which is the preferred method. Only one of these mechanisms should be used.


Service_UKStatus
(Service Call &29)

Unknown *Status

On entry

R0 = pointer to command tail, or 0 if none given
R1 = &29 (reason code)

On exit

R0 preserved
R1 = 0 is status option recognised and no error, else preserved to pass on

Use

If R0 = 0, you should list your status(es) and pass on the service call.

If R0 [NOT EQUAL] 0, then R0 is a pointer to the command tail. If you decode the command tail, and recognise it, you should print the associated information and claim the call. Otherwise you should not claim the call.

Note that it is also possible to trap unknown *Status commands through the module's command table (see the chapter entitled Help and command keyword table) - which is the preferred method. Only one of these mechanisms should be used.


Service_NewApplication
(Service Call &2A)

Application about to start

On entry

R1 = &2A (reason code)

On exit

R1 = 0 to prevent application from starting, else preserved to pass on

Use

This service is called when an application is about to start due to a *Go, *RMRun or *Run-type operation. If you don't want the application to start, you should claim the call, otherwise pass it on.


Service_LookupFileType
(Service Call &42)

Look up file type

On entry

R1 = &42 (reason code)
R2 = file type (in lower three nibbles)

On exit

R1 = 0 if the module knows the file type, else preserved to pass on
R2 = first four characters, if known, else preserved
R3 = last four characters, if known, else preserved

Use

This call is passed round when FileSwitch is unable to convert a hexadecimal 3-digit file type xxx into a textual name, because it is unable to find the system variable File$Type_xxx. If the file type passed in R2 is known to you, you should return with R1=0, and R2, R3 containing the eight characters in the name. If no-one claims the call, FileSwitch will convert the number into a three-digit hex value padded with spaces. This might be loaded as follows:

   ADR     R1, nameString
   LDMIA   R1, {R2,R3}
   MOV     R1, #0
   MOV     PC, R14
.nameString
   EQUS    "My Type "  ; String must be eight bytes long

Service_PostInit(Service Call &73)

All modules have been initialised

On entry

--

On exit

This service call should not be claimed.

Use

This is issued on a reset, after all the ROM resident modules (including those on extension ROMs and expansion cards) have been initialised.


Service_SyntaxError
(Service Call &8C)

Syntax error translation

On entry

R1 = &8C (reason code)
R2 = pointer to the issued command's code offset in the module's help and command keyword table (ie R2+4 is the command's information word; see Help and command keyword table)
R3 = base address of module providing command
R4 = pointer to command string in module

On exit

R0 = pointer to error block giving new syntax message, else preserved to pass on
R1 = 0 to claim service call, else preserved to pass on
R2 - R4 preserved

Use

This service call is issued just before a syntax error is returned from a module * Command. It is provided so that modules can localise their error messages for a particular territory.

On entry, the registers hold sufficient information to identify the particular command being issued, and in which module it resides.

If the service call is claimed, RISC OS outputs the returned error string in the block pointed to by R0; otherwise it uses the syntax error message in the module's help and command keyword table (see Help and command keyword table).

This service call is only issued by RISC OS 3 (version 3.10) or later.

*Commands


*Modules

Displays information about all installed relocatable modules

Syntax
*Modules
Parameters

None

Use

*Modules displays information about all relocatable modules which are currently installed in the machine.

The command displays the number allocated to each module, its position in memory, the address of its workspace, and its name.

  • The number may change as other modules are installed and removed.
  • The names listed by this command are the module titles, which are used as parameters for other commands such as *RMKill.
Example

*ModulesNo. Position Workspace Name
  1 0380BED8 00000000  UtilityModule
  2 038251A8 01800014  Podule
    ...
    ...
 81 039EAF10 00000000  !Edit
 82 039F17E4 0181E984  DOSFS

Related commands

*ROMModules

Related SWIs

OS_Module

Related vectors

None


*RMClear

Deletes all relocatable modules from the module area

Syntax
*RMClear
Parameters

None

Use

*RMClear deactivates all relocatable modules in the module area, deletes them, and frees their workspace. Use this command only with extreme caution, as it is so drastic in its effects.

ROM resident modules are not affected by *RMClear; if you wish to disable such a module, you should use *RMKill or *Unplug.

Related commands

*RMInsert, *RMKill, *RMReInit, *RMTidy, *Unplug

Related SWIs

OS_Module

Related vectors

None


*RMEnsure

Checks the presence and version of a module

Syntax

*RMEnsure module_title version_number [command]

Parameters
module_title the title of any currently installed module

version_number a number against which the version number will be checked

command a Command Line command
Use

*RMEnsure checks that a module is present and is the given version (or a more recent one). A command, optionally given as a third parameter, is executed if this is not the case, or - if none is specified - an error is generated. *RMEnsure is usually used in command scripts or programs to ensure that modules they need are loaded and of a recent enough version.

Example
*RMEnsure WindowManager 2.01 *RMLoad System:Wimp
Related commands

None

Related SWIs

OS_Module

Related vectors

None


*RMFaster

Makes a module faster by copying it from ROM to RAM

Syntax
*RMFaster module_title
Parameters
module_title the title of any ROM resident module
Use

*RMFaster makes a copy of a ROM resident relocatable module and places it in RAM. The module will run faster because RAM can be accessed faster than ROM.

In doing so, the module is moved to the end of the module list. You should be aware that this can cause problems later; for example, the relative ordering of some modules is important to the *RMTidy command, which a number of applications use.

Example
*RMFaster BASIC
Related commands

None

Related SWIs

OS_Module

Related vectors

None


*RMInsert

Reverses the action of a previous *Unplug command

Syntax

*RMInsert module_title [ROM_section]

Parameters

module_title

the title of any ROM resident module

ROM_section

ROM section to restrict command to
Use

*RMInsert reverses the action of a previous *Unplug command, but without reinitialising any modules.

If no ROM section number is specified, then this command clears the unplug bit for all versions of the specified module present in the machine.

If a ROM section number is specified, then this command clears the unplug bit for all versions of the specified module present in the given section. ROM section numbers are:

ROM section Meaning
-1 System ROM
0 Expansion card 0
1 Expansion card 1
2 Expansion card 2
3 Expansion card 3
-2 Extension ROM 1
-3 Extension ROM 2
-4 Extension ROM 3 (etc)

This command is not available in RISC OS 2.

Example
*RMInsert MIDI 1
Related commands

*RMReInit, *Unplug

Related SWIs

OS_Module

Related vectors

None


*RMKill

Deactivates and deletes a relocatable module

Syntax

*RMKill module_title[%instantiation]

Parameters

module_title

the title of any currently installed module

instantiation

the instantiation of any currently installed module
Use

*RMKill deactivates the preferred instantiation of a relocatable module (or the specified instantiation if the second argument is used) and releases its workspace. If the module is in RAM, it is also deleted. If it is ROM resident, it is made inactive until reinitialised by the *RMReInit command, or until the next hard reset. Use this command only with extreme caution, as it may be drastic in its effects.

Example
*RMKill Debugger
Related commands

*RMClear, *RMInsert, *RMReInit, *RMTidy, *Unplug

Related SWIs

OS_Module

Related vectors

None


*RMLoad

Loads and initialises a relocatable module

Syntax

*RMLoad filename [module_init_string]

Parameters

filename

a valid pathname specifying a module file
Use

*RMLoad loads and initialises a relocatable module. It can then be accessed by the help system, and can provide SWIs and * Commands if available.

The file must have file type &FFA, otherwise the module handler will refuse to load it.

The optional initialisation string can be used to pass parameters to certain modules so they initialise themselves in a particular way. For example, you might use it to specify the amount of workspace that the module should claim, or a file that the module should load.

Example
*RMLoad WaveSynth $.Waves.Brass14
Related commands

*RMRun

Related SWIs

OS_Module

Related vectors

None


*RMReInit

Reinitialises a relocatable module

Syntax
*RMReInit module_title [module_init_string]
Parameters

module_title

the title of any currently installed module, active or otherwise

module_init_string

optional parameters to the module
Use

*RMReInit reinitialises a relocatable module, reversing the action of any previous *RMKill or *Unplug command. The module is returned to the state it was in when it was loaded. Use this command only with extreme caution, as it may be drastic in its effects.

  • If the specified module is active, then it is killed and then re-initialised.
  • If the specified module is not active, but is in the ROM, then the unplug bit in CMOS RAM is cleared for all versions of the specified module, and then the newest version of the module is initialised. (Under RISC OS 2 it is the first found version that is initialised.)

The optional initialisation string can be used to pass parameters to certain modules so they reinitialise themselves in a particular way. For example, you might use it to specify the amount of workspace that the module should claim, or a file that the module should load.

This command can produce unexpected results, for a variety of reasons. For example:

  • The order of module initialisation is important in RISC OS. If a module relies on a second module being later initialised, you cannot successfully reinitialise the first module without then reinitialising the second.
  • Under the desktop, a reinitialised module does not get restarted as a task unless you re-enter the desktop.
Example
*RMReInit Debugger
Related commands

*RMClear, *RMInsert, *RMKill, *RMTidy, *Unplug

Related SWIs

OS_Module

Related vectors

None


*RMRun

Loads and initialises a relocatable module, and then runs it

Syntax

*RMRun filename [module_init_string]

Parameters
filename a valid pathname specifying a module file
module_init_string optional parameters to the module
Use

*RMRun loads and initialises a relocatable module, and then runs it.

The module is first loaded and initialised. (This is equivalent to a call to *RMLoad.) The module can then be accessed by the help system, and can provide SWIs and * Commands if available.

The file must have file type &FFA, otherwise the module handler will refuse to load it.

The module is then run, if it can be. This is equivalent to an enter operation in OS_Module. Consequently, if the module cannot be run, then this command is equivalent to a *RMLoad command.

Example
*RMRun My_Module
Related commands

*RMLoad

Related SWIs

OS_Module

Related vectors

None


*RMTidy

Compacts the module area and reinitialises all the modules it contains

Syntax
*RMTidy
Parameters

None

Use

*RMTidy collects together free space in the module area by moving and reinitialising all the modules it contains. The free space is gathered into a consecutive chunk of memory.

Use this command only with extreme caution, as it is so drastic in its effects.

Related commands

*RMClear

Related SWIs

OS_Module

Related vectors

None


*ROMModules

Displays information about all relocatable modules currently installed in ROM

Syntax
*ROMModules
Parameters

None

Use

*ROMModules displays information about all relocatable modules which are currently installed in ROM.

The command displays the number allocated to each module, whether it is part of the system or in expansion cards or in an extension ROM, its name, and its status: active, running, dormant or unplugged. (Note that RISC OS 2 does not support extension ROMs, nor does it give a version number or report modules as running.)

  • The names listed by this command are the module titles, which are used as parameters for other commands such as *RMKill.

System modules are stored in ROM, but may still be *RMKilled, *Unplugged, or replaced by RAM-based modules.

Example

*ROMModulesNo. Position    Module name             Version Status
  1 System ROM  UtilityModule           2.20    Active
  2 System ROM  Podule                  1.23    Active
  3 System ROM  FileSwitch              1.98    Active
  4 System ROM  ResourceFS              0.09    Active
  5 System ROM  Messages                0.16    Active
         ...
  1 Podule 1    Support16a              1.00    Active
         ...
  1 Extn ROM 1  Tube6502Emulator        1.17    Dormant
  1 Extn ROM 2  Turbo6502Emulator       1.17    Dormant
  1 Extn ROM 3  Tube6502Emulator        1.17    Active
  2 Extn ROM 3  Turbo6502Emulator       1.17    Active
  1 Extn ROM 4  FontManager             2.85    Active
         ...

or under RISC OS 2:

*ROMModulesNo. Position   Module Name              Status
  1 System ROM UtilityModule            Active
  2 System ROM FileSwitch               Active
  3 System ROM Desktop                  Active
         ...
  1 Podule 0   MailBleep                Dormant
  2 Podule 0   ROMBoard                 Dormant
         ...

Related commands

*Modules

Related SWIs

OS_Module

Related vectors

None


*Unplug

Kills and disables all copies of a ROM resident module

Syntax
*Unplug [module_title [ROM_section]]

*Unplug [module_title] (RISC OS 2)

Parameters
module_title the title of any ROM resident module
ROM_section ROM section to restrict command to - this parameter is not recognised by RISC OS 2
Use

*Unplug kills all copies of the named ROM module, releasing any workspace used. (In RISC OS 2 only the first copy found is deleted.) It also disables all versions of that module - whether in the system ROM, expansion cards or extension ROMs - by preventing them from being initialised (and hence available for use). This setting is stored in the CMOS RAM, and so is permanent even across a reset. To enable the module again you must use the *RMReInit or *RMInsert command. (The latter command is not available in RISC OS 2.)

If you supply a ROM section parameter, *Unplug restricts its effects to modules that are in that ROM section. ROM section numbers are:

    ROM section Meaning
    -1 System ROM
    0 Expansion card 0
    1 Expansion card 1
    2 Expansion card 2
    3 Expansion card 3
    -2 Extension ROM 1
    -3 Extension ROM 2
    -4 Extension ROM 3 (etc)

You should use this command with caution, otherwise you may find programs stop working because you have unplugged a module that is essential to them.

If no parameters are given, the unplugged ROM modules are listed.

Example
*Unplug RAMFSFiler disables the RAMFSFiler module
Related commands

*RMInsert, *RMKill, *RMReInit

Related SWIs

OS_Module

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015