RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

DOSFS


Introduction

DOSFS is an image filing system used to provide DOS disc access from RISC OS.

The description that follows both describes how image filing systems work, and how DOSFS itself works.

DOSFS is not available in RISC OS 2.

Overview

The diagram below shows how DOSFS communicates with other modules in RISC OS 3 to provide the full functionality of an image filing system:


Interactions of DOSFS with other filing systems

The names identify the component parts. The lines identify links between them:

  • Link a is the standard link from FileSwitch to FileCore.
  • Link b is the standard link between FileCore and ADFS.
  • Link c is a link from FileSwitch to an image filing system - in this case DOSFS.
  • Link d is a link between a host filing system - in this case FileCore - and an image filing system - in this case DOSFS.
  • Link e is a link between an image filing system - in this case DOSFS - and a handler of discs - in this case ADFS.

Components of an image filing system

There are three links to DOSFS shown in the diagram above. An image filing system can be considered as having three parts, each of which handles one of the links:

  • the Image Handler (uses link c)
  • the Identifier (uses link d)
  • the Formatter (uses link e)

In practice it is best to have these parts in one module as this ensures a complete, working, system is loaded, rather than a partial system. Also, having the parts in one module saves a small quantity of space, due to the sharing of the module overhead, and, possibly, of code.

The Image Handler

This is the most complex component of an image filing system. Its job is to manage files held within an image file (or partition).

The image filing system's image handler communicates only with FileSwitch, accessing images as files. FileSwitch tells the image handler when it has found an image file which is relevant to the image handler. FileSwitch makes requests to the image handler for it to access files and directories held within the image file. The image handler then translates these requests into file access requests which it makes to FileSwitch, which then passes these requests on to the relevant filing system using standard calls. Thus a filing system need not provide any special support for image filing systems to be able to hold image files.

Any image handler must identify itself to FileSwitch as such. This process is similar to that done by a native filing system, but the number of calls the image handler needs to support is fewer, the rest of the work being handled by FileSwitch.

The Identifier

This part of an image filing system is used to identify the format of a disc. It does so by checking an image's format and contents against all the formats of which it knows.

The request to check an image is made by issuing a service call. If the image filing system's identifier recognises the image, it claims the service call; if not it passes it on. The issuer of the service call waits for its return. An unclaimed service call indicates the image wasn't recognised, and so the issuer can complain about the disc being unreadable.

The Formatter

This part of an image filing system is used to help format a disc, which is done by other sections of the system.

Before a disc can be formatted, the user has to specify a format. The image filing system's formatter responds to service calls to help this process. The service calls - one for desktop menu format selection, and one for * Command format selection - are used to identify parameters defining a format. These parameters are in the form of two SWI numbers - both provided by the formatter - with parameters to be passed to them.

The first of these SWIs is called by the disc handler to negotiate a physical format that is both achievable by the disc handler, and acceptable to the image filing system. Once the disc handler has formatted the disc it then calls the second SWI, with which the formatter lays out the structure of an empty disc.

Points to note

Each module involved in the system only needs to know how to handle a small part of the whole system. For example, the DOSFS image handler doesn't need to know how to identify or format a disc for itself, nor does it need to know how to drive the ADFS disc driver - all it needs to know is how to access a file. Similarly, FileSwitch need make no distinction between discs in a foreign format and image files - they are both presented to FileSwitch as files of a given type.

Once one image filing system is in place, other image filing systems may easily be added to the system by soft loading them.

There is no reason why a single filing system cannot host image filing systems by providing the combined functionality that FileCore and ADFS provide to image filing systems. In such a case, the structure would appear:


Interactions of complete image filing system with other filing systems

Writing image filing systems and host filing systems

If you are writing either an image filing system or a host filing system, you may use this chapter as an example of how an image filing system must behave, and the interfaces it must support; and as pointers to how a host filing system should interact with an image filing system. You should also see the chapter entitled Writing a filing system.

Technical Details

The Image Handler

Because DOSFS's image handler only communicates with FileSwitch, it does not offer any direct interfaces to programmers.

