Filing system changeover

From BeebWiki
Jump to: navigation, search

On BBC series microcomputers the filing system serving files to the application may be interchanged during a session, under user or program control. Under MOS 3.00 and above, a FileSwitch layer enables co-operative filing systems to be selected at each system call, effectively making all FileSwitch-enabled media available simultaneously. This feature is transparent to both user applications and filing system ROMs, and the process of changing from one filing system to another takes place according to the following outline under all versions of Acorn MOS.

User commands

The user may change filing systems by the following means:

  • By giving the *command that invokes the FS. Acorn have standardised many of these commands, and third-party filing systems have introduced their own.
  • By calling OSBYTE &8C to select CFS or OSBYTE &8D to select RFS.
  • By calling OSBYTE &8F with X=&12 and Y set to the filing system ID assigned by Acorn.
  • On machines with MOS 3.00 and higher fitted, by passing a filename to OSFILE or OSFIND which contains a filing system specifier, such as -DISC-:0.$.!BOOT. FileSwitch selects the named FS and delegates the system call to it.
  • Likewise, the sequential file handling calls OSBGET, OSBPUT, OSARGS and OSGBPB as well as OSFIND cause FileSwitch to select the filing system appropriate to the file handle passed as a parameter.

Workspace locations

One or two shared workspace areas are available to filing systems and other applications, according to the machine model and OS version, and some third-party filing systems are furnished with private, extended memory. Filing system ROMs are generally hard-coded to use one of these workspaces. Each workspace comes with varying conditions of use, and ROMs are required to take certain actions at each stage of changeover, according to the location of their workspace:

  • Main memory resident filing systems use absolute shared workspace starting at address &0E00, and allocated by service call &01.
  • HAZEL resident filing systems use high shared workspace from &C000 upwards, allocated by service call &21.
  • Private memory resident filing systems use workspace not managed by the OS.

Service calls

With the exception of the Cassette and ROM Filing Systems, which are built into the OS, one of the following paged ROM service calls will cause an incoming FS to select itself and close down the outgoing FS. The OS has already installed a filing system by the time these calls are issued.

  • &03 - Boot filing system. Issued on reset; the FS whose assigned key is being pressed on the keyboard, or the first FS to receive this call if no key is pressed, initialises as described below. Once initialised it boots from a bootable medium, if requested, and claims the call.
  • &04 - Unrecognised OSCLI. The FS compares the first word on the command line with the *command(s) that invoke it. If there is a match it initialises and claims the call, otherwise it passes the call to other ROMs.
  • &12 - Select filing system. The FS identified by the value in the Y register initialises and claims the call.
  • &26 - *SHUT command issued. Each FS with files open initialises and closes all its files. This call must always be passed on.

FSC &06

The incoming filing system informs the outgoing one that it is taking over by calling FSCV with A = &06. This is a signal to the outgoing FS that it must perform all finalisation tasks that involve its public call points, as they will shortly be replaced.

  • All outgoing filing systems must call OSBYTE with A = &77 to close the *SPOOL and *EXEC files.
  • Main and private memory resident filing systems may stay resident.
  • HAZEL resident filing systems must vacate the high shared workspace, and set a flag in their private workspace indicating that they no longer own the shared workspace. This includes writing modified sequential file buffers back to the media unless private workspace is reserved for their contents.

Service call &10

The OSBYTE &77 call made by the outgoing FS issues service call &10, warning that the *SPOOL and *EXEC files are about to close. For instance, a utility ROM receiving this call may use it to append a log message to the *SPOOL file. All ROMs should pass this call, as its semantics are ill-defined otherwise.

Service call &0F

The incoming FS installs its public entry points on the extended FS vectors, and arranges for the OS to page in the FS ROM at each call. It then issues service call &0F to notify applications that the vectors have changed. This signals to FileSwitch and enhancement ROMs that they may install intercepts on the vectors, and to the outgoing FS (secondarily to FSC &06) that it has been deactivated.

  • Main and private memory resident filing systems may stay resident.
  • Main memory resident filing systems may optionally vacate the workspace, as CFS may be initialising and applications commonly assume that the shared workspace is free while *TAPE is in effect.
  • A HAZEL resident FS that vacates the high shared workspace on FSC &06 may ignore this call.
  • An outgoing HAZEL resident FS that fails to vacate on FSC &06 must vacate the high shared workspace, including writing back modified file buffers, and mark this fact in its private workspace. It must not call its public entry points while vacating, as the vectors have already been changed; it must call its internal routines instead.
  • An application that intercepts OSBYTE &8F to listen for service call &0F must first forward it to paged ROMs, allowing them to modify the extended vectors, before it may hook into the main vectors at &0212..&021F and return to the OSBYTE caller. This avoids forming an infinite loop from a main vector to an extended vector and back.

Service call &0A

The incoming FS is now ready to set up its workspace, and in the case of absolute shared workspace, it issues service call &0A to claim it from the previous owner. This call is orthogonal to, and may be issued before or after call &0F, but it is typically issued after.

  • Only users of absolute shared workspace should issue, and act on this call.
  • An outgoing main memory resident FS must vacate the absolute shared workspace, including writing back modified file buffers, and set a flag in its private workspace indicating that it no longer owns the shared workspace.
  • An incoming main memory resident FS, receiving its own call, may optionally vacate the absolute shared workspace.
  • Filing systems must not call their public entry points while vacating, as the vectors may have already been changed; they must call their internal routines instead.

It should be noted that several filing systems, particularly CFS and RFS, do not issue this call; the advantage is that in its absence, a main memory resident FS may stay resident. Conversely, users other than filing systems may issue this call and claim the workspace, despite many filing systems assuming that they are resident any time that their vectors are installed, which may lead to data corruption. As a precaution, the filing system should not be used while absolute shared workspace is claimed, and the current FS should be reinitialised after use of the workspace by issuing one of the user commands described above.

Initialisation

Beyond this point, the incoming FS initialises itself privately before exiting the service call that invoked it. As part of this process, it inspects the workspace usage flag in its private workspace:

  • if it indicates that it is still resident in shared workspace, the FS typically validates the workspace contents;
  • if the FS has previously vacated, it restores a saved state from its private workspace and validates it. File buffers not restored from private memory must be marked invalid to force re-reading;
  • if validation fails, or if this is the first invocation, it initialises the workspace from scratch, and prints a filing system banner.

In any case it sets a flag in its private workspace indicating that it owns the shared workspace, then exits with RTS to end the service call.

Idempotence

The filing system must ensure that only the first in a series of identical calls has any effect, that is, it must make the calls idempotent. In particular, it must not save state from a workspace that it has already vacated, or restore state to a workspace that it already occupies.

Regregex (talk) 12:07, 23 October 2024 (CEST)