RISC OS Open
Safeguarding the past, present and future of RISC OS for everyone
ROOL
Home | News | Downloads | Bugs | Bounties | Forum | Documents | Photos | Contact us
Account

Converting older software to run on 32 bit systems

category: Help

Précis

This guide describes the problems regarding making software for older versions of RISC OS work on new (current) systems, such as the Beagle board, RaspberryPi, Panda board, etc.

While RISC OS itself is largely the same at the API level, the underlying hardware is fundamentally different.

If you are new to programming the ARM, I do not recommend this guide as it will make numerous references to “old” and “new” methods. No production ARM offers the older 26 bit modes, and it’s probably been a decade since any did. Please don’t waste your time learning any of this unless you have a specific need of this information.

Introduction

What is the problem?

If you recall, RISC OS originally ran on the ARM 2 and ARM 3 processors in such advanced (for their time) machines as the A310, A440, A3000, and the A5000. In those days, the machine had a 26 bit address bus permitting a maximum of 64MB to be addressed. Because of this, various processor “flags” (the current operating mode, the result of the least mathematical calculation, etc) were incorporated into the “Program Counter” that pointed to the address of the instruction being executed.
This describes the behaviour of all versions of RISC OS prior to RISC OS 5.

In this day and age, modern System-on-Chip (SoC) boards are likely to come with at least 256MB on board, and the more your board costs, the more it is likely to offer, up to Gigabyte sizes.
This necessitated a change in how the ARM addresses memory and holds status. R15, or PC, is now a full 32 bit pointer and the Processor Status Register (for the status and operating mode) is now a new special register. The differences are explained in more detail here

To put it bluntly, unless your programs are written in BASIC, your old code will not work (at least, not natively – you can run many old programs using Aemulor. You can read what Aemulor does and visit the Aemulor site).

How to convert…

Issues affecting all software

Due to the changes between older systems and modern ones, there are a number of issues that may affect your program:

  • If your program relies upon external resources (sound player modules, for example) then you will need to track down 32 bit safe versions. RISC OS 5 will not load modules written for older versions of RISC OS.
  • There are huge differences in display hardware. Generally speaking, 2, 4, and 16 colour modes are no longer available. For example, selecting MODE 2 on a RaspberryPi actually selects MODE 28 which is quite different. You may need to check that the colours you expected to set are, in fact, being set. The SWI ColourTrans_SetGCOL may help.
  • Do not assume the presence of ADFS, or floppy discs.
  • Anything that attempts to poke hardware by reading/writing specific addresses is pretty much guaranteed to fail. If your program bashes the IOC for access to the high resolution timer… that does not exist any more. To add insult to injury, the different SoCs implement such a thing in different ways. In some cases workarounds are available – Rik Griffin’s HalTimer provides access to the high resolution timer.
  • Do not attempt to directly access page zero (addresses below &8000).
  • Likewise, do not expect specific legacy hardware to exist. There are no floppies or harddiscs (any that are connected do so via USB). There is no parallel port. Serial ports generally exist in some manner, though typically only RxD and TxD are connected. DCD, CTS, etc are not.
  • Some SWIs have had their entry parameters tightened up for issues arising as a result of having a greater addressing range. Some SWIs (OS_UpdateMEMC) are just obsolete on modern hardware.
    Additionally, while the PRMs stated that SWIs accept ‘0’ as a null pointer, in many cases (the Wimp, especially) a negative value would be treated as a null pointer. This is no longer the case, and a zero should be used as per the documentation. <!-- Link to document detailing changes to SWIs when it exists... -->
  • Some SWIs have been obsoleted by newer versions. For instance, OS_IICOp replacing IIC_Control; and any of the filesystem DiscOp calls being replaced by DiscOp64 versions to overcome limitations in disc size and memory locations in the original SWI.
  • When dealing with pointers and addresses, you should no longer validate a pointer by checking to see if the value is positive, nor perform signed comparisons on them.
    You should no longer clear the &FC000003 bits from pointers or stuff flags into the high-order bits. Assume that the entire 32 bit value is now a valid address.

Programs written in BASIC

If your program is written in BASIC, with no assembly language code contained within, then you do not need to do anything special once you have made modifications as necessary for the issues described above.

Programs written using ABC

The official development suite contains an updated 32 bit safe version of the ABC compiler. So long as your program does not contain embedded assembler code, once you have resolved the issues mentioned above, it should suffice to rebuild your program from source using the latest version of the compiler.

Programs written in C

Most software for RISC OS is written in C due to its speed, flexibility, and greater ease of maintenance than other languages available.
If your program is written in pure C, once you have resolved the issues mentioned above, all you will then need to do is to rebuild your project using the latest official development suite or GCC if you originally used that.