For details of the entry points that an image handler must make available, see the chapter entitled Writing a filing system.

The Identifier

Perhaps the best way to see how the identifier works is an example. This follows through what happens when a user clicks on ADFS's floppy disc icon with a DOS disc in the drive.

  1. The user clicks on the floppy disc icon.
  2. ADFSFiler (the module running the floppy disc icon) sends the Filer (the module running directory viewers) a Filer_OpenDir message for directory adfs::0.$ .
  3. The Filer first checks to see whether it has already got adfs::0.$ open, and, if it hasn't, it creates an internal structure for it and then calls OS_GBPB 10 (read directory entries and information).
  4. FileSwitch receives the OS_GBPB 10 with the name 'adfs::0.$' and does an FSEntry_File 5 on ':0.$' to adfs:
  5. adfs: uses the FileCore module to process requests from FileSwitch. FileCore, which knows about which discs are in which drives, does not yet know what sort of disc is in drive :0 and so makes a request to the ADFS module to mount the disc.
  6. ADFS identifies what physical format the disc has (density, sectors per track, sector numbering etc) and returns to FileCore.
  7. FileCore, having had the physical format identified by ADFS, makes a Service_IdentifyDisc quoting the disc record as filled in by ADFS.
  8. DOSFS receives the Service_IdentifyDisc, updates the disc record and makes various reads and tries to match the answers with valid DOS disc formats. If a valid format is found it claims the service, if no valid format is found it passes the service on. In this example the service will be claimed and DOSFS will pass back the disc record (which includes the disc name and disc cycle id) and a file type to associate with the disc's contents.
  9. FileCore receives the claimed service and records in its own internal drive record that the disc in that drive has the given name and file type. FileCore then returns back to FileSwitch that :0.$ is a file of the type returned to FileCore by DOSFS.
  10. FileSwitch notices that :0.$ is a file of a given type and looks up that type in its table of registered image filing systems. FileSwitch opens adfs::0.$ as a file and notifies DOSFS that it has a new image to handle.

    (If the file type isn't found because DOSFS hasn't registered itself with FileSwitch, FileSwitch returns a 'Disc not understood - has it been formatted?' error.)

  11. DOSFS receives the notification of an image it has to handle, records internally the FileSwitch handle it was quoted and returns its own handle back at FileSwitch.
  12. FileSwitch records against adfs::0.$ the DOSFS handle DOSFS gave it.
  13. FileSwitch calls the DOSFS entry point ImageEntry_Func 15 (read directory entries and information), quoting the DOSFS handle for adfs::0.$ and the name of the directory of ''.
  14. DOSFS enumerates '' (the root directory of the image) and returns to FileSwitch.
  15. FileSwitch filters out any unwanted entries and returns to ADFSFiler.
  16. ADFSFiler displays the directory viewer.
Points to note
  • The host filing system (ie FileCore) issues the service call Service_IdentifyDisc (see Service_IdentifyDisc (Service Call &69)) to request that image filing systems identify a disc.
  • When an image filing system (eg DOSFS) identifies the disc, it fills in the disc name, disc cycle id and other details in the disc record, and then claims the service call, returning to the host filing system.
  • Each image filing system has one (or more) filetypes allocated to it which identifies how the contents of a file of that type should be interpreted as a directory tree with files as leaves.

Disc cycle ids

The host filing system (eg FileCore) keeps two pieces of information about a disc which it uses to identify the same disc at a later time. These are the disc's name and its disc cycle id. The name is the public bit of the identification and is what the user sees; the disc cycle id is used to distinguish between different discs with the same name. Clearly the host filing system needs to be kept abreast of any changes made to the disc's name or disc cycle id.

The only way the disc name can be changed is the FileSwitch call OS_FSControl 50 (see OS_FSControl 50), in which case FileSwitch calls an entry point in the host filing system to inform it of the change.

