> SWIs

Title: SWI interface to DeviceFS
Authors: David De Vorchik, Tim Dobson
History:
        27-Apr-91 DDV Created.
        29-May-91 TMD Corrected some typos.
        31-May-91 TMD Corrected another typo.
        30-Jul-91 TMD Added some of Mark Taunton's comments.


SWI interface
=============

This document describes the SWI interface to DeviceFS.                 

NB: All reserved/unused fields should be 0 for future expansion.


42740   DeviceFS_Register 
-------------------------

 in:   r0  = global flags for device
                       bit 0 clear => character device
                       bit 0 set => block device
                       bit 1 clear => device is not full duplex
                       bit 1 set => device is full duplex
                       bit 2 clear => device TX/RX monitoring not necessary
                       bit 2 set => MontorTX/RX can be used

       r1 -> list of devices to be installed
                       +0   = self-relative offset to device name / =0 no more devices
                       +4   = flags specific to this incarnation of the device
                                       bit 0 clear => device not buffered
                                       bit 0 set => device is buffered
                                       bit 1 clear => don't set a path variable for device
                                       bit 1 set => set a path variable for device
  
                       +8   = default flags for the RX buffer of the device
                       +12  = default size of RX buffers
                       +16  = default flags for the TX buffer of the device
                       +20  = default size of TX buffers
                       +24  = reserved for future expansion (must be zero)

                       .... repeating until first word =0.
                                                   
       r2 -> device entry point
       r3  = private word
       r4  = workspace pointer
       r5 -> validation string / =0 none (pass through to caller)
       r6  = maximum number of RX streams / =0 for none / =-1 unlimited
       r7  = maximum number of TX streams / =0 for none / =-1 unlimited

 out:  V clear => r0  = device handle
       V set => r0 -> error block

This SWI registers the parent and its associated devices to DeviceFS.  The
parent is the actual interfacing code with the hardware and the device acts
as a port into the parent.  A device driver may have many devices within it, 
for instance you may have a device which supports both buffered and
unbuffered transfer.

The SWI accepts r0 as a global flags word which describes what the device
actually does and how it works.  It contains the following bit fields:

Bit 0 is used to indicate if the device is a character or block device, an
example of a block device is a floppy driver where data is transferred in
blocks (sectors) to the caller.  A character device could be a parallel 
port or serial port.  All devices within RISC OS 2.50 are character devices,
block devices are not currently supported under the RISC OS 2.50
implementation of DeviceFS.

Bit 1 this is used to indicate if the device is full duplex or not, ie.
can handle both input and output streams at the same time.

R1 on entry contains a pointer to the list of devices to be associated with
this parent record being created.  The list is terminated by a null word,
and the list on entry to this SWI need not actually define any devices at
all and they could be registered later.

Assuming that a device is being registered then the first word of the
list contains a self relative offset to the device name, this is used for
creating options variables and is used in the DeviceFS directory structure. 
We suggest that device names be registered with Acorn to avoid conflicts.

The next word is a set of flags describing the characteristics of this
particular implementation of the device:

Bit 0 indicates if the device is buffered or not.  Bit 1 is used to
say if the device would like a path variable so that it can be
access as a pseudo filing system, ie. parallel: is achieved via setting up a
variable called 'Parallel$Path' which points to the DeviceFS entry for this
device.

The next four words in the control block contain information and sizes for
buffers to be created for the device when a stream is opened onto it.  These
words should be zero if not used, see the Buffer Manager documentation of
the flags).

The control block then repeats n times until a null entry is found.  If for
any reason a device should fail to register than all devices specified will
be removed.

r2 on entry to the SWI contains the pointer to the device entry point, this
is called with various reason codes both from DeviceFS and the outside
world.  This is the suggested interface between devices and external
applications.

r3 and r4 contains parameters which are to be passed in on device calls.  r3
contains a private word passed to the device, this can be used for what ever
the device wants, usually to indicate which hardware platform is being used. 
r4 is used as a workspace pointer and is passed to the device in r12.

