MultiFS Formatting Subsystem Specification

Author: Jonathan Roach
Status: Template used for implmentation
History:
0.08: 31-Jul-91: Add flags to enumformats block
0.07: 19-Feb-91: Note that skews are signed
0.06: 06-Feb-91: Alter description of WriteTrack for greater flexibility
0.05: 23-Jan-91: Tidy up the description of handling
Service_EnuerateFormats.
0.04: 23-Jan-91: Fix 1st use of EnumerateFormats
0.03: 22-Jan-91: Explain how disc address map to the disc in the format
sides 1 or 2 only situation.
0.02: 22-Jan-91: Change definition of MultiFS WriteTrack (format track)
0.01: 08-Nov-90: Updates entered from review

This document describes how an MultiFS filing system interacts with other systems in RiscOS to format a disc.

Notation

<FS>Filer denotes the module application which runs the filing system specific Filer icon on the icon bar. An example <FS>Filer is ADFSFiler.

<Image>_DiscFormat denotes a SWI supplied by a MultiFS filing system. An example might be DOSFS_DiscFormat.

Sequence of Events

Probably the best way to get an overally view of how a MultiFS formats a disc is to outline the sequence of events that happens. There are two routes to formatting a disc: via a menu on the <FS>Filer icon, and via the command line using the *Format command. They each have a large body of common functionality, and have been commoned up where possible to avoid duplication of effort.

Here are the sections of doing a format which are specific to the way the format is chosen:

Selecting format from a menu:

<FS>Filer needs the format submenu. This may be at the time the user menus

        on the <FS>Filer icon, or when the user passes over the Format=>
        submenu arrow, but definitely is NOT when <FS>Filer initialises.

OS_ServiceCall issued by the <FS>Filer In
R1 = Service_EnumerateFormats (&6A) R2 = 0
Out
R2 = pointer to list of format specifications suitable for a menu

Menu constructed from the service call results and is displayed.

<Format selected from menu>

Details of relevant format copied (to r2..r5 to match

                Service_IdentifyFormat (see later))

Service call results discarded from RMA

Selecting format from the command line:

User enters command which is picked up by the filing system:

     *format <disc> <format identifier> [<disc name>]

Filing system issues this service call: OS_ServiceCall
In
R0 = Pointer to nul terminated format identifier extracted from the

          command line.
R1 = Service_IdentifyFormat (&6B) Out
R1 = Service_Serviced
R2 = SWI number to call to obtain raw disc format information R3 = Parameter in R3 to use when calling disc format SWI R4 = SWI number to call to lay down disc structure R5 = Parameter in R0 to use when calling disc structure SWI

Once the format has been chosen, and the parameters are available the actual action of formatting a disc can take place. This is common to both methods of choosing a format.

Performing a format:

This is a two-phase process. In the first phase a physical structure is layed out onto the disc, and in the second phase this is filled in with the logical structure of directories for an empty disc. To find out what physical structure is layed down a form of negitiation is done between <FS> and <Image> (eg ADFS and DOSFS), the result of which is a physical format specification record <FS> can use to format a disc with.

The physical format negotiation goes as follows:

<FS> issues:
SWI <Image>_DiscFormat (R2 from Service_IdentifyFormat) In
R0 = Pointer to disc format structure to be filled in R1 = <FS>_VetFormat (eg ADFS_VetFormat) R2 = parameter to vetting SWI
R3 = Format specifier (R3 from Service_IdentifyFormat)

<Image>_DiscFormat then fills in the physical disc format structure as

        specified by the format specifier. The values it fills in are the
        perfect values for this format, and take no account of the abilities
        of the hardware which will have to perform the format.

Once the disc record is filled in <Image>_DiscFormat issues: SWI <FS>_VetFormat (R1 passed into <Image>_DiscFormat) In
R0 = Pointer to disc format structure to be vetted R1 = Parameter passed to <Image>_DiscFormat in R2

<FS>_VetFormat vets the disc format structure for achievability with the

        available hardware. R1 passed to <FS>_VetFormat should contain
        enough information on the hardware on which the format is to take
        place for the disc format structure to be vetted (R1 may just be the
        disc number).

<FS>_VetFormat updates the disc format structure with values that the

        hardware can achieve. For example the only fill byte value available
        when formatting might be 0, but the requested value may be &4e,
        hence 0 would be filled in as the fill byte value.