The host filing system can request image filing systems, where appropriate, to update a disc cycle id when the disc is next altered. It does so by calling OS_FSControl 51 (see OS_FSControl 51). This is so that another machine isn't misled into believing that an altered disc is unchanged, and - for instance - using invalid cached data. It is the responsibility of all image filing systems to flush new disc cycle ids to media by calling OS_Args 255 (see OS_Args 255), and to inform their host filing system whenever a disc cycle id has changed for whatever reason using OS_Args 8 (see OS_Args 8).

If there is a change to the disc cycle id and the host filing system is not informed, then it will refuse to match that disc with its internal record, resulting in continuous 'Please insert disc discname' messages whenever the user tries to access files on the disc. This is clearly undesirable. So, to summarise:

For a host filing system
  • Store away the disc name and disc cycle id to rematch 'new' discs against old ones.
  • Respond to the FSEntry_Func 31 and FSEntry_Args 10 entry points to keep the disc name and disc cycle id up to date.
  • Call OS_FSControl 51 when a disc might have been removed from the drive since it was last accessed.
For an image filing system
  • Call OS_Args 8 whenever you update a disc cycle id.
  • Respond to the ImageEntry_Func 32 entry point to keep the disc cycle id up to date.
Storing disc cycle ids

Depending on an image filing system's disc format, there may or may not be room to fit in an explicit disc cycle id somewhere on the disc. For discs where there is room the disc cycle id should simply be incremented with each update. For discs where there isn't room, a disc cycle id may be some derivative of the structures on the disc, such as a checksum of the free space map. Clearly there's not much that can be done in this situation to update the disc cycle id when requested to, but since it is likely to change anyway with each update, this should not be a problem.

The formatter

The formatter is best explained by following through the process. In this example, the host filing system is FileCore/ADFS; other host filing systems should use exactly the same method.

Selecting a format

There are two ways of selecting a format in RISC OS:

  1. Specifying the format from the command line.
  2. Choosing it from an icon bar menu.
Specifying the format from the command line

Clearly it would be useful for the user to know which formats are available. If the user types *Help Format, ADFS displays help on its own formats, and then issues the service call Service_DisplayFormatHelp (see Service_DisplayFormatHelp (Service Call &6C)). This is passed round all image filing systems, each of which adds its own help text to that already displayed.

To format a disc from the command line, the user calls ADFS's *Format command:

*Format drive [format [disc_name]] [Y]

ADFS then issues the service call Service_IdentifyFormat (see Service_IdentifyFormat (Service Call &6B)), which passes the format around image filing systems. If an image filing system recognises the format, it claims the call. It also returns four values:

  • The number of a SWI it provides that will specify the physical format of the disc. For DOSFS, this SWI is DOSFS_DiscFormat; other image filing systems should use the same naming scheme.
  • A parameter to pass to that SWI, used to specify the format.
  • The number of a SWI it provides that will layout the logical structure of an empty disc onto an image file (which may be an entire disc). For DOSFS, this SWI is DOSFS_LayoutStructure; other image filing systems should use the same naming scheme.
  • A parameter to pass to that SWI, used to specify the structure.
Choosing the format from an icon bar menu

To format a disc from the desktop, the user chooses a format from the Format submenu of the ADFSFiler's floppy disc icon bar menu. The ADFSFiler issues the service call Service_EnumerateFormats (see Service_EnumerateFormats (Service Call &6A)). This is passed round all image filing systems, each of which adds its available formats to a linked list of blocks. Each block specifies a single format, and contains its menu text, its help text, and some flags. These entries are used to display the menu, and to provide help on it. But each block also contains the same four values as are returned by Service_IdentifyFormat, thus once a format has been chosen, ADFSFiler can then make them available to ADFS for the next stage of the process.

Whichever way the format has been selected, the rest of the process is identical. We shall assume that a DOSFS format has been selected, but the process ought to be identical for other image filing systems.

Negotiating a physical format

Once a DOSFS format has been selected, ADFS calls DOSFS_DiscFormat (see DOSFS_DiscFormat), the number of which was obtained from Service_IdentifyFormat, or from Service_EnumerateFormats. In doing so, it passes DOSFS two values:

  • The number of a SWI it provides that will vet the disc format for achievability with the available hardware. For ADFS, this SWI is ADFS_VetFormat; other handlers of discs should use the same naming scheme.
  • A parameter to pass to that SWI, typically used to identify the drive.

