-----------------------------------------------------------------------------
4th October 1996
-----------------------------------------------------------------------------
Engineering Support Application Note
Number: 295
Issue: 2.02
-----------------------------------------------------------------------------
Introduction to StrongARM and Programming Guidelines

-----------------------------------------------------------------------------
Notes: 
This Application Note introduces the StrongARM SA-110 processor, and details
the issues which arise owing to the differences between it and earlier ARM
processors. We also introduce RISC OS 3.7, and describe its enhancements
over RISC OS 3.6.
-----------------------------------------------------------------------------
Applicable Hardware: 
Any system equipped with RISC OS 3.7 

Related Application Notes: 
None

-----------------------------------------------------------------------------
Copyright (C) 1996 Acorn Computers Limited 

Every effort has been made to ensure that the information in this leaflet is
true and correct at the time of printing. However, the products described in
this leaflet are subject to continuous development and improvements and
Acorn Computers Limited reserves the right to change its specifications at
any time. Acorn Computers Limited cannot accept liability for any loss or
damage arising from the use of any information or particulars in this
leaflet. Acorn, the Acorn Logo, ART, the ART logo, Acorn Risc PC, ECONET,
AUN, Pocket Book and ARCHIMEDES are trademarks of Acorn Computers Limited.

ARM is a trademark of Advanced RISC Machines Limited.
All other trademarks acknowledged.
-----------------------------------------------------------------------------
Engineering Support
Acorn Risc Technologies
Acorn House
645 Newmarket Road
Cambridge
CB5 8PB                                           
-----------------------------------------------------------------------------

Introduction to the StrongARM                        
-----------------------------
The StrongARM 110 is a new high-performance processor from Digital
Semiconductor. It offers performance improvements over the ARM710 ranging
from 100% to 1000%, depending on the application.

A StrongARM processor card will available for the Risc PC later this year.
It will come with a new ROM set containing RISC OS 3.70, a new
StrongARM-compatible version of RISC OS. These documents provide information
on writing software, and modifying existing software, for StrongARM-based
machines.


Significant StrongARM features

    * 202MHz core clock
      
    * 5-stage pipeline (Fetch, Issue, Execute, Buffer, Write)
      
    * Separate 16K write-back data cache and 16K instruction cache
      
    * 8 entry write buffer, each entry holding 1-16 bytes
      
    * Fast 32 and 64 bit result multiply instructions
    
    * Averages fewer cycles per instruction than previous ARMs
      

Incompatibilities
-----------------
The StrongARM has two significant differences from previous ARMs that can
affect existing programs. Firstly, the split caches mean that instructions
written into memory may linger in the data cache, and not be in real memory
when the instruction cache comes to fetch them. Likewise if some code is
already in the instruction cache, and it is altered, the changed code will
not be noticed. Thus existing self-modifying code and dynamic code creation
or loading will generally not work.

RISC OS 3.7 provides a call to synchronise the instruction and data caches,
but this is a slow operation on the StrongARM. Self-modifying code should
therefore be avoided. The most common failures here arise from custom SWI
veneers that assemble code on the stack, dynamic code loading and linking
and custom code squeezing and encryption.

The other significant StrongARM change is that storing the PC to memory
(using STR or STM) stores PC+8 rather than PC+12. This can generally be
catered for by judicious use of NOPs to allow for both possibilities. This
affects, for example, APCS stack backtraces and vector claimants (the
example code on PRM page 1-107 will not work, for example).

There are other differences that are only likely to be encountered by
low-level system code.

Most applications will run unmodified on StrongARM, especially those written
in C and BASIC, but some code will inevitably need modification.

Guidelines for Authoring Software for StrongARM
-----------------------------------------------
* Code written in C or BASIC will generally work, but see issues below.

* Code using the shared C library or Toolbox is generally fine. Using
  RISCOS_Lib may cause problems, depending on the variant - re-linking to a
  revised implementation will typically be sufficient. Anything linked with
  ANSILib will not work. Products should _not_ be linked with ANSILib.

