Commit 3da129d2 authored by Neil Turton's avatar Neil Turton

Import from cleaned 360 CD

parent 53da419a
hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
**/s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
*,ffb gitlab-language=bbcbasic linguist-language=bbcbasic linguist-detectable=true
This diff is collapsed.
> !ReadMe
Instructions on how to make/modify Arthur.
Directory Asm contains the Exec files.
Asm.A500 assembles the A500 kernel and then does *Asm.BuildA500
Asm.BuildA500 glues modules to the kernel to make an image for 27512's.
Asm.BigA500 glues modules to the kernel to make an image for 1Mbit devices.
Asm.Test assembles the Archimedes kernel, for 300 and 400 series machines.
NB. This uses Hdr.Archie, not Hdr.Test !!!
Asm.Test2 glues modules to the kernel to make an image for 1Mbit devices.
Asm.MoveFS takes a new copy of FileSwitch (and headers) from the net.
Asm.TransTim takes a new copy of Tim's stuff from the net.
Directory Hdr has the header files for the various assemblies.
Directory Text has various files, only one of which is important:
Text.Changes should be updated whenever changes are made to Arthur.
Text.Still has my list of things still to do.
Quick guide to the source files:
Kernel is the first, and has the SWI dispatcher, plus the initialized variables
to copy into RAM, plus some Brazil swi handlers.
Middle contains the rest of the Brazil swi stuff, plus supervisor routines.
NewReset is the reset code - if you need to change this, you will need to use
the AddTubeBashers flag, which lives in Kernel. The TubeChar macro should then
Super1 is the supervisor loop, plus more Brazil oddsnsods.
ArthurSWIs is ReadUnsigned, vectors, services, ValidateAddress. Note that
the version of ChangeDynamic in here is NOT the one that's assembled.
Arthur2 is variables, GSTRANs
Arthur3 is command code, including Status/Configure.
Other files are hopefully obvious from their names.
Backing Up.
You need to copy the whole tree from $.Kernel to the backup medium.
You also need to take a copy of all the current header files from $.Hdr.
A copy of all the tools in $.Library and $.Utils would also be handy.
Have fun!
This diff is collapsed.
; > 5thColumn
RISC OS Support for extension ROMs
Author: Tim Dobson
Status: Draft
Issue: 0.03
Date Revision Changes
11-Oct-90 0.00 Started
16-Oct-90 0.01 Completed first draft
08-Feb-91 0.02 Updated to reflect reality
23-Apr-91 0.03 Added note about directly executable
extension ROMS
This document describes the enhancements to RISC OS to support extension (or
"5th column") ROMs.
Extension ROMs are ROMs fitted in addition to the main ROM set, which
provide software modules which are automatically loaded by RISC OS on
The availability, size and number of extension ROM sockets depends on which
type of RISC OS computer you are using.
In general, however, RISC OS recognises extension ROMs or ROM sets which are
8, 16 or 32 bits wide, provided the ROM adheres to the specification below.
32 bit wide extension ROM sets are directly executable in place, saving on
user RAM. 8 or 16 bit wide sets have to be copied into RAM to execute.
Creating an extension ROM
Extension ROMs appear in the ROM area of the memory map, ie between
&03400000 and &03FFFFFF. An extension ROM set must end on a 64K boundary or
at the start of another extension ROM. This is normally not a problem as it
is unlikely you would want to use a ROM smaller than a 27128 (16K), and the
normal way of addressing this would mean that the ROM would be visible in 1
byte out of each word, ie within a 64K addressable area.
Extension ROMs have a header at the end of the ROM image which indicates the
presence of a valid extension ROM. The header is at the end because RISC OS
scans the ROM area downwards from the top.
At the end of each ROM set of size 'n' bytes must be a 16-byte header as
Byte address Contents
n-16 1-word size field containing n
n-12 1-word checksum (bottom 32 bits of the sum of all
words from addresses 0 to n-16 inclusive)
n-8 2-word id "ExtnROM0" indicating a valid extension
ROM, ie
n-8 &45 ; "E"
n-7 &78 ; "x"
n-6 &74 ; "t"
n-5 &6E ; "n"
n-4 &52 ; "R"
n-3 &4F ; "O"
n-2 &4D ; "M"
n-1 &30 ; "0"
Note that the ROM header will not necessarily appear in the memory map in
the last 16 bytes if the ROM set is 8 or 16 bits wide. In the 8-bit case,
the header will appear in one of the four byte positions of the last 16
words, and in the 16-bit case, in one of the two half-word positions of the
last 8 words. However, RISC OS copes with this.
Extension ROMs also have a header at the *start* of the ROM set, which is
identical to the format of an expansion card's identity space. This is
because the Podule manager module handles much of the extension ROM
The format of the header at the start is as follows:-
Byte address Contents Meaning
0 &00 Extended expansion card identity,
not requesting IRQ or FIQ
1 &03 bit 0 set => there is a chunk
bit 1 set => interrupt status
pointers defined (necessary because
bit 0 is set)
bits 2,3 = 0 => 8-bits wide (NB this
should be set to 0 irrespective of
the actual width of the ROM set)
2 &00 Reserved, must be zero
3 &87 Product type (lo-byte)
4 &00 Product type (hi-byte)
See below
5 Manuf(lo) Manufacturer code (lo-byte)
6 Manuf(hi) Manufacturer code (hi-byte)
See below
7 Country Country code - see below
8 to 15 &00 Interrupt status pointers (extension
ROMs do not generate interrupts!)
16 onwards Chunk directory - see below
Product type code: Note that &0087 has been allocated as a product type code
for all extension ROMs.
Manufacturer code: All manufacturers of expansion cards and/or extension
ROMs should have a code for manufacturer. If you have not already been
allocated one, you should consult Acorn.
Country code: Every extension ROM should have a code for the country of
origin. These match those used by the International module, except that the
UK has a country code of 0 for expansion cards and extension ROMs. If you do
not already know the correct country code for your country, you should
consult Acorn.
The chunk directory in an extension ROM is identical to that in an expansion
card - see the chapter "Expansion Cards: Technical Details" in the RISC OS
Programmer's Reference Manual.
In extension ROMs which are directly executable (ie which are 32 bits wide),
the word immediately preceding the start of each module must contain (size
of module +4), ie an offset from itself to the first word after the module.
It is recommended that all extension ROMs be created like this, irrespective
of whether they are directly executable.
Additional interfaces to support extension ROMs
Changes to Podule manager
The Podule manager module is responsible for recognising extension ROMs,
although it is the kernel which is responsible for loading modules contained
in them.
The numbering scheme for expansion card slots has been extended to include
extension ROMs. The numbers for extension ROMs are -2, -3, -4... (-1 is
reserved for the main ROM, although the Podule manager itself does not
accept -1 for any of its SWI calls).
All Podule manager SWIs which take an expansion card slot number as a
parameter allow an extension ROM specifier instead.
The SWIs Podule_ReadID, Podule_ReadHeader, Podule_EnumerateChunks,
Podule_ReadChunk operate as one would expect when presented with an
extension ROM specifier.
The SWIs Podule_ReadBytes, Podule_WriteBytes, Podule_CallLoader will
normally fail because extension ROMs have no code space or loader.
SWI Podule_RawRead will read successive bytes out of the extension ROM,
taking the ROM width into account.
SWI Podule_RawWrite must not be used with an extension ROM specifier, as
writing to the ROM area can reprogram the memory and video controllers.
SWI Podule_HardwareAddress returns the base address of the specified
extension ROM, although this is not in general useful as the ROM width can
New SWIs
SWI Podule_EnumerateChunksWithInfo
in: R0 = chunk number (zero to start)
R3 = expansion card slot number or extension ROM number
out: R0 = next chunk number (zero if final chunk enumerated)
R1 = size (in bytes) if R0<>0 on exit
R2 = operating system identity byte if R0<>0 on exit
R4 = pointer to a copy of the module name if the chunk is a relocatable module, else preserved
R5 = pointer to a copy of the module's help string if the chunk is a relocatable module, else preserved
R6 = address of module if the chunk is a directly executable relocatable module
or 0 if the chunk is a non-directly-executable relocatable module
else preserved
SWI Podule_HardwareAddresses
in: R3 = expansion card slot number or extension ROM number
out: R0 = raw hardware address
R1 = combined hardware address
For an expansion card, the "raw hardware address" is the base address of the
expansion card, and the "combined hardware address" is the raw hardware
address (in bits 12-25) combined with the base address of the expansion
card's private CMOS RAM (in bits 0-11) (as returned by SWI
For an extension ROM, the two addresses are the same, and are the start
address of the extension ROM (ie the address of the first byte of the ROM).
Star commands
*Podules now displays the extension ROMs in the system as well as expansion cards.
Changes to kernel
SWI OS_Module
OS_Module 17 (Add expansion card module) - This call now allows R3 to be
either an expansion card slot number or an extension ROM number.
OS_Module 19 (Enumerate ROM modules) - This call now enumerates
over all ROM sections, ie extension ROM modules as well as main ROM and
expansion card modules. R2 on entry now specifies the ROM section number to
start scanning from, with the order of enumeration as follows:-
-1 (main ROM), 0, 1, 2, 3 (expansion cards), -2, -3, -4,... (extension ROMs)
Edition 1 of the PRM is incorrect when it states that on exit R1 (the
module number to scan from) is incremented and R2 (the expansion card number
to scan from) is preserved.
In fact R1 returns the module number of the found module plus one, where
modules are numbered from zero within each ROM section, and R2 returns the
ROM section number of the found module, which may be in a different ROM
section from the value passed in R2 on entry, if there are insufficient
modules in the specified section.
The values returned in R1 and R2 are therefore set up for the next call to
OS_Module 19.
The call returns the error "No more modules" (error number &107) if there
are no more modules from the point specified in the ordering.
New call
OS_Module 20 (Enumerate ROM modules with version)
This call is identical to OS_Module 19, except that on exit R6 holds a BCD
(binary coded decimal) form of the module's version number, as derived from
the module's help string. The top 16 bits of this value hold the integer
part of the version number, and the bottom 16 bits hold the fractional part,
eg if the version number of the module is "3.14" then the value returned
would be &00031400.
Module initialisation
The way in which the kernel initialises modules has been changed. If there
is more than one version of the same module present in the ROM (which
includes all ROM sections) then only the newest version of the module is
initialised, where newest means the version with the highest version number.
(If there are two copies of the same version, then directly executable
versions (ie in main ROM or in a 32-bit wide extension ROM) are considered
"newer". If they are equal in this respect, then the later one in scanning
order is considered to be newer.)
The kernel first scans down the list of modules in the main ROM. For each
module in this list, the kernel initialises the newest version of that
For each module in the main ROM, the newest version of that module
If an extension ROM contains a newer version of a module in the
main ROM, then the newer version will be initialised at the point in the
initialisation sequence where the main ROM version would have been
initialised. This allows main ROM modules to be replaced without the
problems associated with initialisation order.
The kernel then applies the same rule to all of the expansion cards in turn.
In each case the newest version of the module is initialised, but with the
hardware address (in R11) corresponding to that of the expansion card.
The kernel finally initialises any extension ROM modules that are the newest
versions, but which have not already been initialised in lieu of a module in the
main ROM or on an expansion card.
Star commands
*ROMModules now displays the version number of each module, as well as the
other information. Extension ROM modules are now included in the list. Note
that extension ROMs are numbered 1, 2, 3... in this command - these
correspond to ROM section numbers -2, -3, -4... respectively.
*Unplug can now unplug extension ROM modules, as well as modules in the main
ROM or in expansion cards. The syntax is now
*Unplug [<moduletitle> [<ROM section number>]]
*Unplug with no parameters does the same as it used to, ie display any
unplugged modules.
*Unplug with a module name but no ROM section number specified unplugs all
versions of that module in the system, and kills off any active module of
that name.
If a ROM section number is specified then only versions of that module
in that ROM section are unplugged.
The action of *RMReInit has changed slightly. If the specified module is
active, then the effect is as before, ie the module is killed and then
If the specified module is not active, but is in the ROM, then the unplug
bit in CMOS RAM is cleared for all versions of the specified module, and
then the newest version of the module is initialised.
New star command
*RMInsert <moduletitle> [<ROM section number>]
If no ROM section number is specified, then this command clears the unplug
bit for all versions of the specified module, without reinitialising any of
If a ROM section number is specified, then this command clears the unplug
bit for all versions of the specified module present in the given section,
without reinitialising any of them.
; A540Extend
Title: A540Extend
Author: Tim Dobson
Version: 1.01
Started: 01-Nov-90
Last updated: 25-Nov-91
Status: Release
01-Nov-90 TMD Created
25-Nov-91 TMD Updated for RISC OS 3.03
Additions to the mode extension system for A540 and similar machines
This document describes extensions to the RISC OS mode extension system for
machines which have programmable VIDC clock speeds and sync polarities, such
as the A540. Familiarity with the RISC OS 2.00 mode extension system is
assumed (this is described in the existing Programmer's Reference Manual).
The A540 has extra hardware to allow the selection of different VIDC clocks
and to determine the polarity of the sync lines. VIDC uses its clock
together with a set of internal dividers to provide a range of pixel rates.
The format of the "VIDC list" returned from Service_ModeExtension (&50) has
been extended to allow the pixel rate and sync polarities to be specified.
On original Archimedes machines, the VIDC clock is fixed at 24MHz, and the
pixel rate is only determined by VIDC's internal dividers, as specified in
bits 0 and 1 of the Control Register (VIDC address &E0). This would be
stored in the VIDC list as a word of the form &E00000xx.
RISC OS now supports two different format VIDC lists.
The original (type 0) VIDC list format is as follows:-
Offset Value
0 0
4 VIDC base mode
8 VIDC parameter
12 VIDC parameter
.. ..
n -1
The new (type 1) VIDC list format is as follows:-
Offset Value
0 1
4 VIDC base mode
8 VIDC parameter
12 VIDC parameter
.. ..
n -1
n+4 Extended parameter
n+8 Extended parameter
.. ..
m -1
where extended parameters are of the form
(0 << 24) + (pixel rate in kHz)
(1 << 24) + (sync polarity)
(2 << 24) + (true VIDC clock rate in kHz)
** This option available only from RISC OS 3.03 onwards **
The sync polarity is defined as follows:-
bit 0 = 0 => HSync +ve (as on a standard Archimedes)
= 1 => HSync -ve
bit 1 = 0 => VSync +ve (as on a standard Archimedes)
= 1 => Vsync -ve
bits 2..23 must be zero
A pixel rate specifier in a type 1 VIDC list will override the settings of
bits 0 and 1 of a Control Register specifier in the main body of the list.
If no pixel rate is specified, then the VIDC clock is set to 24MHz, and the
settings of the divider in the Control Register are used as normal.
The A540 hardware provides the following pixel rates:-
24000 kHz, 25175 kHz, 36000 kHz with a multiplier of 2/2
16000 kHz, 16783 kHz, 24000 kHz with a multiplier of 2/3
12000 kHz, 12587 kHz, 18000 kHz with a multiplier of 1/2
8000 kHz, 8392 kHz, 12000 kHz with a multiplier of 1/3
If the pixel rate specified is not achievable with the hardware on the
machine, the nearest available pixel rate is used.
Note: when specifying a pixel rate for a hi-res-mono display, the pixel rate
specified should be the actual pixel rate divided by 4, ie 24000 not 96000.
If no sync polarity is specified, a default of 0 is used (ie the same as a
normal Archimedes).
The true VIDC clock rate specifier (only on RISC OS 3.03 or later) is
intended to be used in systems where the clock rate fed to VIDC is under the
control of some external device, rather than being selected by the clock
select latch. (For example, on the portable machine, the LCD ASIC feeds
either 8MHz or 16MHz into VIDC when LCD modes are selected).
The values programmed into the clock select latch and the VIDC divider are
still determined either from the control register specifier or a pixel rate
specifier assuming the same range of clock speeds as on the A540, but the
VIDC clock rate specifier is used to determine the video memory rate,
which in turn determines the VIDC FIFO Request Pointer values (bits 4 and 5
of the VIDC control register). The VIDC clock rate specifier is also stored
in VDU variable VIDCClockSpeed (&AC), which is used by the SoundDMA module
to determine the VIDC Sound Frequency Register value.
> net#arf:$.a500.RiscOS+.doc.Kernel
Description: Documentation of changes to kernel for PRM
Author: Tim Dobson
Status: Preliminary
06-Oct-89 TMD Created
13-Oct-89 TMD Added documentation of OS_RemoveCallBack
27-Oct-89 TMD Added documentation of VDU variable VIDCClockSpeed
01-Dec-89 NRaine Added documentation of OS_FindMemMapEntries
04-Dec-89 TMD Documentation of OS_FindMemMapEntries updated slightly
The description of bug fixes below is in a very rough state at the moment -
it will need to be tidied up before publication. Not all of the information
below is relevant to the average user.
Documentation updates since RISC OS 2.00 release
Changes applying to RISC OS 2.01
A new SWI, OS_ChangeRedirection, has been added, to allow the reading and
writing of the handles associated with OS_CLI input/output redirection. This
call was provided for future versions of the task window module, so that
these handles can be made local to the task running in a task window.
SWI OS_ChangeRedirection
Read or write OS_CLI input/output redirection handles
in: R0 = new input handle (0 => not redirected, -1 => leave alone)
R1 = new output handle (0 => not redirected, -1 => leave alone)
out: R0 = old input handle (0 => not redirected)
R1 = old output handle (0 => not redirected)
In RISC OS 2.00, the SWI OS_AddCallBack allowed interrupt routines to
request a callback, which was granted later when RISC OS was about to
exit to a user mode routine with IRQs enabled. However there was no way to
cancel a callback request before it was granted. This could cause problems,
for example if a module is being killed, and it has outstanding callback
requests, it must refuse to die, otherwise the callback may be granted after
that memory has been reused for something else. For this reason a new SWI,
OS_RemoveCallBack, has been added.
SWI OS_RemoveCallBack
Remove a transient callback from the list
in: R0 = address that was to be called
R1 = value of R12 that the routine was to be called with
out: R0 = preserved
R1 = preserved
A new VDU variable, VIDCClockSpeed (variable number 172), has been added.
The value of this variable is the current VIDC clock rate, in kHz. This
value changes when a screen mode is selected which requires a different
clock rate. The value is read in the same way as other VDU variables, by
issuing the SWI OS_ReadVduVariables.
Typical values are 24000 (ie 24MHz) for TV standard modes, 25175 (ie
25.175MHz) for VGA modes, and 36000 (ie 36MHz) for super-VGA modes.
A number of routines were changed to improve IRQ latency:-
a) New version of ChangeDynamicArea which reenables interrupts.
b) Heap manager extend block has improved IRQ latency.
c) Made OS_Byte &87 restore caller's IRQ state during call.
d) Made OS_Word &0E,0 enable IRQs during call.
e) Made OS_Word &15,0 enable IRQs during call.
The heap manager has been optimised in a few places.
The routine that converts a date and time value (in hours, minutes, seconds
etc) into a 5-byte centisecond value has been made smaller and much faster.
Bug fixes
Fixed bug in extend heap call (stack imbalance when returning 'No RAM for
extending heap' error)
Fixed "*%" (LDREQB not LDREQ).
Fixed OS_ReadArgs with a /E argument that evaluates to a string (always used
to give 'Buffer full' - also fixed 2 other bugs lurking in the background,
viz. did STRB of buffer addr assuming it was non-zero to indicate a string,
and didn't allow for length and type bytes in amount free value.
Fixed OS_Word &15 reason code 4 (Read unbuffered mouse position) - it used
to generate undefined instruction trap due to stack mismatch.
Fixed OS_SWINumberToString with negative numbers.
Fixed ROMModules never saying 'Running'.
Made OS_SpriteOp reentrant by pushing register dump area on stack.
Fixed sideways scroll by one 'byte' in MODEs 3 and 6.
Fixed incarnation names being terminated by 1st character.
Fixed *Unplug using address as extra terminator for module name.
Fixed podule IRQ despatcher corrupting R0 (prevented it from correctly
disabling the podule IRQ (or podule FIQ-as-IRQ) interrupt if no handler)
RR-2047: Fixed bug in GSRead with quoted termination.