On entry r5 contains the pointer to a validation string used to decode
special fields within the device.  This value can be 0 which means that the
string will be passed to the device unparsed, in these cases any unknown
keywords should be ignored as there will be ones used by DeviceFS present.

r6 and r7 contains the counters for the maximum number of output streams on
a device.  If a register is zero then the device does not support that
operation, if a value is -1 then the device has unlimited support for that
type of transfer and will be called to open streams.

DeviceFS range checks the number of streams being opened using these values
so that device driver need not worry about what is happening around it, it
can assume (unless unlimited) that it will only receive x open requests.

When registering a device DeviceFS checks to see if a system variable is
set called 'DeviceFS$<device name>$Options', if it does not exist then it
will attempt to create it with a null entry.  This is used for storing
device setup options.  It is concatenated with the special field strings
when streams are opened.


42741   DeviceFS_Deregister
---------------------------

 in:   r0  = device handle

 out:  V clear => device deregistered (all preserved)
       V set => r0 -> error block.

This call will deregister all devices and their parent from DeviceFS.  This
causes all streams to be closed and the system variables setup for the
device to be unset.  The exception to this is the 'DeviceFS$<device
name>$Options' variable which will be left intact so that when the device is
reloaded it can assume the original setup.


42742   DeviceFS_RegisterObject
-------------------------------

 in:   r0  = device handle
       r1 -> list of devices to be registed with device (see Register call) 

 out:  V clear => all devices registered.
       V set => devices not registered (none will have been registered)

This call registers a list of devices with a parent of the device.  This is
an extension to the DeviceFS register SWI which itself allows devices to be
registered when the parent record is made.



42743   DeviceFS_DeregisterObject
---------------------------------

 in:   r0  = device handle
       r1 -> device name of the object to remove

 out:  V clear => device has been deregistered.
       V set => device could not be deregistered.

This call will deregister a device related to a particular parent, tidying up
as required.



42744   DeviceFS_CallDevice
---------------------------

 in:   r0 = reason code
       r1 -> parent record (device handle), or
          -> path (can include "$."), or
          = 0 broadcast to all devices

   r2..r7  = parameters passed to device
       wp -> workspace

 out:  V clear, registers setup as defined by call
       V set, r0 -> error block.

This call is used to talk to the actual device, the call is made and then
the device is called with the specified register set.  A call can be
directed at a specific device or all devices.  When directing a call at a
specific device you can specifiy this by either its parent handle or its
filename within the directory structure.




The following SWIs are used by devices to communicate with DeviceFS when transferring
or handling data.
                 

42745   DeviceFS_Threshold
--------------------------

 in:   r1  = external handle (from DeviceFS on open)
       r2  = threshold value to be used / -1 to read
       
 out:  V set, r0 -> error block
       V clear, preserved.

This call is used to set the threshold value used on buffered devices, this
SWI will give an error if the device is not buffered.  Otherwise a set
of halt and resume reason codes will be passed to the device when the
buffer levels get close to the specified threshold.



42746   DeviceFS_ReceivedCharacter
----------------------------------

 in:   r0  = byte recieved
       r1 -> external handle (from DeviceFS on open)

 out:  C set, if byte not transferred, else C clear.

This call is made by the device when it receives a character.  DeviceFS then
attempts to process the character as required unblocking any streams that may
be waiting for the character or simply inserting it into a buffer.

The C flag is set to indicate if the transfer was successful.



42747   DeviceFS_TransmitCharacter
----------------------------------

 in:   r1  = external handle

 out:  C clear:
               r0  = character to transmit (8 bits)
       C set:
               unable to read character to be transmitted

       V set, r0 -> error block!

This call is used when the device wants to transmit a character. DeviceFS will
attempt to obtain the character to be sent either by extracting from
the buffer or reading it from a waiting stream.


NB: For speed TransmitCharacter and CharacterReceived do not validate
    the external handle passed so be warned some strange effects can
    occur by passing in duffo handles matey!