<FS>_VetFormat returns with:
Out
Structure updated with achievable values registers preserved

<Image>_DiscFormat rechecks the disc format structure for suitability. It

        may choose to accept formats which only differ by fill byte or
        sector skew, and reject those which have differing numbers of
        sectors per track or other really wild differences.

It is recommended that negotiation only be performed once as otherwise an

        infinite loop may ensue.

<Image>_DiscFormat returns with: Out
Regs preserved and disc format structure filled in with achievable values.

The disc gets physically formatted with given parameters. This may

        either be by *format explicitly, or by !format.

The disc gets verified and a bad block list constructed.

The disc then gets openned as a FileSwitch file by whatever is organising the format (!format or *format).

Finally, the second phase of the format happens and this is issued: SWI <Image>_LayoutStructure (R4 from Service_IdentifyFormat) In
R0 = identifier of particular disc structure to lay down

                (R5 from Service_IdentifyFormat)
R1 = Pointer to bad block list
R2 = Pointer to nul terminated disc name R3 = FileSwitch file handle of image
Out
Regs preserved
  1. Specification of the menu

    To obtain the texts for the format menu, issue an OS_ServiceCall:

    SWI OS_ServiceCall
    On entry:
    R1 = Service_EnumerateFormats (&6A) R2 = 0
    On exit
    R2 = Pointer to list of format specifications

    This service call issued by an <FS>Filer is used to get sufficient information to construct a format=> submenu and to support !Help for that submenu. It is expected that this service be issued at menu construction time, eg when the user has menued on the <FS>Filer icon. If this service is issued at <FS>Filer initialisation then it is likely many formats will not be available, and so doing this service that early is not recommended.

    The responsibilities are as follows:
    The <FS>Filer must issue the service and is responsible for freeing the linked list of blocks and their attached strings. A MultiFS receiving this call is responsible for allocating RMA blocks for each new block to be added to the list and for allocating RMA blocks for copies of the strings. A MultiFS must NOT point at strings embedded inside its code, but must copy the strings into individually allocated RMA blocks instead.

    In detail, a MultiFS must for each format it wishes listed in the menu:

    A linked list block is layed out as follows: Offset Meaning
    0       Link to next of these blocks, or 0 to indicate end of list
    4       Pointer to RMA block containing text suitable for inclusion in the
            format submenu.
    8        Pointer to RMA block containing text which is a suitable response
            for !Help for this format submenu entry.
    12      SWI number to call to obtain raw disc format information.
    16      Parameter in R3 to use when calling disc format SWI.
    20      SWI number to call to lay down disc structure.
    24      Parameter in R0 to use when calling disc structure SWI.
    28      Flags:
            Bit     Meaning when set
            0       'This is a native (ADFS) format'
            1-31    unused - set to 0.
    

    When the user has chosen a format the list should be freed by the <FS>Filer and the format performed using the given parameters.

    2) Formatting from the command line

    *format <disc> <format specification> [<disc name>]

    The format specification is a string which is passed round the image filing systems until one identifies it: Service_IdentifyFormat:
    On entry
    R0 = Pointer to format specification string (nul terminated) R1 = Service_IdentifyFormat
    On exit
    When successful:
    R0 unchanged
    R1 = Service_Serviced
    R2 = SWI number to call to obtain raw disc format information R3 = Parameter in R3 to use when calling disc format SWI R4 = SWI number to call to lay down disc structure R5 = Parameter in R0 to use when calling disc structure SWI When unsuccessful:
    R0 unchanged
    R1 unchanged

    As a module supplying a format (or formats) your service call handler should identify this service and claim it if the format is recognised: On entry
    R0 = Pointer to nul terminated format specification string R1 = Service_IdentifyFormat
    On exit
    If recognised:
    R0 unchanged
    R1 = Service_Serviced
    R2 = SWI number to call to obtain raw disc format information R3 = Parameter in R0 to use when calling disc format SWI R4 = SWI number to call to lay down disc structure R5 = Parameter in R0 to use when calling disc structure SWI If the format is not recognised just return with the registers unchanged, thus passing this service call to the next module.

    2a) *Help format

    Given that there is a *format command, it would be nice if there was an interface for MultiFSs to supply help on their formats. To this end this service will be issued when help on formats is required:

    Service_DisplayFormatHelp (&6c):
    On entry
    R0 = 0
    R1 = Service_DisplayFormatHelp
    On exit
    If help was displayed without a hitch: Regs unchanged, service passed on
    If an error occured whilst displaying the help: R0 = pointer to error block
    R1 = Service_Serviced (the service is claimed)

    The receiver of the service should list the formats it will respond to in Service_IdentifyFormat. The list should be displayed one format per line in this format:

    <format>        <Description>
    
    Where <format> is the text as recognised by Service_IdentifyFormat, and <Description> is a description of the format. A couple of examples might be:
    E               FileCore E format for use on ADFS floppy discs
    DOS8            8 Sectors per track DOS floppy disc format
    
    The listing should be done using OS_WriteC or a derivative of that (eg OS_Write0, OS_WriteS etc)

    3) Performing the format

    Once a format has been found, the actual operation of formatting the disc can start. This process goes as follows:

    a) Get the physical format parameters

    b) Format the disc physically

    c) Open the disc as a disc image file

    d) Lay down a filing system structure onto it

    Having selected a format from the menu or the command line, four parameters will be available which specify the format:

    i) SWI number to call to obtain raw disc format information ii) Parameter in R3 to use when calling disc format SWI iii) SWI number to call to lay down disc structure iv) Parameter in R0 to use when calling disc structure SWI

    The first should be used to obtain the physical disc format:

    3a) Getting the physical format parameters

    SWI <Image>_DiscFormat (paramter (i) above) On entry
    R0 = Pointer to disc format structure to be filled in R1 = vetting SWI (eg ADFS_VetFloppyFormat) R2 = Parameter to the vetting SWI
    R3 = Format specifier (parameter (ii) above) On exit
    All regs preserved and format structure filled in.

    This SWI number and its parameter in R0 were obtained when the format was chosen. The vetting SWI, supplied by the caller of this SWI, will be used to vet the format specification before it is returned from <Image>_DiscFormat. The vetting procedure should correct the format specification to something which can be performed by the disc controller. The reason that the <Image>_DiscFormat, and not the caller of <Image>_DiscFormat, calls the vetting SWI is so that <Image>_DiscFormat can check the achievable format, as given by the vetting SWI, for usefulness before accepting the corrected format and passing it back.

    Contents of a disc format specification structure:

    Format specification record:
    Offset Length Meaning

    0       4       Sector size
    4       4       Gap 1 side 0
    8       4       Gap 1 side 1
    12      4       Gap 3
    16      1       Sectors per track
    17      1       Density:
                    0       SD
                    1       DD
                    2       HD
                    3       ED
    18      1       Options:
                            Bit     Meaning when set
                            0       Lay down an index mark (1)
                            1       Single step (0); double step (1)
                            2-3     Alternate sides (0)
                                    format side 1 only (1)
                                    format side 2 only (2)
                                    sequence the sides (3)
                            4-7     Reserved - should be 0
    19      1       Start sector number on a track
    20      1       Sector interleave
    21      1       Side/Side sector skew (signed)
    22      1       Track/Track sector skew (signed)
    23      1       Fill value
    24      4       Number of tracks to format
    28      36      Reserved (must be 0)
    

    The structure returned must have been vetted using the given SWI as follows:

    SWI <FS>_VetFormat
    On entry:
    R0 = Pointer to required format
    R1 = Parameter given to <Image>_DiscFormat in R2 (eg disc number) On exit
    No registers changed, but the format structure will have been vetted and updated with the parameters which can actually be used. If the vetter cannot sensibly downgrade the parameters an error will be returned.

    The vetted parameter block can be further checked by <Image>_DiscFormat and rejected as being too far from the original. This should be indicated by returning an error.

    3b) Formatting using the physical format structure


    SWI <FS>_DiscOp 4 Write track
    On entry
    R1 = &000000o4
    R2 = Disc address of start of track
    R3 = 0 (this distinguishes it from a normal Write track) R4 = Pointer to disc format structure On exit
    All regs preserved, except in an error.

    The disc format structure is as follows: Offset Length Meaning

    0       4       Sector size (bytes)
    4       4       Gap1 side 0
    8       4       Gap1 side 1
    12      4       Gap3
    16      1       Sectors per track
    17      1       Density:
                    1 - single (125Kbps FM)
                    2 - double (250Kbps MFM)
                    3 - Double+ (300Kbps MFM)
                    4 - quad (500Kbps MFM)
                    8 - octal (1000Mbps MFM)
    18      1       Options:
                    Bit 0   1 - index mark required
                    Bit 1   1 - double step
                    Bit 2-3 0 - alternate sides
                            1 - Format side 1 only
                            2 - format side 2 only
                            3 - Sequence sides
                    Bit 4-7 reserved, should be 0
    19      1       Sector fill value
    20      4       cylinders per drive
    24      12      Reserved, should be 0
    36      ?       Sector ID buffer, 1 word per sector:
                    bits    use
                    0-7     Cylinder number mod 256
                    8-15    Head (0 for side 1, 1 for side 2)
                    16-23   Sector number
                    24-31   Log2 sector size - 7, eg 1 for 256 byte sector
    

    The o nibble in R1 is the flags nibble as normal. The SWI will format a track of the specified disc. An error will occur if the specified format is not possible to generate, or if the track requested is outside the valid range. The tracks are numbered from 0, so the valid track numbers are 0 to number of track minus one. The mapping of the address is controlled by the disc structure record.

    For the driver writers: The alternate sides and double step information must be remembered against the drive so that when the disc is Mounted in preparation for laying out a structure on it these values can be stored in the disc record passed to <FS> by FileCore. Only the last such information need be remembered. For the purposes of formatting, formatting side 1 or 2 only means the disc should be treated as a sequenced sided disc. Also, as far as the disc driver writer is concerned no distinction should be made between side 1 only, side 2 only and sequence sides, as this will be taken acount of by the controlling software. So, disc address 0 on format side 2 only still means the first byte (byte 0) on side 1.

    3c) Verifying a Disc


    A disc is expected ot be verified using the standard DiscOp verify sectors. It is up to the caller to manage the collection of bad sectors for use later.

    Once the disc has been formatted using the parameters passed back by <Image>_DiscFormat, then a structure must be layed out. To do this the whole disc image is opened as a single file and this is passed to the structure layout SWI given above:

    3d) Laying out a structure on a blank, formatted, disc

    SWI <Image>_LayoutStructure (parameter (iii) above) R0 = identifier of particular disc structure to lay down (parameter (iv)

                            above)
    
    R1 = Pointer to list of bad blocks
    R2 = Pointer to nul terminated disc name R3 = File handle of image

    This SWI should lay out in the disc image all necessary structures to have a valid, empty, disc. If the given image format has no option to store a disc name then this should be ignored. The bad block list should be presented as an array of bad block addresses. Each address is four bytes long. The array is terminated by a -1 entry. It is assumed that R0 gives enough information for the format - it may be that R0 contains many bit fields or points to a block of information - the choice is up to the image filing system module.

    The disc image is treated as a file so that an image can be layed out in a real file, for example, for the PC emulator.

    Further information

    Disc record extension:
    Offset Length Meaning

    0       1       Log2 of sector size
    1       1       Sectors per track
    2       1       Heads:
                            If there are physically n heads then, if the tracks are
                            numbered 0..s-1 on side 0, then s..2s-1 on side 1 and so on, then
                            n-1 will be stored here, otherwise n will be stored here.
    3       1       Density (0 - Hard disc; 1, 2 or 4 for 256, 512 and 1024 byte sectors)
    4       1       Length, in bits, of the id field of a map fragment.
    5       1       Number of bytes which correspond to one map bit
    6       1       Track/Track sector skew for random access file allocation
    7       1       Boot option
    8       1*      Was reserved, now is:
                    Bit     Meaning when set
                    0-5     Lowest numbered sector on a track
                    6       Tracks are numbered 0..s-1 on side 0, then s..2s-1 on side 1, etc
                    7       Double step
    9       1       Number of zones on disc
    10      2       Zone spare - non-allocation bits between map sectors.
    12      4       Disc address of root directory
    16      4       Disc size (bytes)
    20      2       Disc id
    22      10      Disc name
    32      32      Reserved
    

    It should be noted that much of the information supplied and managed by one module and used by another is quite long. Because of this, an RMTidy operation would break this system.

    You may well have noticed the large number of SWI numbers being passed around. These may be passed in either X- or non-X form, and the receiver should make no assumption about which form it has been given.