* Proprietary code squeezers may cause problems. Unsqueezed code or standard
  squeezed code with AIF headers (eg code produced with our Squeeze system) is
  generally fine. A new module, UnsqueezeAIF, detects squeezed images and
  unsqueezes them itself with a negligible performance penalty.

* An application patcher will be supplied with RISC OS 3.7 that is capable
  of detecting some known StrongARM-incompatible code sequences in an AIF
  image and replacing them before the image is executed. This is only a
  temporary solution though. If you find your software works only because the
  patcher is patching it, you should modify it so it does not need patching.

* All Absolute files must have valid AIF headers. Absolute files without AIF
  headers and untyped files are deprecated.
  
When writing in Assembler:

* Any self-modifying code or dynamically generated code is a problem. RISC
  OS 3.7 provides a SWI to support StrongARM synchronisation to dynamic code,
  but the performance penalty is typically severe; cleaning the data cache
  will take some time, and the entire instruction cache must be flushed.
  Hence, most cases of dynamic code can no longer be justified, and should be
  reimplemented in a static manner. One common reason for dynamic code is the
  calling of a SWI by SWI code passed in a register. RISC OS 3.7 provides a
  new SWI which implements this in an entirely static manner.

* The StrongARM pipeline is generally not a problem (even though it is now 5
  levels deep rather than 3). The main issue is storing of the PC to memory
  using STR and STM; this now stores PC+8 instead of PC+12. Code should be
  made to work whether PC+8 or PC+12 is stored (so that ARM 6,7 are still
  supported). Use of the PC in data processing instructions (MOV, ADD etc)
  remains unaltered on StrongARM.

* STRB PC has an undefined result. This has sometimes been used as a
  shortcut for storing a non-zero semaphore value in speed critical code. This
  instruction should no longer be used. Use STR PC or STRB of some other
  register.

Other differences at the assembler level, which affect RISC OS itself but
are unlikely to affect applications are:

* StrongARM does not support 26 bit configuration. It does support 26 bit
  mode within a 32 bit configuration.

* The control of architecture functions via coprocessor #15 is significantly
  different. The requirements for context switching are significantly more
  complex.

* The 'abort timing' (definition of values in affected registers) for data
  aborts has changed.

At the hardware level:

* When storing a byte, previous ARMs replicate the byte across the entire 32
  bit data bus. StrongARM only outputs the byte on the relevant byte lane. The
  StrongARM processor card implements a compatibility fix for pre-Risc PC
  style podules as follows: bytes stored to word aligned addresses (byte 0)
  will be replicated on byte 2.  This should allow most podules to work
  without firmware changes.

Backwards compatibility:

* Much StrongARM-ready code (especially in libraries, such as the
  aforementioned revised RISC_OSLib) may use the new SWI-calling mechanism.
  Therefore a new module "CallASWI" will be made available for use on RISC OS
  3.1, 3.5 and 3.6 to provide the SWIs OS_CallASWI, OS_CallASWIR12,
  OS_PlatformFeatures and OS_SynchroniseCodeAreas.

Changes to Existing SWIs
------------------------                       
OS_MMUControl (page 5a-70)

    This SWI has a new reason code, to support platform independent cache 
    and/or TLB flushing:

OS_MMUControl 1 (SWI &6B)

    Cache flush request
    
On entry
    R0 = reason code and flags
           bits 0-7  = 1 (reason code)
           bits 8-28 reserved (must be zero)
           bit 29 set if flush of single entry, else complete flush
           bit 30 set if processor TLBs are to be flushed
           bit 31 set if processor caches are to be flushed
    R1 = logical address, if R0 bit 29 set

On exit
    R0,R1 preserved

Interrupts
    Interrupt status is not altered
    Fast interrupts are enabled

Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is not re-entrant
    
