Latest News
!System updates

Development tools
C/C++ Tools

Writing 32-bit code
32-bit introduction
32-bit overview
32-bit technical
Memory issues
Developer tools
Paul Skirrow's Guide (PDF)
Download area

32-bit APIs
API changes
CallASWI
FileCore

RISC OS 5
Overview
BBC BASIC
CDFS driver
OS_ClaimDeviceVector behaviour
CDFS
Draw clipping
GraphicsV
HAL
Internet
UTF8 & Japanese support
International IME support
MIMEMap
Module PostInit/Final
PCI Manager
PDumper
Podules
Resource allocation
SCSI
Service Calls
UCS fonts
USB
WIMP API Changes
WIMP Flags

IYONIX pc
DDR memory
Help system
Keyboard layout
Miscellaneous
PCI slots

Opportunities

Iyonix Ltd
IYONIX home page
Contact details

   

32-bit compatibility overview

Document version 0.12, 23 January 2003

Overview

RISC OS was originally designed for the ARM 2 and ARM 3 processors, which had a 26-bit address bus and a combined 24-bit program counter + 8-bit status flags in register R15.

The ARM 6 expanded the address bus and program counter to 32 bits and moved the status flags to a separate register, but included backwards-compatible 26-bit modes to allow ARM 2 and ARM 3 user programs to run unmodified. The latest ARM processors have removed these 26-bit compatibility modes in favour of the new 16-bit "Thumb" architecture. As a result, versions of RISC OS for new processors such as the ARM 9, 10 and XScale will be 32-bit only, using only 32-bit modes.

In the past RISC OS has used only 26-bit modes for backwards compatibility (with the exception of FIQ handlers and, in RISC OS 4, the FPEmulator). Indeed, current versions of RISC OS do not support operation in 32-bit modes for general applications or modules.

As a result, most RISC OS software was originally designed to run in a 26-bit mode, and needs updating to work on a 32-bit system. The components included here will allow programs to be built so they run on any system from an ARM2 Archimedes to an Intel 80200-based platform. This is achieved by creating 26/32-bit neutral code that performs the same when running in either a 26-bit or 32-bit mode.

Undocumented OS interfaces

We reiterate here the standard warning about reliance on undocumented OS interfaces and accesses to private OS workspace. If such things are attempted, no amount of 32-bit mode compatibility will allow you to run on new hardware.

In particular, 32-bit RISC OS has a radically different memory map, so hard-coded knowledge of addresses should be avoided, apart from application space starting at &8000.

The locations of any areas such as the RMA and screen memory should be read using the provided system calls. The expectation is that a 32-bit RISC OS will allow (virtually) unlimited application slot size. This mandates that all the system workspace currently in the region 01C00000-06000000 will move.

Also bear in mind that modern RISC OS computers are unlikely to use IOMD/VIDC compatible peripherals. Use OS calls rather than attempting direct hardware access.

Device drivers are unlikely to work on new hardware. However, the more abstraction steps you can take, the more chance you have. For example, Podule_ReadInfo will tell you which interrupt device to claim for your podule, and will give you addresses of interrupt mask registers. R3 on entry to IRQ routines contains a pointer to the I/O controller - use it and although your code may not work on a non IOMD-compatible system, it will stand a better chance of working on an IOMD-compatible system with a different memory map.

Other warnings

In the past it has been common to store flags at the top or bottom of pointers. This is likely to cause problems on 32-bit systems. In particular, a revised memory map will lead to many things being much higher in memory. Also, function pointers may have bits 0 and 1 set if Thumb is in use.

All existing ARM warnings in the PRM and Acorn Assembler manuals hold true - it is more likely than ever that deprecated sequences will fail to work. For example, all NV condition instructions are now either UNDEFINED or have new functions in architecture 5 (as implemented in the ARM10 and XScale).

