> 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
       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!