Changes to APIs due to 32-bit addressing
Document version 0.13, 14 May 2002
A fully 32-bit OS opens up the possibility of more areas of memory being
above 64MB. Currently the application slot, module area and ROM are all
below 64MB, but it is likely that in the future the module area and ROM
will move higher to allow the application slot to be limited only by
physical RAM (reducing the need for normal programs to create their own
dynamic areas, and wasting logical address space).
Now that the Relocatable Module Area (RMA) is at a high address a number of
26-bit APIs in RISC OS 3/RISC OS 4 that place flags in the top bits of
addresses are liable to fail. Similar problems can also occur in a program
with a very large application slot.
This document summarises the API changes in ROSC OS 5 to avoid these
problems. All of the new 32-bit APIs are available in RISC OS 5.00 except for
the Draw_ProcessPath change which will be introduced in Draw 1.17 and
supplied with RISC OS 5.04.
A number of 26-bit APIs, particularly in the Window Manager, allow registers or
other values to be a either be a pointer or <= 0. These APIs are being
changed to only accept -1 or 0 as a non-pointer value.
Also, some APIs are documented as only accepting 0 as a non-pointer value,
such as the scaling factors in OS_SpriteOp 52, but actually treat any
negative value as a non-pointer; these are being tightened up to match
the documentation.
In existing OSes, R0 is interpreted as a 26-bit address, with 6 flag bits, 4
currently unused.
In a 32-bit OS, OS_ReadLine now interprets R0 as a 32-bit address, and acts
as though the flags are both clear. This reflects the most common usage, and
allows applications not wanting to use the flags to remain unaltered.
A new SWI, OS_ReadLine32, takes its flags in R4. Bits 31 and 30 correspond to
the original flags. Bits 29-8 are reserved and must be zero. Bits 7-0 are
used as the echo byte (if bit 30 is set). As before, R4 is preserved by the
call.
ReadLineV, in a 32-bit OS, is called as though from OS_ReadLine32; ie on
entry R0 is the buffer address and R4 contains the flags (always valid,
regardless of which SWI was called).
A ReadLineV claimant may handle this at run-time by beginning their
handler:
ReadLineV_Handler
STMFD R13!, {R4, R14} ; must preserve R4
TEQ PC, PC ; 26 bit OS?
ANDNE R14, R0, #&FC000000 ; if so, extract flags
ANDNE R4, R4, #&FF ; and potential echo byte
ORRNE R4, R4, R14 ; combine into new form
BICNE R0, R0, #&FC000000 ; may corrupt R0
...
; R0 now address
; R4 now flags plus echo byte
Because of the way ReadLineV operates, any OS_ReadLine32 SWI on a 26-bit
OS will return an error if R0 > 64MB.
When using either SWI, applications for existing 26-bit OSes should ensure
that the buffer is in a low address - eg allocated in the RMA or application
space.
In existing OSes, R0 is interpreted as a 31-bit address, with 1 flag bit.
In a 32-bit OS, OS_SubstituteArgs now interprets R0 as a 32-bit address, and
acts as though the flag is clear. This allows applications not wanting to use
the flags to remain unaltered.
The new SWI OS_SubstituteArgs32 interprets R0 as a 32-bit address, and takes
a flags word in R5. Bit 31 of R5 corresponds to the existing bit 31 of R0;
bits 30-0 are reserved. R5 is preserved across the call.
In existing OSes, R1 is interpreted as a 29-bit address, with 3 flag bits.
Also, due to a long-standing bug, instead of inspecting bit 31, the call
inspects bit 30, meaning bit 30 causes the documented functions of both bits
30 and 31 to occur, while bit 31 is ineffective.
In a 32-bit OS, the SWI continues to work in the same way, with R1 being
interpreted as a 29-bit address plus flags, and with the flags bug preserved
for backwards compatibility.
The new SWI OS_HeapSort32 interprets R1 as a 32-bit address, and takes a
flags word in R7. Bits 31-29 of R7 correspond to bits 31-29 of R1, but with
the flags bug corrected, so each bit functions as documented on PRM page
1-939.
The API for calling Draw_ProcessPath in Draw modules has a shortcoming by
combining a flag in bit 31 of R7 with a pointer to either the output path or
the output bounding box.
This will therefore perform the wrong action when applications make a call to
it where the output is unwittingly requested from some top bit set piece of
memory, for example a dynamic area which has its top bit set.
Example
| Output address: | | &A0000000
| | Desired effect: | | Output a path
| | Actual effect: | | Output the bounding box to &20000000
| | | May lead to a data abort if &20000000 is not mapped in
|
Note that this problem exists in version 1.16 of the "Drawing module" which
is present in RISC OS 5 up to and including version 5.03.
Therefore, from version 1.17 of the "Drawing Module" the Draw_ProcessPath SWI
can optionally be called giving the full 32 bit pointer in R7:
Draw_ProcessPath (&40700)
Entry:
| R0 -> | | path block
| | R1 = | | fill style and flags
| | | New flag bits:
| | | bit 26 set: the pointer in R7 is a 32 bit value
| | | bit 26 clear: behave per old API
| | | bit 25 set: output the bounding box to memory at R7
| | | bit 25 clear: output the path to memory at R7
| | | Attempting to set bit 25 without having set bit 26 too will result
| | | in a "Reserved bits non zero" error.
| | R2 -> | | transformation matrix, or 0 for none
| | R3 = | | flatness, or 0 for default
| | R4 = | | thickness, or 0 for default
| | R5 -> | | join/cap block, or 0 for none
| | R6 -> | | dash pattern block, or 0 for none
| | R7 -> | | output block (or special value if < 4)
|
Exit:
| If R7 = | | 0, 1, 2 on entry | | R0 => | | corrupt
| | If R7 = | | 3 on entry | | R0 => | | size required
| | If R7 -> | | output block | | R0 => | | new end of buffer
|
See also PRM volume 3 (page 3-535 in Acorn's printed edition).
A simple BASIC patch program will be available so that applications authors
can immediately migrate to the new API without fears of backwards
compatibility. Applications authors are free to distribute the patch and
should use an appropriate set of RMEnsures to decide whether it is necessary
to invoke it.
Attempting to call this SWI with bits 26 or 25 set on unpatched versions and
versions before 1.17 will result in a "Reserved bits non zero" error.
Version 1.17 of the Draw module will be supplied with RISC OS 5.04.
 |
| © 2006 IYONIX Ltd |
32-bit RISC OS |
|