> net#arf:$.a500.RiscOS+.doc.ResourceFS

Author: Neil Raine
Status: Draft proposal, not agreed yet
History:
         6-Feb-90  0.01  First draft.
        20-Feb-90  0.02  Aasm164 included
        22-Feb-90  0.03  Name changed from DeskFS to ResourceFS


Issues (ignore on first reading)
------

There is work still to be done on getting C modules to include files.


Overview
--------

This document describes the interface to the ResourceFS module, which
provides the hooks necessary for modules to include files in the Resources:
filing system.

This facility is useful because it allows the resource files associated with
a particular module to be included in the same file as the binary image,
which helps with release control.

It also has an important application for podule modules, since it allows
them to *IconSprites a sprite file which they put into Resources:.  This is
important as there is no other way to introduce a sprite into the Wimp's
free pool other than from a file.

Another application is for certain resource files to be replaced on a
selective basis, which is an additional technique to the path mechanism
already in use (eg. Wimp$Path can be set up to reference a resource
directory).


Directory structure
-------------------

In order to avoid possible name clashes, it is important that a well-defined
directory structure is adhered to by all concerned.  This is:

        $.Apps.!<appname>               ; the ROM-resident applications
        $.Fonts                         ; the ROM-resident fonts
        $.Resources.<modulename>        ; resources for ADFSFiler etc.
        $.Resources.<appname>           ; resources for PrinterDM etc.
        $.ThirdParty.<appname>          ; resources for 3rd parties

where <appname> is the name of the application concerned, without the "!" on
the front (eg. Draw, Paint, Edit).

The above all indicate directories, which normally contain files called
"!Sprites", "Templates", "Messages" and so on.

Where third party software is involved, the actual <appname> used must be
registered with Acorn, to avoid clashes.


Software interface
------------------

In order to register a group of files with ResourceFS, a module must have
the files included in their image, with appopriate header information, and
then call SWIs to register and de-register this area as appropriate.

SWI ResourceFS_RegisterFiles
        In:  R0 -> area of memory containing files (see below for format)

        This SWI should be called when the module is initialised. 
        ResourceFS will link the file(s) into its structure, and then issue
        a Service_ResourceFSStarted (not to be confused with
        Service_ResourceFSStarting - see below), which tells any programs
        relying on ResourceFS files that the structure has changed.  The
        Wimp responds to this service call by looking for its default sprite
        pool again.

SWI ResourceFS_DeregisterFiles
        In:  R0 -> area of memory containing files

        This SWI should be called when the area of memory containing the
        files is about to be deallocated (eg. when the module containing
        them is killed).

        Note that it is not necessary to call this SWI on receipt of a
        Service_ResourceFSDying, since the ResourceFS module 'loses' all
        references to ResourceFS files when it dies anyway.

Service_ResourceFSStarting (&60)
        In:  R2 -> code address to call
             R3 = workspace pointer for ResourceFS module
        Out: all registers preserved (do not claim the service)

        When the ResourceFS module is reloaded or re-initialised, it issues
        this service call so that modules that provide ResourceFS files can
        put them back into the structure.

        Unfortunately the ResourceFS module is not linked into the module
        chain at this point, so it is not possible to call
        ResourceFS_RegisterFiles.  Instead, the application should execute
        the following code:

                STMFD   SP!, {R0, LR}
                ADR     R0, ResourceFSfiles ; R0 -> ResourceFS file structure
                MOV     LR, PC          ; LR -> return address
                MOV     PC, R2          ; call ResourceFS routine
                LDMFD   SP!, {R0, PC}^

        Note that the value of R3 passed in the service call must be given
        to the ResourceFS routine intact, so it can find its workspace.

        This call is subtly different from SWI ResourceFS_RegisterFiles, in
        that it will not cause a Service_ResourceFSStarted to be issued. 
        This is because the ResourceFS module waits until all modules have
        received the Service_ResourceFSStarting before issuing a
        Service_ResourceFSStarted to let the "clients" of Resources: know
        about it.

The format of the (word-aligned) file data is as follows:

        Offset  Size    Meaning
        ------  ----    -------
         0       4      offset from here to the next file (contiguous),
                        or 0 => end of list (no data follows)
         4       4      load address of file  )
         8       4      exec address of file  ) as returned by OS_File (5)
        12       4      size of file          )
        16       4      attributes of file    )
        20       n      full filename, excluding "$.", terminated by 0
        20+n     0..3   padded with 0s until word-aligned
                 4      size of file + 4
                 s      file data
                 0..3   padded with 0s until word-aligned
                        followed by more data in the same format
                        (last entry must be a single 0 word)

The file data must be contiguous - if this is not possible, then
ResourceFS_RegisterFiles should be called once for each of the areas to be
used (and an equivalent set of ResourceFS_DeRegisterFiles's later on).  Note
that each area must be terminated by a single word containing 0.

There are no directory objects, since the directory structure can be
determined from the full filenames supplied.

Note that where name clashes occur, the first occurrence of the filename in
the most recently registered area will be used.


Constructing the modules
------------------------

In net#arf:$.a500.Aasm164, you will find two files:

        Aasm
        ObjAsm

which are the C versions of Aasm 1.64 and ObjAsm 1.64 respectively.  They
require the C shared library (with or without RISC_OSLib extensions) to run.

Version 1.64 has the following additional features:

        BIN     "<filename>"            ; include binary file in output

        DCD     :FLOAD:"<filename>"     ; get load address of file
        DCD     :FEXEC:"<filename>"     ; get exec address of file
        DCD     :FSIZE:"<filename>"     ; get size (length) of file
        DCD     :FATTR:"<filename>"     ; get attributes of file

These are used in net#arf:$.a500.Hdr.ResourceFS in a macro called
"ResourceFile", which takes two arguments: the name of the file to include,
and the name it will have under Resources:.  You can put a series of calls
to this macro in sequence, followed by " DCD 0" to terminate the list, eg:

        ResourceFSfiles
                ResourceFile  Sources.Messages,  Resources.MyProg.Messages
                ResourceFile  Sources.Templates, Resources.MyProg.Templates
                DCD     0