DOSFS fills in a disc format structure with the 'perfect' parameters for the specified format, taking no account of the abilities of the available hardware that will have to perform the format. Once filled in, DOSFS calls ADFS_VetFormat (see ADFS_VetFormat) to check the format structure for achievability on the available hardware. ADFS may generate an error if the format differs widely from what can be achieved; alternatively it may alter the format structure to the closest match that can be achieved. ADFS_VetFormat then returns to DOSFS, which checks whether the format block - as updated - is still an adequate match for the desired format. If it is, DOSFS_DiscFormat finally returns to ADFS; otherwise it generates an error.

We recommend that image filing systems and handlers of discs only go through one cycle of vetting, as otherwise an infinite loop may ensue.

Formatting the disc

ADFS now has a disc format structure that contains parameters that are both achievable, and satisfactory to DOSFS.

ADFS physically formats and verifies the disc, either by using the *Format command, or by the desktop formatter. Both methods use ADFS_DiscOp (see ADFS_DiscOp) to write and verify tracks. A bad block list is constructed.

The disc then gets opened as a FileSwitch file by whatever is organising the format (*Format or the desktop formatter).

Laying out the logical structure

Finally, ADFS calls DOSFS_LayoutStructure to layout the logical structure of an empty disc onto the image file opened by FileSwitch - which is, in fact, the whole disc.

Notes

You can also use DOSFS_LayoutStructure to layout a partition in an image file that is only part of a disc.

Much of the information supplied and managed by one module and used by another is quite long. Because of this, an RMTidy operation is very likely to break the formatting subsystem.

SWI numbers in the formatting subsystem may be passed in either X or non-X form, and the receiver should make no assumption about which form it has been given.

Summary of responsibilities

FileSwitch is responsible for:
  • noticing when an image file needs to be opened
  • opening it and redirecting the user's request to the relevant image filing system.
FileCore is responsible for:
  • organising the identification of a disc whose logical structure is, as yet, unidentified
  • faking the entire contents of that disc to be a file of the required type - if an image filing system recognises it - and storing the name of that disc against it
  • identifying its own discs and managing the logical structure of them.
ADFS is responsible for:
  • identifying the physical format of a disc
  • laying down a physical format on a disc
  • reading and writing to a disc
  • verifying a disc
  • organising the formatting and verifying of a disc from the command line.
An image filing system (eg DOSFS) is responsible for:
  • managing the logical structure of an image file given its file handle
  • identifying a particular disc as being one of its own when requested to do so
  • specifying lists of its own formats for the ADFSFiler menu
  • identifying a command line format identifier as one of its own
  • constructing a physical format description record for one of its own formats
  • laying down a logical structure into a file for one of its own formats.
ADFSFiler is responsible for:
  • organising the menu selection of a disc format and organising a format to that specification
  • organising the verification of a disc to a given specification.

Filename mapping

Filenames are mapped between RISC OS and DOS filenames as follows:

From RISC OS to DOS

The RISC OS filename is truncated to 8 characters. Some characters having special meaning are changed:

RISC OS DOS
# ?
? #
+ &
= @
; %
< $
> ^

Note that the first mapping shown above is unlikely to occur in practice, since '#' is a wild card in RISC OS, and '?' a wildcard in DOS. In practice, we recommend that you use alphanumeric filenames where possible.

Filename extensions

DOSFS provides the *DOSMap command (*DOSMap) with which you can set up mappings between RISC OS filetypes and DOS filename extensions.

When transferring a file to DOS, the RISC OS filetype is checked against any that have been registered using *DOSMap; if there is a match the DOS file is given the corresponding filename extension.

From DOS to RISC OS

If the DOS filename has an extension, the separator is changed from '.' to '/'. Characters having special meaning are changed, as above. RISC OS is then passed the filename, concatenated with the (changed) separator and extension. This may be up to 12 characters in total; the *Configure Truncate command (*Configure Truncate) controls how RISC OS copes with this. By default, filing systems will typically handle this from the command line or in program interfaces, but their desktop filers will truncate the names.