Also ARM architecture 5 introduces new behaviour - a load from memory of the PC will cause the processor to automatically switch to Thumb mode if bit(0) of the loaded value is set. Beware.

BASIC programs

Pure BASIC programs should work unmodified on a 32-bit RISC OS, subject to the warnings above.

C programs

Pure C applications and modules should work unmodified on a 32-bit RISC OS, following recompilation using the components provided here. Once recompiled, these programs will require the Shared C Library provided here to operate on existing versions of RISC OS.

To compile 32-bit programs:

  1. Install the new tools and libraries provided here.
  2. Build your program.
  3. Ensure that no attribute conflict warnings are produced by the linker (as will occur if you are mixing APCS-R and APCS-32 code/libraries).
  4. Ensure that the necessary software components are available in your program's !Run file as follows:
    RMEnsure UtilityModule 3.10 Error This application requires RISC OS 3.10 or later
    RMEnsure UtilityModule 5.00 RMEnsure CallASWI 0.03 RMLoad System:Modules.CallASWI
    RMEnsure UtilityModule 5.00 RMEnsure CallASWI 0.03 Error This app requires CallASWI 0.03 or later
    RMEnsure FPEmulator 4.03 RMLoad System:Modules.FPEmulator
    RMEnsure FPEmulator 4.03 Error This application requires FPEmulator 4.03 or later
    RMEnsure SharedCLibrary 5.17 RMLoad System:Modules.CLib
    RMEnsure SharedCLibrary 5.34 Error This application requires SharedCLibrary 5.34 or later

Note that you should always specify 5.17 (the first 32-bit version) as the version of the Shared C Library required in the first RMEnsure - this will avoid the potentially fatal possibility of killing a RAM version that is currently in use (killing the ROM version is safe). The second RMEnsure asks for 5.34, as that is the first non-beta version. If you do require a newer version, only change the second RMEnsure.

The components provided within the enclosed !System application, together with the !SysMerge obey file, may be freely distributed with your RISC OS software.

Care should be taken if you are building a C module that is potentially shared by a number of programs - if your program installs a newer, 32-bit version of this shared module in a central location, existing programs may load the module without RMEnsuring the appropriate C library etc, causing problems if those programs are loaded first. This can be dealt with by installing the latest version of !System, which ensures the minimum components (as above) that are needed to run 32-bit programs are loaded when it is first seen.

Assembler programs

Hand-coded assembler programs, or subcomponents of programs should be written to be 26/32-bit neutral. For simple APCS fragments, this is straightforward.

For routines that need to manipulate the PSR or provide RISC OS module entry points, it is more complicated. The amount of complexity can be reduced by dropping RISC OS 3.1 compatibility, hence allowing the assumption that MRS/MSR instructions are available. More technical details of RISC OS APIs and 26/32-bit techniques are provided in the accompanying documents.

If you are writing much ARM code, obtain a copy of the latest ARM Architecture Reference Manual, commonly referred to as the ARM ARM. This is available as a printed book and also in PDF format free of charge from ARM upon request (ARM document number DDI-0100).

APCS-32

The new APCS variant for RISC OS is called "APCS-32"; it is the same as APCS-R, except that it is 32-bit PC, and LFM/SFM are used. Note that APCS-32 adds 2 extra provisos over basic APCS-3:

APCS-32 code must work when called in a 26-bit mode. This precludes constructs like:

            ADD     a1, a1, pc     ; may or may not add PSR flags

APCS-32 code must be able to call APCS-26 code (but not vice-versa). This requires that lr must contain the PSR flags on entry to all functions if the code is running in a 26-bit mode. So the following is illegal:

            ADR     lr, return     ; doesn't include PSR flags
            MOV     pc, r2
     return

The following is legal:

            MOV     lr, pc         ; includes PSR flags in 26-bit mode
            MOV     pc, r2

APCS-32 is transitional. It is likely that a move to a form of the new ATPCS will occur in the future. In that event, a new ATPCS C library would operate alongside the APCS-32 library to allow both old and new applications to work together.