Use
    This call implements platform independent cache and/or TLB flushing.
    
WARNING: This SWI reason code is only intended for occasional, unavoidable
requirements for cache/TLB flushing. You should respect the performance
implications of this SWI reason code, in a similar way to SWI
OS_SynchroniseCodeAreas.
             
 Currently, bit 29 is ignored, so that only whole flushing of caches and/or
TLBs are supported. A cache will be cleaned before flushing, where the
processor supports a write-back cache.

 This reason code is not re-entrant. Interrupts are not disabled during the
flush, so the cache or TLB flush can only be considered to be complete with
respect to logical addresses that are not currently involved in interrupts.


OS_File 12, 14, 16 and 255 (page 2-40)

If R3 bit 31 is set on entry, the file being loaded will be treated as code,
and the relevant area will be synchronised using OS_SynchroniseCodeAreas if
necessary.

A filetype for Code (&F95) has been allocated, with the intention that it be
a parallel of Data (&FFD), and when it is loaded a synchronise is
automatically performed. However this functionality has not been implemented
in RISC OS 3.70; you will still need to set bit 31 as described above.

Note that the *Load command calls OS_File 255 with bit 31 of R3 set, so no
synchronise is required. This is to aid backwards compatibility; if no
synchronisation is required, then use OS_File 255 directly.


DMA (page 5a-83)

The DMA Manager now marks pages uncacheable for both transfers from device
to memory and transfers from memory to device. This is to ensure StrongARM's
write-back cache is cleaned before the transfer starts.

New Service Calls

Service_UKCompression (Service call &B7)

    An application that may need unsqueezing/patching has just been loaded
    
On entry
    R0 = subreason code
           0 -> first pass (unsqueeze)
           1 -> second pass (patch)
           all other codes reserved
    R1 = &B7 (reason code)
    R2 = load address
    R3 = size
    R4 = execute address
    R5 = filename (as passed to FileSwitch, not canonicalised)

On exit
    R1 preserved to pass on, or 0 to claim if you know you have performed
  all required unsqueezeing/patching for this pass.

    R3 may be modified to indicate an altered size (eg after unsqueezing)
    R4 may be modified to specify an new execute address
    Other registers preserved

Use
    This service call is passed around when an Absolute (&FF8) file is run.
    The sequence of events is as follows.
    
      1) The image is loaded.
      2) If it does not contain an unsqueezed AIF header, then
         Service_UKCompression 0 is issued.
      3) Service_UKCompression 1 is issued.
      4) OS_SynchroniseCodeAreas is called.
    
Therefore unsqueezers and patchers need not do any synchronisation except
that necessary for their internal working (they may want to alter some code,
synchronise, and call it before returning from the service call).
     Two modules are supplied with RISC OS 3.7 that use this service call:
    
 UnsqueezeAIF will unsqueeze squeezed AIF images on the first pass, and
squeezed non-AIF images by code modification (so the unsqueeze will not
occur until after stage 5 above)
    
 AppPatcher will patch squeezed and unsqueezed AIF images containing certain
common code sequences that are known to fail on StrongARM.

Scanning an application for code sequences is a relatively slow operation.
Therefore a bit has been allocated in the AIF header to indicate that a
program is "StrongARM-ready". If bit 31 of the 13th word of the AIF  header
(ie bit 31 of location &8030 in the loaded image) is set, the patching stage
will be skipped (in RISC OS 3.7 by AppPatcher claiming the service call and
doing nothing; in a future version of RISC OS FileSwitch may not issue the
service call). The program will still be automatically unsqueezed; it is
recommended that you continue to use the existing Squeeze utility provided
with Acorn C/C++, and rely on the operating system to unsqueeze the image
for you.
   
Service_ModulePreInit (Service call &B9)

    A module is about to be initialised
    
On entry
    R0 = module address
    R1 = &B9 (reason code)
    R2 = module length