Setting file types

When transferring a file to RISC OS, the DOS filename extension is checked against any that have been registered using *DOSMap; if there is a match the RISC OS file is given the corresponding file type. Otherwise the file type is set to 'DOS' (&FE4).

Attribute mapping

If a DOS file is read only, its RISC OS attributes are LWR; otherwise they are RW. If a RISC OS file is locked, it is a read only file when transferred to DOS; otherwise it is a read/write file.

Other attributes are preserved where possible, using a mechanism that is subject to change and so not documented.

SWI numbering

Under RISC OS 3 (version 3.00) DOSFS had a SWI chunk base number of &41AC0; all subsequent versions have a SWI chunk base number of &44B00. If you are writing software that calls DOSFS_DiscFormat or DOSFS_LayoutStructure (the only two SWIs present in 3.00), and wish it to work under RISC OS 3 (version 3.00), you must either call the SWIs by name, using OS_SWINumberFromString to convert the name at run time; or you must call the SWIs by different numbers depending on which version of RISC OS you are running under.

An alternative is to refuse to run under RISC OS 3 (version 3.00), giving a suitable error.

Warning: possible data corruption

There is a bug in DOSFS which can cause data corruption under the following circumstances:

  • You write < 256 bytes to the start of a cluster.

    (A cluster is a technical term used in MS-DOS for a group of sectors, the number of which is format dependent. Note that files always start at the start of a cluster.)

  • The last write before closing a file is later in the same cluster.

There are two possible workrounds:

  1. If writing < 256 bytes that may be at the start of a cluster, use OS_Args 255 to flush the data to disc before any subsequent writes.
  2. Always build data in structures of > 256 bytes before writing it.

SWI Calls


DOSFS_DiscFormat
(SWI &44B00)

Fills in a disc format structure with parameters for the specified format

On entry

R0 = pointer to disc format structure to be filled in
R1 = SWI number to call to vet disc format (eg ADFS_VetFormat)
R2 = parameter in R1 to use when calling vetting SWI
R3 = format specifier

On exit

R0 - R3 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call fills in the disc format structure pointed to by R0 with the 'perfect' parameters for the specified format, taking no account of the abilities of the available hardware that will have to perform the format. Once filled in, this SWI calls the vetting SWI to check the format structure for achievability on the available hardware. The vetting SWI may generate an error if the format differs widely from what can be achieved; alternatively it may alter the format structure to the closest match that can be achieved. The vetting SWI then returns to this SWI, which checks whether the format block - as updated by the vetting SWI - is still an adequate match for the desired format. If it is, this SWI returns to its caller; otherwise it generates an error.

The following format specifiers are recognised:

Value Meaning
0 DOS/Q 1.44M MS-DOS 3.20 double sided
1 DOS/M 720K MS-DOS 3.20 double sided
2 DOS/H 1.2M MS-DOS 3 double sided
3 DOS/N 360K MS-DOS 2, 3 double sided
4 DOS/P 180K MS-DOS 2, 3 single sided
5 DOS/T 320K MS-DOS 1, 2, 3 double sided
6 DOS/U 160K MS-DOS 1, 2, 3 single sided
7 Atari/M 720K Atari double sided
8 Atari/N 360K Atari single sided

The returned disc format structure contains the following information:

Offset Length Meaning
0 4 Sector size in bytes (which will be a multiple of 128)
4 4 Gap1 side 0
8 4 Gap1 side 1
12 4 Gap3
16 1 Sectors per track
17 1 Density:
1 single density (125Kbps FM)
2 double density (250Kbps FM)
3 double+ density (300Kbps FM) (ie higher rotation speed double density)
4 quad density (500Kbps FM)
8 octal density (1000Kbps FM)
18 1 Options:
bit 0 1 index mark required
bit 1 1 double step
bits 2-3 0 interleave sides
1 format side 1 only
2 format side 2 only
3 sequence sides
bits 4-7 reserved - must 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 Sector fill value
24 4 Number of tracks to format (ie cylinders/drive: normally 80)
28 36 Reserved - must be zero