How to be 26/32-bit neutral

Be aware that your program may be running in either 26 or 32-bit modes. As an application, you may be running in USR26 or USR32. As a module, you may be in SVC26 or SVC32. As a TickerV claimant you may be in IRQ26 or IRQ32. Write your code accordingly. Do not use <dop>S PC,... or LDM {...,PC}^ instructions except where documented as legal for 32-bit code.

It is often easiest to change function calls to not preserve the PSR. If PSR preservation is required, it can be done explicitly with MRS/MSR.

Use MRS and MSR instead of TEQP etc - these calls work perfectly well on the ARM 6 or later in either 26 or 32-bit modes. If RISC OS 3.1 compatibility is required, check the current processor mode and dynamically choose whether to use TEQP or MSR. Alternatively, use processor-independent instructions like CMP PC,#0 to clear the Z flag. Avoid instructions like CMP PC,#&80000000 to set the V flag - the program counter may be above &80000000.

Another possibility is to use macros controlled by build switches then produce separate RISC OS 3.1 and 3.5+ versions of your modules. This is the technique used by the FPEmulator module (although its 26/32-bit issues are more complex than most).

Be aware of the differences in behaviour on a 32-bit system. In particular, SWIs will no longer be expected to preserve flags as stated on PRM 1-29; indeed, they usually cannot. Flags may still be set to report results.

Avoid code sequences that have a different effect in 26 and 32-bit modes. For example:

Don't use:

           ADD   R0,R0,R15        ; includes PSR in R15 on a 26-bit system

Use:

           ADD   R0,R15,R0        ; never includes PSR

Don't use:

           BIC   R0,LR,#&FC000003 ; to find address of caller

Use:

           SUB   R0,LR,PC         ; R0 = LR - PC {- PSR}
           ADD   R0,PC,R0         ; R0 = LR {- PSR} + 4
           SUB   R0,R0,#4         ; R0 = LR {- PSR}

or:

           RSB   R0,PC,PC         ; R0 = PC {+ PSR} - PC = {PSR} 
           SUB   R0,LR,R0         ; R0 = LR {- PSR}

In both of the last two cases, the assumption is that the PSR has not been altered since function entry.

More technical information is provided in the accompanying document.

The Shared C Library

The Shared C Library module supplied here is suitable for RISC OS 3.10 or later. It requires FPEmulator 4.03 or later (to support the LFM and SFM instructions) and it also requires the CallASWI module on RISC OS 3.60 or earlier.

The C library supports the new APCS-32 calling standard, together with the existing APCS-R. It no longer supports APCS-A.

On a 32-bit RISC OS APCS-R will no longer be supported, unless via some form of 26-bit emulation software.

CallASWI

CallASWI 0.03 is an update to the CallASWI module provided with RISC OS 3.70; it ensures correct operation following a soft reset - particularly critical when the Shared C Library is relying on it.

FPEmulator

Version 4.19 of the Floating Point Emulator / FPA Support Code is provided here, in three forms to match different versions of RISC OS. Version 4.03 or later is required to support the LFM and SFM instructions used by the Shared C Library, and expected to be used by APCS-32 programs. An appropriate version is present in RISC OS 3.5 or later, but will need to be soft-loaded for RISC OS 3.1.

The FPPC hardware floating point system is no longer supported.

ANSILib

The ANSILib library supplied here is suitable for RISC OS 3.50 or later. It is provided for debug purposes only - linking it with released applications is liable to impact future compatibility.

CMHG

The version of CMHG supplied here will create APCS-32 module headers that are compatible with RISC OS 3.1 onwards, and will support 32-bit processors; it will set the "32-bit compatible" module header flag - it is up to you to ensure any assembler linked in to the module is 32-bit compatible.

© 2006 IYONIX Ltd 32-bit RISC OS