On exit
    R1 preserved to pass on

Use
    This service is called just before a module is initialised. When a
    module is *RMLoaded:
    
       1) The module is loaded into memory
       2) The module is unsqueezed if necessary
       3) Service_ModulePreInit is called
       4) OS_SynchroniseCodeAreas is called
    
    This service call is intended to allow run-time patching of modules.
    
    
New SWIs
--------
OS_PlatformFeatures (SWI &6D)

    Determine various features of the host platform

On entry
    R0 = reason code (bits 0-15) and flags (bits 16-31, reason code
         specific)
    Other registers depend upon the reason code

On exit
    Registers depend upon the reason code

Interrupts
    Interrupt status is unaltered
    Fast interrupts are enabled
    
Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is re-entrant

Use
    This new SWI is used to determine various feaures of the platform that
    the application or module is running on.

    The particular action of OS_PlatformFeatures is given by the reason code
    in bits 0-15 of R0 as follows:
    
        R0    Action
          0     Read code features

OS_PlatformFeatures 0 (SWI &6D)

    Read code features

On entry
    R0 = 0 (reason code); all flags are reserved, so bits 16-31 must be
    clear

On exit
    R0 = bit mask of features:
           Bits     Meaning
           0        Must tell OS when code areas change (by calling
                    OS_SynchroniseCodeAreas)
           1        Enabling, then immediately disabling interrupts will not
                    give interrupts a chance to occur
           2        Must be in 32 bit mode to read hardware vectors
           3        Storing PC to memory (eg with STR or STM) stores PC+8
                    rather than PC+12
           4        Data aborts occur with 'full early' timing (ie. as
                    defined by ARM Architecture 4)
                                
   If bit 1 of R0 set then                             
     R1 -> routine to call between IRQ enable & disable.

Use
    This call determines features of the host processor's instruction set.
    
 Platforms running ARM 6 or 7 cores will return with R0 bits 0-4 clear;
platforms running StrongARM will return with bits 0-4 set in RISC OS 3.7
(but bit 2 should in fact be clear). For compatibility with older versions
of RISC OS, you should call this SWI in the X form; if V is set on return
and the error is 'SWI not known', then this can be taken as equivalent to a
return with R0 bits 0-4 clear. Note that the easiest way to deal with the
PC+8/PC+12 issue across all platforms is to make sure that the code is valid
in either case (typically with judicious use of NOPs).

The routine pointed to by R1 is suitable for calling from any 26-bit
mode; it preserves all flags and registers, and is reentrant. It should be
called as follows:
     
LDR    R0, irqroutine   ; Load address previously stored in workspace
MOV    R14, PC          ; Get return address of PC+8
MOV    PC, R0           ; Call routine
...                     ; Code returns here
  

OS_SynchroniseCodeAreas (SWI &6E)

    Inform the OS that code has been altered

On entry
    R0 = flags
           bit 0 clear  Entire address space to be synchronised.
           bit 0 set    Address range to be synchronised.
           bits 1-31    Reserved

    If R0 bit 0 is set then:
        R1 = low address of range (word aligned)
        R2 = high address (word aligned, inclusive)

On exit
    R0-R2 preserved

Interrupts
    Interrupt status is not altered
    Fast interrupts are enabled

Processor mode
    Processor is in SVC mode

Re-entrancy
    SWI is not re-entrant

Use
    This new SWI informs the OS that code has been newly generated or
modified in memory, before any attempt is made to execute the code.

WARNING: This SWI is only intended for synchronisation with unavoidable use
of dynamic code, because of the potential for large performance penalties.
There is no longer any justification in RISC OS applications for frequent
code modification. This call  must never be used in an interrupt routine.
Examples of  reasonable use include one-off loading, relocation etc. of 
subsidiary code or libraries.

      When using this SWI, you should use the ranged variant wherever
possible, in order to minimise the performance penalty.

     The call may take a long time to return (up to around 0.5ms), so it
