Technical details
RISC OS was designed initially for code written in assembler, and for use by BASIC. Its legacy of the BBC MOS influenced many of the interfaces that were used in the earliest systems, and these are not as suited to modern systems. Because of this, and to take advantage the opportunity to re-work some interfaces, some of the interfaces in 64 bit RISC OS differ from those in the 32 bit variant.
The differences relate primarily to entry and exit conditions for SWI calls and vectors. The changes will allow easier use of the system calls from high level languages, and may allow for easier transition to other architectures.
Areas which have changed
Registers
Where registers between R0 and R9 are used for vectors, SWIs, upcalls, events and other interfaces, these map directly to the registers X0 to X9. Initially these registers should be expected to contain values which are 32 bit (despite the 64 bit nature of these registers).
Register R12, which is usually passed to extension interfaces as a private word pointer, or context value, is passed in X12.
Processor flags
Some interfaces in RISC OS, like OS_ReadC, return part of their state in ARM processor flags. This made them easier to call in assembler, but does not work as well with high level languages. The convention of returning with the overflow (V) flag set to indicate a call error, with an error pointer in the first register is retained, however.
Instead of returing state in the carry, zero, or negative flags, RISC OS 64 bit interfaces return the additional state in an extra register, or with a modified return in an existing register.
Rarely, there are interfaces which have different state on entry. The vector CnPV is an example of this. These interfaces have been updated to include an additional register on entry to perform different operations.
Interface changes
Modules
Multiple instantiation
Multiple instantiation of modules is not supported under 64-bit RISC OS.
Multiple instantiation is a feature which allows the same module code to be used for different purposes. The FileCore module uses it to create separate instances for each module is it providing a file system for, for example. However, multiple instantiation of modules also brings with it a penalty in that the behaviour of modules which are given priority changes by the commands that are processed by them. Additionally, the features provided by multiply instantiated modules are also reproducible with a single instance, so the benefit is reduced. The feature is not widely used.
In 26-bit and 32-bit RISC OS, the ability to multiply instantiate modules was given special features within the compiler to allow separate data areas for an execution. This used the 'stack entrails' (data at the bottom of the current stack chunk) to find the data area. This was a special compiler feature for RISC OS, and had to be given special consideration when using compilers such as GCC. In APCS for 32-bit, this could have also been provided through the use of relocatable code using a 'static base'.
In AArch64, there is no provision for a 'static base'. All code is expected to be link-time resolved and use a Global Object Table to locate data regions. This does not work well with the traditional form of referencing workspace used for multiple instantiation. As building custom compilers for RISC OS is unnecessary work, and would further limit the support for the system, the ability to multiply instantiate modules is no longer supported in 64-bit RISC OS.
Module workspace may still be used, but it is expected that all modules will have their data located within the module itself, and the zero-initialised data region will be automatically allocated by the Kernel on module load. The size of this zero-initialised area is indicated in the module feature data.
Initialisation offset
Within 64-bit RISC OS, the module initialisation offset must have bit 30 set. This prevents the module from loading on non-64-bit systems. The module feature flags must also contain bits to indicate the module's architecture.
Command handler
Within 64 bit RISC OS, the module command handler does not need to set the V flag to indicate an error. The error pointer is returned in X0. If no error occurs, X0 must be set to 0.
Module feature data
Within 64-bit RISC OS, the module feature flags contain new bits to indicate features of the module. Bits 4-7 indicate the architecture of the module, which must be used in conjunction with bit 30 in the module initialisation offset. Bit 2 indicates that the zero-initialisation data byte is present.
The feature data has the following format:
Offset | Contents | |||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 |
Module feature flags:
| |||||||||||||||||||||||||||||||||
4 | Zero-initialisation data size (if bit 2 set) |
Zero-initialisation data follows on after the module, and will be allocated in excess of the module size by the Kernel.
Code variables
Code variables have a different definition and API within 64-bit RISC OS to allow them to be used more easily with high level languages.
Code variable definition
Code variables are defined with a 16 byte block which contains the address of the entry points for the code variables.
Offset | Size | Contents |
---|---|---|
0 | 8 | Address of the variable's write entry point |
8 | 8 | Address of the variable's read entry point |
Both entry points may point to the same routine, in which case the type of call can be differentiated by the value in X0 on entry. Register X1-X15 may be corrupted by the entry points.
Write entry point
Register X0 contains the value to write. Register X1 contains the length of the value. Register X2 contains the workspace pointer for the code variable.
The handler does not need to set the V flag to indicate an error. The error pointer is returned in X0. If no error occurs, X0 must be set to 0.
Read entry point
Register X0 contains 0. Register X1 contains 0. Register X2 contains the workspace pointer for the code variable.
On exit, X1 will contain a pointer to the read data, and X2 contains the size.
The handler does not need to set the V flag to indicate an error. The error pointer is returned in X0. If no error occurs, X0 must be set to 0.
SWI calls
Within 64 bit RISC OS, SWI calls are issued through the
SVC
(supervisor call) instruction, using parameter 0.
The SWI number is passed in register X10.
Input SWIs
OS_ReadC
In 64 bit RISC OS, OS_ReadC does not return the escape state in processor flags.
On exit, X1 will be set to the following values:
Value | Meaning |
---|---|
0 | A character was read (value in X0) |
1 | An escape condition occurred (value in X0 is 27) |
OS_ReadLine
In 64 bit RISC OS, OS_ReadLine does not return the escape state in processor flags.
On exit, X0 will be set to the following values:
Value | Meaning |
---|---|
0 | A line was read |
1 | An escape condition occurred (no line was read) |
OS_ReadEscapeState
In 64 bit RISC OS, OS_ReadEscapeState does not return the escape state in processor flags.
On exit, X0 will be set to the following values:
Value | Meaning |
---|---|
0 | No escape condition has occurred |
1 | An escape condition has occurred |
OS_Byte 129
In 64 bit RISC OS, OS_Byte 129 (read key state) does not return the read state in processor flags. The state of the carry flag had not been documented in the PRMs, and is not carried forward into 64 bit RISC OS.
OS_Confirm
In 64 bit RISC OS, OS_Confirm does not return the escape and acknowledgement state in processor flags.
On exit, X1 will be set to the following values:
Value | Meaning |
---|---|
-1 | An escape condition was detected |
0 | A negative response was given (not 'y') |
1 | A positive response was given |
Buffering SWIs
OS_Byte 138/153
In 64 bit RISC OS, OS_Byte 138/153 (insert into buffer/insert into input buffer) does not return the insertion state in processor flags.
On exit, X2 will be set to the following values:
Value | Meaning |
---|---|
0-255 | Value was inserted |
-1 | Value could not be inserted |
OS_Byte 145/152
In 64 bit RISC OS, OS_Byte 145/152 (read or examine buffer) does not return the read state in processor flags.
On exit, X2 will be set to the following values:
Value | Meaning |
---|---|
0-255 | Character read from, or available in, the buffer |
-1 | No character was available |
File system SWIs
OS_BGet
In 64 bit RISC OS, OS_BGet does not return the read state in processor flags.
On exit, X0 will be set to the following values:
Value | Meaning |
---|---|
-1 | No byte was read |
0-255 | Value read |
Output SWIs
VDUXV
In 64 bit RISC OS, VDUXV does not return the redirection to printer in the processor flags.
On entry, X1 will be set to 0.
On entry, X1 will be set to -1 to send to printer.
Graphics SWIs
OS_CheckModeValid
In 64 bit RISC OS, OS_CheckModeValid does not return the validity state in processor flags.
On exit, X0 will be set to the following values:
Value | Meaning |
---|---|
-1 | Mode does not exist; X1 contains the mode to use, or -2 if no alternative exists |
-2 | Mode exists, but is not selectable |
other | Mode exists and is selectable |
OS_ReadModeVariable
In 64 bit RISC OS, OS_ReadModeVariable does not return the validity state in processor flags.
On exit, X1 will be set to the following values:
Value | Meaning |
---|---|
-1 | Mode or variable number is invalid |
other | Mode and variable exist |
Memory SWIs
OS_ValidateAddress
In 64 bit RISC OS, OS_ValidateAddress does not return the validity state in processor flags.
On exit, X0 will be set to the following values:
Value | Meaning |
---|---|
0 | Memory is not valid |
1 | Memory is valid |
System variables
The system variable Sys$Arch is provides information on the architecture of the system.
The current values are defined.
Value | Meaning |
---|---|
aarch32 | ARM, 32-bit architecture (AArch32) |
aarch64 | ARM, 64-bit architecture (AArch64) |