home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
misc
/
tornado
/
tndemo2
/
_Kernel
next >
Wrap
Text File
|
1996-06-03
|
33KB
|
762 lines
Notes:
-=-=-=
Fix TTiming to stop slowing down my machine!
Add Tornado_Callback
Add all the Tornado filing system SWIs
- do specs for them
Finish that window renderer!
Add Tornado_CoordGraphics which plots all coord graphics
Add Tornado_Text which plots all text
Add Tornado_Bitmap which plots all bitmaps
Add specs for multithreading multitasking in assembler
- write it!
- think about them for C and Basic [difficult!]
Revise these outdated docs!
Tornado kernel
-=-=-=-=-=-=-=
This is cursory documentation covering the tornado kernel v0.10 (29-12-1995).
The Tornado kernel extends the RISC-OS kernel by providing:
* Management of tornado code
- Its own service call handler
- Its own vector handler
- Function and procedure calls to interface with RISC-OS
- Tornado_Register
- Tornado_Function
* Extended memory and heap management facilites
- Tornado_Initheap
- Tornado_Getblk
- Tornado_Freeblk
- Tornado_Extblk
- Tornado_HeapInfo
- Tornado_ExtHeap
- Tornado_Getaddr
- Tornado_GarbageHeap
* Extended sprite (bitmap) facilities
- Tornado_SpriteOp (#001)
* Miscellaneous extensions
- Tornado_Hourglass (#002)
... and general control of TShell and TLib running under the kernel.
The tornado kernel is loaded in as a RISC-OS module, and during initiation
claims workspace:
+00: reserved
+04: Tornado version * 100
+08: RISC-OS kernel version * 100
+12: handle of list of clients
+16: handle of function vector list
+32: wkspace for Tornado_Register
+36: wkspace for Tornado_Register
+128: 128 bytes of general wkspace
+256: start of tornado shared system heap
The only facilities at present contained within the kernel are the heap
management SWIs. All other facilties are vectored out of the kernel into
subsiduary modules which link themselves into tornado during initiation.
*Note* that tornado extension modules do NOT usually participate in RISC-OS
operations unless it is through the tornado kernel. In other words, they do
not provide their own SWIs, participate with RISC-OS service calls etc -
however, they can, will and do use RISC-OS facilities as vectoring these
through the tornado kernel (which would only pass them onto RISC-OS anyway)
is resource-wasteful.
You will notice tornado has undergone quite a change since you previously
heard from me last summer (1995). It has been hacked down into a much more
modular form, made much more streamlined and flexible. I am not a great
believer in monolithic operating systems, and tornado I felt was becoming a
little monolithic in nature. Thus, I broke the hourglass handling routines
etc into seperate modules which now register their presence with tornado when
they load in.
These docs aren't hugely detailed. Below is simply a list of SWIs, data
structures and various other bits and pieces currently defined.
Niall Douglas.
5th January 1996.
The current format of tornado extended heaps:
+00:&70616548 = "Heap", like with OS_Heap |
+04:Offset to free list | Note this is the standard
+08:Offset to heap base | OS_Heap header
+12:Offset to heap end |
+16:&20 = the Heap+ identifier - also to OS_Heap indicates a block length
+20:offset within heap to the list of non-relocatable blocks
+0: length of list in bytes (beginning=0)
+4: offset within heap to an allocated block descriptor
+24:offset within heap to the list of relocatable blocks
+0: length of list in bytes (beginning=0)
+4: offset within heap to an allocated block descriptor
This is negative if block is locked
+28:flags
bit 0: this heap is auto-extending using Wimp_SlotSize
bit 1: this heap is auto-extending using OS_Module
bit 2: this heap is auto-extending using Tornado_Extblk
bit 30:this heap is auto-extending as the Tornado system heap
bit 31:disable garbage collection if bit 30 set (ie; is negative)
+32: base of heap+ heap containing this heap+ heap if bit 2 of +28 is set
MUST be physical address OR special address eg; 0,1,-1,-2,-3 etc
+36: block within above heap that holds this heap
+40: Reserved for future use
Also, the format of each allocated blk:
___
/ -36: Filetype of file
| -32: First block of file
| -28: Total length of file contained in these blocks (higher word)
| -24: Total length of file contained in these blocks (lower word)
| -20: reloc ptr of linked block before this one (=0 if first)
| -16: reloc ptr of linked block after this one (=0 if last)
| -12: normally nothing before this, but when the block is one of a
| linked list (denoted by bit 29 in the flags) then this word is the
| fragment length of the block (max len this block can be before it
\___ spawns another block)
/|\
|
** Note this may be replaced with a far simple approach later **
-08: Flags
bit 30: clear=nonreloc, set=reloc
bit 29: set means this block is one of a linked list
-04: length of data (not including this header). Negative if the data is
on disc and not in memory.
+00: start of data if data is in memory, or end of block if data is on
disc. Blocks are stored in the format (for example)
"<Tornado$MemoryCache>.F.F.F.F.F.F.F.F" for block -1.
Tornado_Register (SWI &C0000)
On entry:
R0=flags
bits 0,1:
=0: register
=1: deregister
=2: enumerate extensions
=3: return info on a particular extension module
For R0 AND %11=0,1:
R1=addr of RISC-OS module title with instantiation descriptor
R2=addr of data block
For R0 AND %11=2:
R4=0 to start enumeration
For R0 AND %11=3:
R1=addr of RISC-OS module title with instantiation descriptor
On exit:
For R0 AND %11=0,1:
All registers preserved
For R0 AND %11=2:
R1=RO module title
R2=addr of data block
R3=memory word
R4=new enumeration value, or -1 for end of list
Z will be set if no entry was returned
For R0 AND %11=3:
R2=addr of data block
R3=contents of memory word
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: None
Use:
Used to register an extension module with the tornado kernel. The data
block is of the following format:
+00: format of this list (currently =0)
+04: offset to tornado module name (48 char limit)
eg; "Tornado hourglass'"
+08: offset to version of module (8 char limit), date started, date last
updated (last two binary encoded)
eg; "1.00ß",xxx,xxx
+12: offset to credits list (OS_PrettyPrint used) (80 char limit)
and registered number of developer (=0 if not registered)
eg; "© 1996 N. Douglas",xxx
+16: version of tornado this module expects * 100
+20: version of RISC-OS this module written on * 100
+24: version of tornado above which this module probably won't work
correctly on (=0 if all versions okay)
+28: version of RISC-OS above which this module probably won't work
correctly on (=0 if all versions okay)
+32: flags:
bit 0: almost certainly will not work on tornado versions below that
specified
bit 1: almost certainly will not work on RISC-OS versions below that
specified
bit 2: almost certainly will not work on tornado versions above that
specified
bit 3: almost certainly will not work on RISC-OS versions above that
specified
+36: offset to initialisation code
+40: offset to finalisation code
+44: offset to service call code
Binary encoded times are two words of the following format:
%VVVVRRRREEEEEEEESDDDDDDDDDDDDDDD (1st word)
%DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD (2nd word)
The D bits are the number of milliseconds since 12:00am January 1st year
0.
The S bit is the sign of the D bits - before or after 12:00am January 1st
year 0.
The E bits are an eight bit exponent number. The milliseconds from the D
bits are multiplied by 10 to the power of the exponent number.
The R bits are reserved for version number 0, undefined for other
versions.
The V bits are for version number of the format - current all zero
This format gives a theoretical range of + or - 2^47*10^255 which is
around four and a half x 10^258 years, which is enough to get back to the
start of the universe, and possibly the end of it, which was my intention.
The initialise and finalise entries should be seperate from your module's
initialise and finalise entries in that tornado may call your module through
finalise then initialise to restart your module should it get into
difficulties. Your module's RISC-OS initialise and finalise entries should
merely register and deregister itself using this SWI.
Note that the initialise entry is supplied with only R13, the supervisor
stack, and R14 which is the link back into tornado. Your routine may corrupt
all registers except R13 and the current processor mode (SVC), and should
return with a MOVS PC,R14 type construction, making sure to copy across the
PSR.
Note also however that the contents of R12 on exit from your initialise
routine have a special meaning - they are stored and retained by tornado for
future passing to all your routines.
Obviously, standard RO error handling practices are in force here - and as
with almost all tornado entries into your code, you can return an error by
setting V and R0 as appropriate. However, all tornado does (currently) with
this is to return the very same error back out of Tornado_Register, so make
sure your RO initialise entry has error handling implemented for that.
Data struct of client list at +12:
+00: addr of RO name of module
+04: version of tornado it expects
+08: version of RISC-OS it was written for
+12: addr of the data block it passed us first day
+16: addr of its init code
+20: addr of its final code
+24: addr of its service code
+28: value to pass in R12
Note that R12 on exit from the initialise entry will become R12 for the
service or function entries.
Tornado_Function (SWI &C0001)
On entry:
R0=flags
bit 0: clear to register, set to deregister (N/I yet)
R1=addr of RO module name
R2=addr of data blk
R3=ptr to list of call numbers and code entries
R4=R12 to call with
On exit:
All registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to declare an extension module's intent to provide a service or SWI
call. You may also replace existing calls using this call.
Simply pass a list made up of the following blocks, terminated with a
null word:
+00:flags
bit 0: always set
bit 1: clear is register, set is deregister
bit 2: set means we want to intercept the existing provider
bit 15: set means we are a bugfix
+04:Call number this entry refers to
+08:Offset of code entry from module base
If you are providing this call (bit 1 clear), then your code entry will be
entered with all the registers that you would expect. If you are
intercepting, then your code entry will be entered with all the registers
intact but R14 will return to the original provider, and the link to return
to tornado will be on the stack. This allows you to pre and post process the
original providers code.
Note that you cannot count on your code entry to be accepted. You will
never be told whether your code is used to provide the call or not, and you
should *never* assume that it is (ie; have other function code rely on data
shared with other function code). Tornado also may use your code to provide
some calls but not others ie; some of your entries may be used, others may
not.
Bit 15 allows you declare yourself to be a bugfix. This means that your
code will be more likely to be installed.
List struct:
+00: RO module name
+04: data blk
+08: flags
+12: call number
+16: address of code
+20: R12 to call with
+24 to +28: reserved
Tornado_Initheap (SWI &)
On entry:
R0=flags
bit 0: This heap is a Wimp postslot heap
bit 1: This heap is a heap within an OS_Module block in RMA
bit 2: This heap is a heap within a Heap+ block
bit 30: This heap being initialised is the proposed Tornado system heap
R1=ptr to proposed heap base
R2=ptr to addr of heap base if bit 2 set
R3=length of proposed heap (must be >1024 bytes)
R4=handle of block within heap pointed to by R1 if bit 2 set
On exit:
R0=corrupted
R1=ptr to heap base
All registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to initialise a Tornado Heap+ type heap. This heap format is based on
OS_Heap style heaps, and offers complete internal format compatibility with
OS_Heap style heaps, and thus relies on the current structure of OS_Heap
heaps. It will complain if OS_Heap uses a format it does not know about.
The area of memory you intend to initialise will be verified, and header
and other information written into it. Note minimum size is 1024 bytes, and
the base must begin on a word-aligned address. The length must be a multiple
of 4 bytes.
Note that if bit 0 is set then the task's wimpslot is automatically
extended by an appropriate amount and the heap set up at the previous
environment end address which should be passed in R1 on entry. From now on,
any extensions to the heap needed will be done automatically, extending the
wimpslot as necessary. Bit 1 will extend it using OS_Module; bit 2 will
extend it using Tornado_Extblk, which may cause a cascade extension down
through blocks in heaps below the heap being extended.
Note also that the heap+ structure itself is relocatable - this means all
heap+ heaps can also be stored in a Heap+ or otherwise relocatable block.
Tornado_Getblk (SWI &)
On entry:
R0=flags
bit 0: this block is relocatable
bit 1: Don't return address of block in R2
bit 2: don't do a garbage collection after this call
bit 29:(internal) this is the subtask heap
bit 30:(internal) this is the system heap
R1=heap+ ptr, 0 if system heap, 1 if subtask heap
-1,-2 refers to task heaps (NOT IMPLEMENTED YET!)
R3=size of block wanted
Other registers not used as yet
On exit:
R0=corrupted
R1=updated heap+ ptr if R1<>magic heap no on entry
R2=addr of block, otherwise preserved if bit 1 is set
R3=handle of block
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to claim a block from a Heap+ heap. As in other tornado heap calls,
R1 may either point to an actual heap, or may be a 'magic' heap number. These
are currently defined as:
0: Tornado shared system heap (stored in RMA)
1: Tornado subtask shared heap (undefined location currently)
-1: Private heap of first tornado task
-2: Private heap of second tornado task
-3: etc
If you ask for a relocatable block (by setting bit 0), which is _strongly_
recommended, then you will be given a handle which from hence you can use to
reference the block by. It will always be a negative number, and any data
contained within the block must be able to be relocated at arbitrary times.
You will not know if/when/how/why the block has been moved. To get the
_current_ address of the block, use Tornado_Getaddr. Read its entry for
further details of use. You are guaranteed that your block will NOT move
between calls concerning your heap to tornado, except for shared heaps which
may be accessed by another party without your knowledge. Thus, you should
take measures to prevent your block moving while you use it.
If you ask for a non-relocatable block, the handle will be equal to the
start of the block. However, it is good programming practice to also call
Tornado_Getaddr for this handle, just to be sure you are getting the address
of the block (also makes sure if you change it later you won't have to change
too much of your code).
Unless you specifically ask otherwise, an automatic garbage collection
will be performed after this call, unless it has been disabled (only for
system heap). Also, for your convenience the current position of the block is
returned in R2.
Note that if you have specified auto-extending in Tornado_Initheap call,
then this call will only return an error if the entire heap couldn't be
extended, otherwise it's because the heap is full.
Note also that recursion is possible here: this heap being extended by
this call may cause the heap it's in to extend which may cause the heap it's
in to also extend. Failure of any one of these will return an error from this
command. Also, this command thus may take a while having to garbage and
extend multiple heaps.
Tornado_Freeblk (SWI &)
On entry:
R0=flags
bit 2: don't do a garbage collection after this call
bit 29:(internal) this is the subtask heap
bit 30:(internal) this is the system heap
R1=heap+ ptr, or 'magic' heap no
R3=handle of block
On exit:
R0=corrupted
R1=updated heap+ ptr if R1<>'magic' heap no
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to free a claimed block.
Unless you specifically ask otherwise, an automatic garbage collection
will be performed after this call, and if auto-extending is set, then the
heap will be automatically shrunk if possible. This, as above, may lead to
all heaps in the tree above to shrink as well. Thus, this command may take a
while having to garbage and shrink multiple heaps.
Tornado_Extblk (SWI &)
On entry:
R0=flags
bit 0: don't bother returning new size
bit 1: don't bother returning current address
bit 2: don't do a garbage collection after this call
bit 29:(internal) this is the subtask heap
bit 30:(internal) this is the system heap
R1=heap+ ptr, or 'magic' heap no
R2=signed change in bytes
R3=handle of block
On exit:
R0=corrupted
R1=updated heap+ ptr if R1<>'magic' heap no
R2=current addr of block
R3=new handle of block
R4=new size of block
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to change the size of a claimed block. Note that the new size of the
block may be larger than you intended, as it is always rounded up to the
nearest word. This is alright: just take care to redo any future resizing
decisions (ie; if storing the size, don't store previous size changed by the
requested size change, store the size returned by R2 instead). This will
prevent bytes 'appearing' on the end of the block that you will never use.
The new handle for the block will be the same if the block was
relocatable, but note it is good programming practice if you restore the
handle anyway, in case you may later have to alter the relocatable nature of
the data.
Unless you specifically ask otherwise, an automatic garbage collection
will be performed after this call, and the repercussions are as for
Tornado_Getblk and Tornado_Freeblk.
Tornado_ExtHeap (SWI &)
On entry:
R0=flags
bit 29:(internal) this is the subtask heap
bit 30:(internal) this is the system heap
R1=heap+ ptr, 0 if system heap, 1 if subtask heap
R2=signed change in size
On exit:
R2=new size
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to manually change the size of a Heap+ heap. Usually automated. Note
this may cause auto-extending heaps above this to garbage and also change
size.
Related calls:
All tornado heap calls;
Tornado_Getaddr (SWI &)
On entry:
R0=flags
bit 0: don't cache block
bit 1: preserve R4 on exit (ie; don't bother calculating it)
bit 29:(internal) this is the subtask heap
bit 30:(internal) this is the system heap
R1=heap+ ptr, 0 if system heap, 1 if subtask heap
R2=offset within block you wish to access (if block fragmented)
R3=handle of block
R4=number of bytes to be made contiguous (-1=full length)
On exit:
R2=actual address of block (points to offset given by R2)
R3=reloc handle of block if bit 0 was set on entry; otherwise preserved
R4=number of bytes from R2 you can access before you must call this SWI
again (may be to end of block though)
All other registers preserved
Interrupts: IRQ's enabled
Processor mode: SVC
Re-entrancy: Full
Use:
Used to determine the actual address of a claimed block. If the handle passed
is non-negative, then the same handle is currently returned in R2.
The offset contained within R2 is the patch of data within the block you
wish to access. This should be given even if the block isn't fragmented, as
the user may have specified that a cap be placed on requests.
You can work out what memory can be accessed using R3 ie; you won't need
to call this SWI to access as far as this. You can still do anyway, and this
call is quite quick so little difference in speed will be noticed.
Note you can only access R4 bytes from where you asked for. This is
because only that much data has been loaded within that block.
Setting bit 0 on entry means that a new reloc block is created of R4
bytes, and one or more fragmented blocks are loaded into it to make it a
contiguous area of data. Make sure that when you're finished with this block
and the data (ie; before calling Tornado_Getaddr again), free the block. Note
finally that setting bit 0 is quite slow in operation, and having blocks
already in memory doesn't matter - they remain in memory - and thus, quite a
lot of memory can be wasted. Use a routine capable of using fixed size data
blocks to manipulate the data if possible.
This call also resets the time elapsed since last access to this block, or
fragment of a block. This is used for virtual memory, where when the system
heap becomes full the oldest blocks get dumped to disc. Using this call
indicates that you want to use this block. If the block is currently on disc,
it is reloaded into the heap and its address returned to you. Note no garbage
collection occurs when this happens.
You can be guaranteed that this address will remain the same until the
next specific call to Tornado_<call>, as all the calls done under
interrupts/vectors etc. by Tornado do not garbage collect the heap.
PLEASE NOTE: When preempting code and referring to the system heap, you
MUST use Tornado_GarbageHeap to force disabling of garbaging. If you do this,
you must be prepared to regularly do a Tornado_GarbageHeap followed with
another Tornado_Getaddr to ensure fragmentation does not become endemic. This
is because other Tornado apps may cause the heap to be garbaged.
Related calls:
All tornado heap calls;
Tornado_Misc (SWI &C0008)
On entry:
R0=no of miscop you want
On exit:
Dependent on call
Use:
Used to call any one of the following calls:
&0002: HeapInfo. Takes the heap address in R1, and returns:
R0=size of heap
R1=heap addr, filled in if R1=0,1 on entry
R2=largest free block in heap
R3=amount of free space available
R4=number of relocatable blocks in heap
R5=number of non-relocatable blocks in heap
R6=bytes occupied by relocatable blocks
R7=bytes occupied by non-relocatable blocks
All other registers preserved
&0003: Integer divide routine, R1=value, R2=divisor
Returns R1=divided value, R2=remainder
&0004: Garbage heap. Takes the heap in R1, preserves everything on return
&0005: addr of extblk routine (R1)
&0006: addr of integer divide routine (R1)
&0007: R1=addr of getaddr routine which allows you to determine the
address of a memory block much quicker.
&0008: Return info on RO & Tornado versions:
R1=Machine operating system type:
00: RISC-OS on a native ARM-based propriatary archietecture
01: RISC-OS on PCI ARM extension board
02: NCOS ???
08: ARM based multi-platform capable operating system that supports
RISC-OS calls
09: As above, but ARM code is emulated
10: As above, but ARM code is translated on load-in
11: ARM based Unix
16: Multiple platform portable advanced tornado operating system
(ATOS)
R2=OS as specified above version number * 100
R3=Tornado version number * 100
Tornado_CallAfter (SWI &C0100)
On entry:
R0=flags
bit 0: clear to add routine, set to remove one
bit 1: reserved
R1=address to call
R2=time from now in units of 0.1 milliseconds (1 x 10^-4 seconds)
R3=value of R12 to be called with
On exit:
All registers preserved
Use:
This call will call the code pointed to by R1 in R2 x 0.1 milliseconds.
Note that tornado will call your code in SVC mode with interrupts disabled
and r14_svc stacked - therefore, you may call reentrant SWIs with no
preparatory code (other than your r14 preserved to return to tornado). Your
code must preserve all registers and flags apart from V and R0 on exit (see
below), and should not cause interrupts to be enabled unless your code can
deal with/prevent reentry and you do not wish to use the relatch facility
below.
Please realise when writing your code with a low interval time
(R2<100) that it *must* be very efficient, much more so than normal RO
interrupts. Inefficient code called 10,000 times a second can kill a
machine's performance - try it and see if you wish, and then imagine it on a
Arm2 machine. To this end, do not access memory more than you can, do not
access the stack more than you have to, and try and remove as many branch
instructions as possible [1].
A very important fact that *must* be remembered when using this facility
is that serial access on non-hardware-buffered serial chips (ie; the internal
serial chip on every pre-RPC machine) *will* *not* function correctly with
heavy interrupt usage such as that caused by low interval times with this
routine. While this may not sound important, I would also add that all
interrupt-based functions can be affected, including almost all peripheral
access. To this end, take the idea of reenabling interrupts very seriously -
the tornado shell does, despite its very short switching code.
Relatching: Tornado also supports a relatch on exit process in which you
set R0 to the next interval and also set V. If you do not wish to use this,
simply MOVS PC,R14. You must not enable interrupts if you use this facility.
Note also that you *must* *not* relatch if you are using callbacks.
Callbacks by their nature take up to a centisecond to be dealt with normally,
and thus you would overflow the callback handlers with requests for the same
piece of code. To get around this, call Tornado_CallAfter from the the called
back code to relatch the entry.
Finally, a small difference exists between the relatch interval and the
interval passed to this SWI - the latter is unchecked, whereas the former is
and thus bad intervals (ie; those equal to zero or below zero) are screened
out. This is because internally extra code is required to screen the interval
and the relatching code has to be very optimised. Note that a zero relatch
interval will not work (1 is the smallest), and a minus one will cause
extreme problems (memory overflows, no routine being called etc).
As an addendum, due to latency requirements, a guaranteed maximum of four
routines can be on tornado's list. Your routine may be refused.
Note also that due to hardware limitations, it is very possible that this
call may be interfered with by other software using the same facilities in
the Acorn hardware (Sound samplers, video digitisers, multitasking Replay's
etc).
[1]: These optimisations are probably only effective on Arm2-Arm7's as
later ARMs use different architectures and much improved L1 and L2 caches'.
Tornado_ReadMonotonicTime (SWI &C0101)
On entry:
Nothing
On exit:
R0=low word of 1 x 10^-4 second counts since tornado was last activated
R1=high word of the above
Use:
This call reads a count value incremented by tornado 10,000 times a
second.
Note also that due to hardware limitations, it is very possible that this
call may be interfered with by other software using the same facilities in
the Acorn hardware (Sound samplers, video digitisers, multitasking Replay's
etc).
Tornado service calls:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Tornado_Genocide (&0000):
On entry: nothing
This call is made to module extensions just before their finalise entries
are called. Admittedly there isn't much point to it, but it's worth being
here.
Note that this call is duplicated by a call in the RISC-OS service
channels of number &C0000, and that's of even less use.
Tornado_NewModule (&0001):
On entry: R2=data block of module
This call is made when a new extension module is registering itself. It
can be vetoed by setting V on exit and R0 can contain an error message if you
like - if not, set it to zero and a suitable alternative will be generated
instead.
Tornado_ModuleDying (&0002):
On entry: R2=data block of module
This call is made when an existing extension module is trying to
deregister itself. It cannot be vetoed as this would leave partially active
code in memory, never mind the fact that someone might be killing it the
RISC-OS way. However, you can raise an objection if you wish by setting V and
R0 to a suitable message, or none if you wish.
Tornado_ResolutionChange (&0040):
On entry: R0=old style mode number now in force if applicable
R1=new style mode number now in force if applicable
R2=pixels across
R3=pixels high
R4=xeigen
R5=yeigen
R6=bits per pixel
R7=screen refresh rate in Hz (if available)
R8=pixel rate in Hz (if available)
This call is made when the video systems have changed their configuration
in some way. The call is made after the change has occured so it cannot be
vetoed (use the RISC-OS channels if you need to do this).
Note that any unavailable fields will be -1 as appropriate. Some versions
of RISC-OS do not supply the same mode numbers, and some do not supply the
pixel and refresh rates either.
Please try to not use R0 or R1 when writing your module - it will tie your
module to one version of RISC-OS. However, not passing the mode number to
things like ColourTrans is virtually impossible, so test which one of R0,R1
is -1 and pass the other one to it. This will guarantee backwards
compatibility.
Tornado call providers
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Tornado_Register (&00000)
Tornado_Function (&00001)
Tornado_Initheap (&00002)
Tornado_Getblk (&00003)
Tornado_Freeblk (&00004)
Tornado_Extblk (&00005)
Tornado_HeapInfo (&0000X)
Tornado_ExtHeap (&00006)
Tornado_Getaddr (&00007)
Tornado_GarbageHeap (&0000X)
Tornado_Misc (&00008)
Tornado_CallAfter (&00100)
Tornado_ReadMonotonicTime (&00101)
Tornado error numbers
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Tornado_TornadoNotPresent (&C0000)
This error occurs when an extension module was loaded in without the
tornado kernel present or active.
Tornado_BadVersion (&C0001)
This error occurs when you try and set an impossible RISC-OS version
using *Set Tornado$ROver or when someone tries to start up tornado on a bad
version of RISC-OS.
Tornado_HeapNotPossible (&C0002)
This error occurs when you try to initialise a heap that would be illegal
if initialised. The error string will tell you exactly what the problem was.
Tornado_BadGetblk (&C0003)
This error occurs when you try to claim a block that would be illegal -
currently this is only when you specify a negative size.
Tornado_BadHeap (&C0004)
This error occurs when you pass a heap in R1 that is not a tornado Heap+
heap.
Tornado_BadListFormat (&C0005)
This error occurs when tornado tries to deal with a data structure
format that is either damaged, incorrect, out of date or in a format that
the particular routine involved does not know how to deal with.
Tornado_BadExtHeap (&C0006)
This error occurs when you try to change the size of a heap whose size is
automatically changed by tornado without your intervention.
Tornado_BadHandle (&C0007)
This error occurs when the handle you passed to a routine is incorrect
for some reason - the error string specifies the exact problem.
Tornado_CallAfterNotPresent (&C0100)
This error occurs when someone has tried to delink a routine not known to
Tornado_CallAfter.
Tornado_ShellAlreadyActive (&00900)
This error occurs when somone has tried to start the tornado shell when
it is already active.
Tornado_CallAfterNoRoom (&C0101)
This error occurs when there is no room to add a routine to the list.