should not be called with interrupts disabled.

 For compatibility with older versions of RISC OS, you should either have
determined (with OS_PlatformFeatures) that this SWI should not be called, 
or always call this SWI in the X form, and ignore any error returned. On
platforms that do not require code synchronisation (as indicated by
OS_PlatformFeatures 0), OS_SynchroniseCodeAreas will do nothing.

 Note that standard loading of applications or modules (and the standard C
overlay system) are automatically handled by the OS, and do not require
synchronisation. This may be defeated by custom squeezing, failure to use a
standard AIF header for applications, and so on.

OS_CallASWI (SWI &6F)

   Call a run-time determined SWI

On entry
    R0-R9 as required for target SWI
    R10 = target SWI number

On exit
    R0-R9 as defined by target SWI
    R10 preserved

Interrupt status
   As defined by target SWI

Processor mode
   As defined by target SWI

Re-entrancy
   As defined by target SWI

Use
    This new SWI allows a target SWI number to be determined at run time,
and passed in a register. This removes the need for a common idiom of
dynamic code, in language library SWI veneers for example. In an APCS-R 
library, OS_CallASWIR12 may be more appropriate (see below).

 Note that OS_CallASWI is merely an alias for calling the target SWI. It has
no entry/exit conditions of its own, except for the special use of R10. To
call a target SWI with X bit set, us the X form of the SWI number in R10;
there is no distinction between OS_CallASWI and XOS_CallASWI.

 You cannot call OS_CallASWI or OS_CallASWIR12 via OS_CallASWI, since there
is no defined final target SWI in this case.

 You cannot usefully call OS_BreakPt or OS_CallAVector using OS_CallASWI, as
OS_CallASWI will corrupt the processor flags before entering the target SWI.
    
 For future compatibility, you should always use this SWI in preference to
any local construction for calling a SWI by number. For compatibility with
older versions of RISC OS, a new CallASWI module will be made available (see
below).
    
 Note that this SWI calling mechanism is almost certainly faster than any
other alternative implementation, including the original _kernel_swi  and
_swix code contained in older versions of the SharedCLibrary. The new
SharedCLibrary now simply uses OS_CallASWIR12 for _kernel_swi and  _swix.
    
 OS_CallASWI cannot be called from BASIC as BASIC only passes registers
R0-R7 via its SYS instruction. It would not be useful anyway.

OS_AMBControl (SWI &70)

    This SWI is for system use only; you must not use it in your own code.

OS_CallASWIR12 (SWI &71)

    Call a run-time determined SWI

On entry
    R0-R9 as required for target SWI
    R12 = target SWI number

On exit
    R0-R9 as defined by target SWI
    R12 preserved

Interrupt status
   As defined by target SWI

Processor mode
   As defined by target SWI

Re-entrancy
   As defined by target SWI

Use
    This call is identical to OS_CallASWI, except that it uses R12 to
specify the target SWI. This may be more convenient in some environments. In
particular under APCS-R, R10 is the stack limit pointer, which must be
preserved at all times; if a SWI called using OS_CallASWI were to abort or
generate an error the run-time library would usually examine R10 and decide
that it had no stack to handle the abort or error. Therefore APCS-R
libraries must use OS_CallASWIR12 (R12 being a scratch register  under
APCS-R).

The CallASWI Module
-------------------
The CallASWI module provides support under RISC OS 3.1, 3.5 and 3.6 for the
following SWIs:

              OS_CallASWI
              OS_CallASWIR12
              OS_PlatformFeatures
              OS_SynchroniseCodeAreas

This will enable application programmers and library writers to use the new
calls freely without any worries about backwards compatibility. There is no
performance penalty for the use of these SWIs via the CallASWI module. One
slight caveat is that older machines will not know the names of these SWIs;
they would have to be called by number from BASIC.

