The Tornado shell
-=-=-=-=-=-=-=-=-

Well, this time I can actually write something about the tornado shell - some
it has been written, and much more finalised.

When you start up your RISC-OS computer, and display a directory containing
!Tornado (tornado's resource directory), it loads itself in and installs its
resources. TShell sets itself up as a Wimp task, and claims a section of
application space on MEMC1/1a machines, or a dynamic area on later
architectures. It then starts up the multitasker in the memory space, and
starts up a small task which handles tornado's user interactions.
   From hence, all files double clicked on in the filer are intercepted, and
checked to see if they are wimp apps. If so, they are returned to the wimp,
and if not a new memory domain is created, the image loaded in, and execution
started.
   The code is now preempted, and a handler is installed on WrchV which upon
vdu output creates a 640x512x2 sprite, and redirects vdu output and the
OS_ReadVduVariables into it (thus allowing most games to work). The task can
run nicely in its window, or if the user chooses they can move the task to
full screen use. Note that during full screen use, either full, partial or no
multitasking is retained [1].
   On the other hand, if the image calls Tornado_Initialise before outputting
to the vdu, the handler is removed and tornado searches the home path for the
options, templates, messages and menu files. These are all loaded in by
tornado, and installed in memory.

Writing for tornado
-=-=-=-=-=-=-=-=-=-

Code written for tornado is done using a visual editor, similar to that used
on other platforms. You create an application, and then design the windows to
be used in it. To the various parts of each window you attach code segments,
written using Zap via the external edit protocol.
   Probably the best way to explain this is to write a program, here and
now. Ok then: how about a program which will update a window in real-time
according to the amount of space available on a disc drive?

Firstly, you create a new application (which appears as a icon in the loaded
apps window), and then you create a window in it by dragging the 'create
window' tool onto the window icon. The new window pops up. Inside the window
you create a text icon with "Free:" in it by dragging one of the predefined
text icons into it, and beside it a green raised icon - also from the
predefined icon library. Now, you use the Basic link tool to attach a section
of Basic to that icon, and make the code callable on every refresh. Up pops
an empty function in a Zap window:

DEF FNicon1
LOCAL 

=

Now, you change this to:

DEF FNicon1(disc$)
LOCAL free%
REM By right I should check for other FS's
SYS "ADFS_FreeSpace",disc$ TO free%
=free%/4096

... and change the code entry to
'wi=FNicon1(MID$("%ti",1,INSTR("%ti",":")))'. This, by the way, set the width
of the icon this code is attached to to the returned result of FNicon1.
FNicon1 is passed the result of 'MID$("%ti",1,INSTR("%ti",":"))', where %ti
is replaced with the text in the title bar (which BTW would have code
attached to it setting it to the media this window is referring to)
   From hence, everytime the window is opened this code is called, and the
bar set to the correct value. But this isn't real time, is it?

The trick is to set up a ticker. This is done by specifying a ticker
countdown in cs, and every x cs the code is called. Here's the code:

DEF FNticker1(handle%)
IF !updated% THEN SYS "Tornado_OpenWindow",handle%
=0

This checks !updated, and if it's true reopens the window. BTW, the link code
for this would be: 'FNticker1(%th)', where the handle of the window owning
the icon is substituted in for %th.

But how would !updated% be altered. By setting up a handler, in this case a
window create handler. This code gets called on every window created:

DEF FNhandler1(wkspace%,disc$)
 LOCAL P%,N%,blk%,addr%
 SYS "Tornado_Getblk",%1,0,1024 TO ,,,blk%
 SYS "Tornado_Extblk",,0,+4,wkspace%
 SYS "Tornado_Getaddr",,0,,wkspace% TO ,,addr%
 !addr%=blk%
 FOR N%=0 TO 2 STEP 2
 P%=blk%
 [OPT N%
 .disc EQUS disc$:EQUB0:ALIGN
 .upcallv
 \Checks for alterations to the path at .disc, and sets .updated% if true
 ...
 .updated% EQUD 0
 ]
 NEXT
 =1:REM This specifies we want to keep the wkspace passed to us

Of course, this will only allow one window to work at a time. To get around
that, you would put updated% in the wkspace. The wkspace ptr can be passed
via a substitution to any code linked to icons, handlers or tickers called
from that window.

Of course, future versions of tornado will allow the ticker used above to be
done automatically by tornado - tornado will check updated% for the task. But
for the time being, this is as far as tornado goes.

Languages:
-=-=-=-=-=

Although I used Basic to demonstrate tornado's visual style of writing, both
C and assembler can be used as well. In fact, there is no reason why a
mixture of C, Basic & assembler can't be used in the one program, and leaving
the tornado editor with the problem of linking the lot together. Also
supplied with the editor are libraries of code segments, which allow further
standardisation and ease of program construction.
   However, despite the loss of multithreading with Basic, Basic does contain
one huge advantage over C and assembler - it's interpreted. This allows
tornado to directly call functions in the image using EVAL. With C and
assembler, large tables of function names and their offsets must be created -
a real burden for a programmer. Of course, the editor will automate all that
- but for now, it's a lot easier and simpler for us to write the lot for
Basic - and extend for C and assembler later.
  Anyway, Basic needs a bit of a boost. Acorn have definately been ignoring
it in the last few years.