If you are using libraries that are not the standard libraries provided with the compiler, you will need to replace your older libraries with newer, compatible, versions. In order to help you:

  • OSLib
  • UnixLib
  • DeskLib (official v2.80)
  • DeskLib (Rick Murray’s 32 bit conversion of the widely-used v2.30 version)
  • Desk v3.20 – I am not currently aware of a conversion of this library.
  • Numerous other useful libraries (GNU LibXXX, etc) are available.

Programs written in assembler, or containing assembler

Assembly language is the most complicated as it needs to be modified by hand and due to the earlier API’s requirement that flags be preserved, there are likely to be a lot of places where minor modification is necessary.

The first thing you must do is to pick up a copy of The ARM Club’s ARMalyser. This tool is invaluable in helping to detect parts of code that need changing.

Continue reading…

ARM code in a 32 bit world

Instructions to be avoided

The first main problem, and the complete show-stopper, is that the Processor Status Register (PSR) and the Program Counter (PC) are no longer combined. As a result of this, anything that tries to manipulate the PSR by performing operations on PC will fail. An example is returning from an instruction with the V set using ORRS PC, LR, #(1 << 28).

You should note that the following instructions will no longer work as expected:

  • MOVS PC
  • TEQP
  • LDM ^
  • TST xx, PC
  • Anything that tries to set bits in PC (such as the ORRS above)

The second problem that affects modern processors is the behaviour of unaligned loads – that is to say, executing an LDR instruction on an address that is not word aligned.
This issue has always been contentious, and it can be roughly summarised as follows:

  • Old ARMs (Archimedes, RiscPC, Iyonix, emulators):
    • LDM, STM, and STR would ignore bits 0 and 1 and access a word aligned address
    • LDR would load from a word aligned address and rotate in a complex manner
  • ARMv6 (RaspberryPi):
    • Has an option to configure the old behaviour described above, or the new behaviour described below, or to just abort.
  • ARMv7+ (Beagle, Panda, etc):
    • Can be configured to abort on all unaligned word accesses, otherwise:
    • LDM and STM will always abort.
    • LDR and STR will perform sequential memory accesses to read or write a word at a non-aligned address

The ARMv7 compatibility primer describes the behaviour of non-aligned loads and stores in more detail.

It is worth mentioning that if you are using LDR to read data byte by byte, you should be using LDRB instead.

Detecting 32 bit mode

The legitimate way of detecting a 32 bit system is to called the SWI OS_PlatformFeatures, which will return various flags that indicate the features of the current system. You are particularly interested in bit 6 which means that it is a 32 bit version of RISC OS, and bit 7 which means the processor does not support the older 26 bit mode.

In assembler, the following code can be used to detect a 32 bit mode:

    TEQ R0, R0    ; Set Z flag
    TEQ PC, PC    ; Set Z flag if in 32 bit mode

This works because the second operand to TEQ will include the flags in 26-bit mode, but not in 32-bit mode, whereas the first operand never includes the flags. We are therefore comparing PC with PC+PSR if in 26-bit mode, but comparing PC with PC in 32-bit mode. This will set Z in 32-bit mode but not in 26-bit mode since we know at least one bit (the Z flag) is set in the PSR. Note that the first instruction can be omitted if a flag is known to be set (eg the V flag) or if not in user mode (since one of the mode flag bits will be set).

If in SVC mode (a relocatable module), you could also use the instruction:

    CMP PC, PC

This replies EQual on a 32 bit system, and NotEqual on a 26 bit system, for the same reasons as above (comparing PC with PC+PSR and a mode bit is set; so will differ on a 26 bit system, but will be identical on a 32 bit system as the mode bit is stored elsewhere).

Work in progress – more to come.

Revised on May 25, 2014 15:41:44 by Rick Murray (539) (90.32.36.30)
Edit | Back in time (3 revisions) | See changes | History | Views: Print | Source | Linked from: Programmer documentation

Search the Wiki

Social

Follow us on and

ROOL Store

Buy RISC OS Open merchandise here, including SD cards for Raspberry Pi and more.

Donate! Why?

Help ROOL make things happen – please consider donating!

RISC OS IPR

RISC OS is an Open Source operating system owned by RISC OS Developments Ltd and licensed primarily under the Apache 2.0 license.

Navigation

  • Home Page
  • All Pages
  • Recently Revised
  • Authors
  • Feeds
Site design © RISC OS Open Limited 2018 except where indicated
The RISC OS Open Instiki theme is based on Insitki's default layout

Valid XHTML 1.0  |  Valid CSS

Instiki 0.19.1(MML+)
This site runs on Rails

Hosted by Arachsys