Performance issues
------------------
The StrongARM has significantly different performance characteristics to
older ARM processors. It is clocked 5 times faster than any previous ARM,
and many instructions execute in fewer cycles. In particular

    *  B/BL take 2 cycles, rather than 3
    *  MOV PC,Rn and ADD PC,PC,Rn,LSL #2 etc take 2 cycles rather than 3
    *  LDR takes 2 cycles (from the cache) rather than 3, and will take only
       1 cycle if the result is not used inthe next instruction.
    *  STR takes 1 cycle rather than 2, if the write buffer isn't full
    *  MUL/MLA take 1-3 cycles rather than 2-17 cycles.
    *  Many instructions will in fact take only one cycle provided the
       result is not used in the next instruction.

For fuller information see the StrongARM Technical Reference Manual,
available from Digital Semiconductor's WWW site (currently at
http://www.digital.com/info/semiconductor/dsc-strongarm.html)

The StrongARM's cache and write buffer are also significantly better than
previous ARMs, allowing an average fivefold speed increase, despite the
unaltered system bus. Pumping large amounts of data will still be limited by
the system bus, but advantage can be taken of the write buffer to interleave
a large amount of processing with memory accesses. For example on StrongARM
it is quicker to plot a 4bpp sprite to a 32bpp mode than to plot a 32bpp
sprite to a 32bpp mode; the latter case is pure data transfer, while the
former is less data transfer with interleaved (ie effectively free)
processing.

The long cache lines of the ARM710 and StrongARM can impact performance. A
random read or instruction fetch from a cached area will load 8 words into
the cache; this can make traversal of a long linked list inefficient. It is
also often worth aligning code to an 8-word boundary. In current versions of
RISC OS modules are loaded at an address 16*n+4. Future versions of RISC OS
will probably load modules at an address 32*n+4, so it is worth aligning
your service call entries appropriately in preparation for this change.

Two significant disadvantages of StrongARM over previous processors are:

1) Burst reads are not performed from uncached areas. In particular this
   means that reads from the screen are slower on the StrongARM than on
   previous ARMs. A future version of RISC OS may address this by marking
   the screen cacheable before reading (eg in a block copy operation). Also,
   burst writes are not performed to unbuffered areas.

2) Code modification is expensive. You can modify code, but a complete
   SynchroniseCodeAreas can take of the order of half a millisecond (ie
   100000 processor cycles) to execute, and will flush the entire
   instruction cache. Thus use of self-modifying code is strongly
   deprecated; a static alternative will almost always be faster.
   Synchronisation of a single word (eg modifying a hardware vector) is
   cheaper (of the order of 100 processor cycles) but still requires the
   whole instruction cache to be flushed.

Note that future processors will no doubt have different performance
characteristics again; you shouldn't optimise your code too much for one
particular architecture at the expense of others. However, hopefully you
will now have a better idea how to get better performance from your
StrongARM.

Use of FIQs
-----------
FIQ usage is now deprecated. When you modify the FIQ vector, you will need
to synchronise the code. However, as FIQ routines cannot call SWIs you are
unable to call OS_SynchroniseCodeAreas. For StrongARM compatibility we
recommend you use the FIQ vector as follows:

     0000001C: LDR PC,&00000020
     00000020: <address of FIQ handler>
     
and use the following code to do the synchronise manually when you write the
instruction at location &1C (no synchronise is required when you alter the
address at &20).

        .
        <alter FIQ vector>
        .
        MRC    CP15,0,R0,C0,C0           ; get processor ID
        AND    R0,R0,#&F000
        TEQ    R0,#&A000
        BNE    NotStrongARM
        MOV    R0,#&1C           
        MCR    CP15,0,R0,C7,C10,1        ; clean data cache entry for FIQ vector
        MOV    R0,#0
        MCR    CP15,0,R0,C7,C10,4        ; drain write buffer
        MCR    CP15,0,R0,C7,C5           ; flush whole instruction cache
  NotStrongARM
        .
        .
        .