This structure tells you how to format a disc. Note that it differs from that used in FileCore_DiscOp to actually format a track (see The disc format structure pointed to by R4 is as follows:). The differences are because the DiscOp structure only specifies the format of a single track.

Under RISC OS 3 (version 3.00) this SWI had the number &41AC0.

Related SWIs

ADFS_VetFormat, FileCore_DiscFormat

Related vectors

None


DOSFS_LayoutStructure
(SWI &44B01)

Lays out into the specified image a set of structures for its format

On entry

R0 = structure specifier
R1 = pointer to list of bad blocks (terminated by -1)
R2 = pointer to disc name (null terminated)
R3 = file handle of image

On exit

--

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call lays out in the specified image all necessary structures to have a valid, empty, disc. It can be used:

  • to layout a structure on a blank, formatted disc (in which case the specified image should be the whole disc image)
  • to layout a partition in a file on a disc that has already been formatted (for example for the PC emulator).

The following structure specifiers are recognised:

Value Meaning
0 DOS/Q 1.44M MS-DOS 3.20 double sided
1 DOS/M 720K MS-DOS 3.20 double sided
2 DOS/H 1.2M MS-DOS 3 double sided
3 DOS/N 360K MS-DOS 2, 3 double sided
4 DOS/P 180K MS-DOS 2, 3 single sided
5 DOS/T 320K MS-DOS 1, 2, 3 double sided
6 DOS/U 160K MS-DOS 1, 2, 3 single sided
7 Atari/M 720K Atari double sided
8 Atari/N 360K Atari single sided

If the given image format has no option to store a disc name then this parameter 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 value in R0 is used to pass enough information to specify the disc structure. DOSFS uses a simple table index for this; other image filing systems may pass different information (using a pointer if necessary) for their LayoutStructure SWI.

Under RISC OS 3 (version 3.00) this SWI had the number &41AC1.

Related SWIs

None

Related vectors

None

* Commands


*CopyBoot

Copies the boot block from one MS-DOS floppy disc over the boot block of another

Syntax
*CopyBoot source_drive dest_drive
Parameters

source_drive - the number of the source floppy drive (0 to 3)
dest_drive - the number of the destination floppy drive (0 to 3)

Use

*CopyBoot copies the boot block from one MS-DOS floppy disc over the boot block of another.

DOSFS currently writes an MS-DOS 3.30 boot-block onto discs that it formats. If you wish to use a different boot block you need a floppy disc containing that boot block (from another system). You can then use this command to overwrite the MS-DOS 3.30 boot-block with your other boot block.

DOSFS does not place the system files on a disc, so it cannot be used to boot-strap an MS-DOS system or the PC-Emulator. To make a DOSFS disc bootable you need to use this command to copy a bootable boot block to the disc, and also need to copy a suitable set of system files to the disc.

Example

*CopyBoot 0 0
Copies the boot block from one MS-DOS floppy disc to another, using only drive 0. You will be prompted to change discs when necessary.

Related commands

None

Related SWIs

None

Related vectors

None


*DOSMap

Specifies a mapping between an MS-DOS extension and a RISC OS file type

Syntax
*DOSMap [MS-DOS_extension [file_type]]
Parameters

MS-DOS_extension - An MS-DOS file extension of up to three characters
file_type - a number (in hexadecimal by default) or text description of the file type to be mapped. The command *Show File$Type* displays a list of valid file types.

Use

*DOSMap specifies a mapping between an MS-DOS extension and a RISC OS file type. Any MS-DOS file with the given extension will be treated by RISC OS as having the given file type, rather than being of type 'DOS'.

If the only parameter given is an MS-DOS extension, then the mapping (if any) for that extension is cancelled. If no parameter is given, then all current mappings are listed.

The mappings are only retained until the next reset.

Example

*DOSMap TXT Text
Treat all files with an MS-DOS 'TXT' extension as RISC OS Text files. For example, they will have Text file icons, and load into a text editor when double-clicked on.

Related commands

None

Related SWIs

None

Related vectors

None

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015