If you want to write a complete FIQ handler into locations &1C to &FC, you
should clean each 32-byte data cache line containing written code thus:

  replace
        MOV     R0,#&1C
        MCR     CP15,0,R0,C7,C10,1
        
  with
        MOV     R0,#&E0              ; clean complete FIQ area
  01    MCR     CP15,0,R0,C7,C10,1   ; 32 bytes (1 cache line) at a time
        SUBS    R0,R0,#&20
        BGE     %BT01
        
This will usually be slower than the approach recommended above.

This is, of course, not a future-proof solution. We recommend that no new
products use FIQ code. If you feel you have a pressing need to use FIQs,
contact ART Developer Support for advice.

Miscellaneous Changes in RISC OS 3.7 Not Directly Related to StrongARM
----------------------------------------------------------------------
The Kernel
----------
The System ROM is now marked read-only in the MMU page tables of machines
with an ARM7 or later processor. Attempts to write to ROM space will cause a
data abort.

The kernel is now aware of multiple applications (see below).

FileSwitch
----------
FileSwitch now supports 2048-byte buffers (see FSEntry_Open on page 2-531).

The Window Manager
------------------
The Window Manager has now delegated application memory management to the
kernel. The kernel is now aware of multiple application memory blocks (AMBs)
and pages them in and out when requested by the Window Manager. This
improves task switching performance, as the kernel is able to remap AMBs far
faster than the Window Manager was able to using OS_SetMemMapEntries.

The Font Manager
----------------
The Font Manager now supports background blending in modes with 256 colours
or more. This blending causes the anti-aliased pixel data to be blended with
the background colour rather than using the fixed colour specified in the
various colour setting SWIs.

To use the blending, you should set bit 11 of R2 in the call to Font_Paint.
However, you need to ensure the following:

 1) The font colours specify that there is >= 1 anti-aliasing colour,
    otherwise the Font Manager will attempt to paint from 1bpp cache data
    rather than the 4bpp anti-aliased data.
  
     
 2) The Font Manager you are calling supports this bit, as previous versions
    of the Font Manager will complain if they find this bit set. You should
    call Font_CacheAddr to check the version of the Font Manager your
    application is running on, and only set  the bit on Font Manager 3.35 or
    later.

There is a noticeable speed hit in using blending, so you should not use it
if you know you are plotting onto a uniform background.

Blending should not be activated during printing.

Debugger
--------
SWI Debugger_Disassemble is now aware of the complete ARMv4 instruction set.

Note that the LDRH, LDRSH and STRH instructions are not supported by the
Risc PC memory system; although they will often work in a cached area
because memory is accessed a 4 or 8 words at a time, they will not work
reliably. LDRSB, MULL and MLAL may be freely used (except of course they
won't be backwards-compatible). Contrary to the information in the Acorn
Assembler manual about the ARM7M, the long multiply instructions can be used
in 26-bit modes.

Econet
------
A StrongARM-compatible Econet module has been placed in the System ROM,
rather than the RiscPC/A7000 Econet card firmware being upgraded.

The Internet module
-------------------
The Internet module supplied with RISC OS 3.70 is a major new version based
on FreeBSD, a 4.4BSD-derived UNIX. It offers improved performance, and a
wider API, including support for multicasting and T/TCP. All calls
documented in chapter 123 of the Programmer's Reference Manual continue to
work as documented, but some of the lower-level socketioctl calls,
particularly those to do with route manipulation have been withdrawn. More
details will be made available later.

A revised !Internet application is supplied as part of the !Boot structure
and a new application provides an easy interface for configuring the various
networking components built in to RISC OS 3.7

Access
------
Access Plus is now in the System ROM, instead of being supplied in the
System application on the hard disc.

AUN
---
A new subreason code of Service_InternetStatus has been added;
Service_InternetStatus 1 is issued when the Net module receives a network
map from a gateway station.
