Software and Utilities for Trident Disks:
                              Tfs and Tfu






1. Introduction


This document  describes Bcpl-based software  for operating any  of the
family of  Trident disk  drives attached  to an  Alto using  a "Trident
controller card" (the software presently deals with the T-80  and T-300
models).   Hardware  and diagnostic  information  can be  found  in the
document "Trident disk for the Alto"  (on AltoTrident.press),
by Roger Bates.

A  "Shugart controller  card" also  exists, for  connecting  to Shugart
model  SA-4004  and SA-4008  disk  drives.  The  Shugart  controller is
microprogram compatible  with the Trident  controller, and  the Trident
software can operate it as  well.  In this document, all  references to
Trident  disks  apply to  Shugart  disks as  well,  except  where noted
otherwise.

The software  documentation is  divided into three  parts: (1)  a brief
"how-to"  section  describing   the  software  package   available  for
operating the  Trident; (2)  a section  describing the  utility program
Tfu; and (3) a section describing the software package in  more detail.
There is a short revision  history at the end.  (Documentation  for the
Triex program, formerly included  here, has been eliminated.   Triex is
now needed only for hardware checkout and is not required during normal
operation.)

The  Tfs  package and  utilities  all assume  that  the disk  is  to be
formatted with  1024 data  words per sector.   The maximum  capacity of
each disk is given in the following table.

    Disk     Tracks   Heads    Sectors  Total pages   Total words
    T-80     815      5        9        36,675        37,555,200
    T-300    815      19       9        139,675       142,709,760
    SA-4004  202      4        8        6,464         6,619,136
    SA-4008  202      8        8        12,928        13,238,272

For all disks  except the T-300, it  is possible to construct  a single
Alto-format file system utilizing  the full disk capacity.  Due  to the
restriction of virtual disk addresses to 16 bits, a single  file system
may utilize only about 47 percent of a T-300 disk, and it  is necessary
to construct multiple file systems  in order to make use of  the entire
disk.

Because of bandwidth limitations,  it is unwise to operate  the Trident
disk while the Alto display is on.  Although the Tfs package  will save
the display state, turn it  off, run the disk, and restore  the display
for  every  transfer, the  user  may  prefer to  turn  the  display off
himself.  The Tfs management of the display causes the screen  to flash
objectionably whenever frequent calls to Tfs are underway.

                             ------------
                   Copyright Xerox Corporation 1980


Trident disk software        June 14, 1980                            2




The  present version  runs only  under Operating  System version  16 or
newer.



2. Trident File System (Tfs) software package


The  software   for  operating  the   Trident  disk  is   contained  in
Tfs.dm,  and  consists   of  the  following   relocatable  files:
TfsInit.br, TfsBase.br, TfsA.br, TfsWrite.br TfsCreate.br, TfsClose.br,
TfsDDMgr.br,   TfsNewDisk.br,   TfsSwat.br,   and   TriConMc.br.    The
definitions file Tfs.d is also included.

Source files are contained in TfsSources.dm.  Included also
are the Trident microcode source files, TriConMc.mu  and TriConBody.mu.
These are needed if you want to load other microcode into the Ram along
with the Trident microcode.

The  LoadRam.br file,  formerly included  as part  of the  Tfs,  is now
available as a separate package.


2.1. Initializing the microcode

Operating the  Trident requires special  microcode that must  be loaded
into the  RAM before  disk activity can  start.  The  procedure LoadRam
will load the RAM from a table loaded into your program (it is actually
part of TriConMc.br).  It will  then "boot" the Alto in order  to start
the  appropriate  micro-tasks in  the  RAM.  (This  booting  process is
"silent" -- it does not re-load Alto memory from the file Sys.Boot, but
instead lets your program  continue.) The standard way to  call LoadRam
to load the Trident disk microcode is:

        external DiskRamImage
        external LoadRam

        let result=LoadRam(DiskRamImage, true)  //Load and boot
        if result ls 0 then
                [
                Ws("The Alto has no RAM or no Ethernet board.")
                Ws(" Cannot operate Trident")
                finish
                ]

After  LoadRam  has  returned successfully,  the  code  of  LoadRam and
TriConMc may be overlaid with data -- they are no longer needed.

When exiting a  program that has micro-tasks  active in the RAM,  it is
helpful  to  "silently"  boot  the Alto  so  that  all  micro-tasks are
returned to the ROM.   If this is not  done, subsequent use of  the RAM
may cause some running micro-task to run awry.  To achieve  the "silent
boot," simply call the procedure TFSSilentBoot() at 'finish' time or as
part of a 'user finish procedure'.

For further information, consult the LoadRam package documentation.


Trident disk software        June 14, 1980                            3




2.2. Initializing the Trident drive

Once the RAM has been loaded, the Trident disk can be initialized.  The
procedure TFSInit will  do this, provided  that a legal  file structure
has previously been  established on the  drive (see Tfu  Erase, below).
The procedure returns  a "disk object," a  handle which can be  used to
invoke all the disk routines.   This disk object (or "disk"  for short)
can be passed to various  Alto Operating System procedures in  order to
open streams on Trident disk files, delete Trident disk files, etc.

tridentDisk = TFSInit(zone, allocate [false], driveNumber [0], ddMgr
            [0], freshDisk [false])

zone        You must provide a free-storage pool from which  memory for
            the disk  object and  possibly for a  buffer window  on the
            disk  bit table  can  be seized.   The zone  must  obey the
            normal  conventions  (see  Alto  Operating  System Manual);
            zones created by InitializeZone are fine.

allocate    This flag is true if you wish the machinery  for allocating
            or de-allocating disk space  enabled.  If it is  enabled, a
            small DDMgr object and a 1024-word buffer will be extracted
            from the zone in order to buffer the bit table  (unless you
            supply a ddMgr argument, described below).

driveNumber This argument, which defaults to 0, specifies the number of
            the Trident disk drive being initialized.  If the  drive is
            a T-300,  the left-hand  byte specifies  the number  of the
            file system to be accessed on that drive, in the range 0 to
            2.  (For further information, consult the  section entitled
            'Disk Format'.)

ddMgr       This argument, which defaults to 0, supplies a handle  on a
            'DiskDescriptor    Manager'    (DDMgr)     object,    whose
            responsibility it is to manage pages of  the DiskDescriptor
            (bit table), which, on the Trident, must be paged  into and
            out  of  memory  due to  its  considerable  size.   If this
            argument  is defaulted,  a separate  DDMgr will  be created
            upon each call to TFSInit, at a cost of a little  over 1024
            words.  If you intend to have multiple Trident  drives open
            simultaneously, you  may conserve  memory by  first issuing
            the call  'ddMgr =  TFSCreateDDMgr(zone)' and  then passing
            the returned pointer as the ddMgr argument in each  call to
            TFSInit, thereby permitting  the single ddMgr to  be shared
            among  all drives.   (This argument  is ignored  unless the
            allocate argument is true.)

freshDisk   Normally,  TFSInit  attempts  to  open  and  read   in  the
            DiskDescriptor file  in order  to obtain  information about
            the  file  system.   However, if  freshDisk  is  true, this
            operation is  inhibited and  the corresponding  portions of
            the  disk  object are  set  up with  default  values.  This
            operation is essential for creating a virgin file system.

tridentDisk The procedure returns  a disk object,  or 0 if  the Trident
            cannot  be  operated  for  some  reason.   The  most likely
            reasons are:

            1. No Trident disk controller plugged into the Alto.


Trident disk software        June 14, 1980                            4




            2. No such disk unit, or disk unit not on-line.

            3.  Can't  find  SysDir,  can't  open   DiskDescriptor,  or
            DiskDescriptor format is incompatible.  (These errors can't
            happen if freshDisk is true.)

            Important: If the AC power  to drive 0 is turned off  or no
            drive 0  is connected,  it is not  possible to  operate any
            drive.  (Drive 0 need not be on-line, however.) This is due
            to a  hardware bug  that has been  deemed too  difficult to
            fix.

After TFSInit has been executed, the code can be overlaid, as it is not
used for normal disk operation.


2.3. Closing the Trident disk

When all operations on  the disk are completed, the  TFSClose procedure
will insure that any important state saved in Alto memory  is correctly
written  on the  disk.   This step  can  be omitted  if  the 'allocate'
argument to TFSInit was false (assuming you don't mind the loss  of the
storage that was extracted from 'zone' by TFSInit).

        TFSClose(tridentDisk, dontFree [false])

The second argument is  optional (default=false), and if true  will not
permit the DiskDescriptor Manager (DDMgr) to be destroyed.  This option
is useful in conjunction with the 'ddMgr' argument to TFSInit.


2.4. Example

Following  is  an  example  that  uses  the  Trident  disk  system  and
demonstrates the  procedures described above.   Note that the  calls on
operating system disk  stream routines all pass  a private zone  to use
for stream structures, rather than the default sysZone.  The  reason is
that streams on Trident disks require large buffers (1024  words) which
quickly  exhaust  the available  space  in sysZone.   In  addition, the
stream  routines  will  consume more  stack  space  when  operating the
Trident disk than they do when operating the standard Alto disk.

Since the Alto  OS does not  know about Trident  disks, a call  to Swat
will  not properly  wait for  all Trident  transfers to  complete, with
consequent undefined results.  This problem is easily  remedied through
use of an  assembly-language Swat context-switching  procedure TFSSwat,
which is included as part of the TFS package.  The example shows how it
is set up.

//Example.bcpl -- TFS Example
//Bldr Example TfsBase TfsA TfsWrite TfsCreate TfsClose TfsDDMgr
//  TfsSwat TfsInit LoadRam TriConMc

get "streams.d"

external [
        TFSInit
        TFSClose
        TFSSilentBoot
        LoadRam


Trident disk software        June 14, 1980                            5




        DiskRamImage

        OpenFile
        Closes
        Puts
        DeleteFile

        InitializeZone
        SetEndCode
        TFSSwatContextProc
        lvUserFinishProc
        lvSwatContextProc
        ]

static [ savedUFP; savedSCP; TFSdisk = 0 ]

let TryIt() be
[
        let driveNumber=0
        let zonevec= vec 3000
        let TFSzone = InitializeZone(zonevec, 3000)

//Initialize the RAM:
        let res=LoadRam(DiskRamImage, true)
        if res ls 0 then [ Ws("Cannot load the RAM."); finish ]

//Set up to cleanly finish or call swat
        savedUFP = @lvUserFinishProc
        @lvUserFinishProc = MyFinish
        savedSCP = @lvSwatContextProc
        @lvSwatContextProc = TFSSwatContextProc

//Initialize the disk:
        TFSdisk = TFSInit(TFSzone, true, driveNumber)
        if TFSdisk eq 0 then
                [ Ws("Cannot operate Trident disk"); finish ]

//Reclaim space used by initialization code:
        SetEndCode(TFSInit)     //Overlay TFSinit, LoadRam, TriConMc

//Now we are ready to operate the disk:
        DeleteFile("Old.Bad", 0, 0, TFSzone, 0, TFSdisk)

        let s=OpenFile("New.Good", ksTypeReadWrite, 0,0,0,0,
                                TFSzone, 0, TFSdisk)

        for i=1 to 1000 do
         for j=1 to 1000 do Puts(s, $a) //Write a million bytes!

        Closes(s)

        finish
]

and MyFinish() be
[
        if TFSdisk ne 0 then TFSClose(TFSdisk)
        @lvUserFinishProc = savedUFP
        @lvSwatContextProc = savedSCP
        TFSSilentBoot()


Trident disk software        June 14, 1980                            6




]



3. Trident File Utility, Tfu


The  Tfu utility  (saved on  Tfu.Run) is  used to  certify  a new
Trident pack  for operation, to  initialize a pack  with a  virgin file
system, and  to perform various  file copying, deleting,  and directory
listing operations.

Commands are given  to Tfu on  the command line:  immediately following
the word "Tfu" is a sub-command name (only enough characters of  a sub-
command are needed in order to distinguish it from other sub-commands),
followed by optional arguments.  Several subcommands may appear  on one
command line, separated by vertical  bars.  Thus "TFU Drive 1  | Erase"
will erase drive 1.  There must be a space on each side of the vertical
bar.

All information shown on the  display by Tfu is also written  into file
Tfu.log  (on  the  Diablo  disk).   Certain  commands  pause  and  type
"Continue?" after each screenful; type any character to proceed.

In what follows, an "Xfile" argument is a filename, perhaps preceded by
a string that specifies which disk is to be used:

        DP0:name.extension      -- use standard Alto (Diablo) disk
        TPn:name.extension      -- use Trident drive n (n=0 to 7)
        name.extension          -- use default disk (Trident)

The "default disk" is always a Trident drive; the identity of the drive
is set with the Drive command.

TFU DRIVE driveNumber

      This command sets the default Trident drive number to use for the
      remainder of the command line.  The default drive  is effectively
      an  'argument' to  the  CERTIFY, ERASE,  DIRECTORY,  CONVERT, and
      BADSPOTS commands.   (On a T-300,  file systems 0,  1, and  2 are
      specified  as  'TPx', 'TP40x',  and  'TP100x', where  'x'  is the
      actual unit number.)

TFU CERTIFY [passes]

      This command  initializes the  headers on  a virgin  Trident disk
      pack, then runs the specified number of passes (default  10) over
      the  entire  pack,  testing it  using  random  data.   Any sector
      exhibiting an uncorrectable ECC error, or correctable  ECC errors
      on two or more separate occasions, is permanently marked unusable
      in  the  pack's bad  page  list.  This  information  will survive
      across all  subsequent normal  file system  operations (including
      TFU ERASE), but may be clobbered by the Triex program.

      This command should be executed on every new Trident  pack before
      performing any other operations  (such as TFU ERASE).   10 passes
      of  TFU CERTIFY  are  adequate for  reasonably  thorough testing,
      though more are recommended for packs to be used  in applications
      requiring high  reliability.  The running  time per pass  for TFU


Trident disk software        June 14, 1980                            7




      CERTIFY is approximately 3  minutes on a Trident T-80,  9 minutes
      on a T-300, and 1.5 minutes on a Shugart SA-4008.

      TFU  CERTIFY  may  be  terminated  prematurely  by  striking  any
      character to get its attention, then typing 'Q'.  Subsequent runs
      of TFU CERTIFY will not clobber the existing bad page information
      but  rather will  append to  it.  It  is recommended  (though not
      necessary) that TFU CERTIFY be executed before each TFU  ERASE so
      as to pick up any new bad spots that may have developed.

      TFU CERTIFY ordinarily  asks you to  confirm wiping out  the disk
      before going ahead  and doing so;  however, the /N  global switch
      may be used to indicate that no confirmation is necessary.

TFU BADSPOTS

      Displays the addresses  of all known bad  spots on the  disk pack
      mounted on the default drive.

TFU RESETBADSPOTS

      Resets the bad spot table of the disk pack mounted on the default
      drive.  (Note that TFU  CERTIFY appends to the existing  bad spot
      table.) There should normally be no need to execute this command,
      but it may be useful, for example, after a disk pack  is cleaned,
      if the known bad spots were caused by dirt.

TFU ERASE [tracks]

      This command initializes (or reinitializes) a file system  on the
      pack mounted on  the default Trident  drive, after asking  you to
      confirm your destructive intentions (overridden by the  /N global
      switch).  The tracks argument specifies how many "tracks"  of the
      drive are to be included  in the file system; it defaults  to the
      maximum   possible.    If   smaller   numbers   are   used,   the
      initialization is  correspondingly faster.   In any  case, tracks
      beyond  the  one  specified are  available  for  use  outside the
      confines of the file system.  (Note that one "track" is 45 pages;
      this corresponds  to one  cylinder on  a T-80  and to  nothing in
      particular on other disks.)

      The disk pack should previously have been initialized  and tested
      by means of the TFU CERTIFY command.

      The DiskDescriptor file is normally located in the middle  of the
      file  system  so as  to  minimize average  head  movement between
      DiskDescriptor  and file  pages.   However, this  does  limit the
      maximum size contiguous file that can be created to a little less
      than half the  file system.  If you  wish to create  a contiguous
      file  larger  than  that,  use the  /B  local  switch  (i.e., TFU
      ERASE/B)  to  force  the  DiskDescriptor  to  be  located  at the
      beginning of the file system instead.

TFU COPY Xfile ← Xfile

      This command copies  a file in the  direction of the  arrow.  The
      destination file may be optionally followed by the switch  /C, in
      which case (provided it is a Trident disk file), the file will be
      allocated on the disk at consecutive disk addresses.  (Note: More


Trident disk software        June 14, 1980                            8




      precisely, an attempt will be made to perform such an allocation.
      If the attempt  fails, you will  sometimes get an  error message.
      The best way to  verify that a file  is contiguous is to  use the
      "address" command, below.)

TFU CREATEFILE Xfile pages

      This command  creates a contiguous  file named Xfile  with length
      "pages."

TFU DELETE Xfile Xfile ...

      This command deletes the given file(s).

TFU RENAME Xfile ← Xfile

      This command renames a file.

TFU DIRECTORY [Xfile]

      This command lists the directory of the default Trident  drive on
      the file Xfile; if Xfile is omitted, each entry will be  shown on
      the display.   A somewhat  more verbose  listing can  be obtained
      with TFU DIR/V.

TFU ADDRESS Xfile

      This command reads the entire file and displays a list (in octal)
      of virtual disk addresses of the file pages.

TFU CONVERT

      An incompatible change in  the format of DiskDescriptor  was made
      in the Tfs  release of July 24,  1977.  The current  Tfs software
      will refuse  to access  Trident disks written  in the  old format
      (specifically,  TFSInit  will  return  zero).   The  TFU  CONVERT
      command  reformats  the  DiskDescriptor  to  conform  to  current
      conventions (it is a no-op if applied to a disk that  has already
      been converted).  Once you have converted all your Trident disks,
      you should take care to  get rid of all programs loaded  with the
      old  Tfs,  since   the  old  Tfs   did  NOT  check   for  version
      compatibility.

TFU EXERCISE passes drive drive drive ...

      This command  embarks on  a lengthy  "exercise" procedure;  it is
      repeated 'passes'  times (default=10), and  uses the  disk drives
      listed after 'passes' (if none are specified, all drives that are
      on-line  are used).   It  operates by  making a  series  of files
      (test.001,  test.002  etc.)  on the  disk  packs,  and performing
      various  copying, deleting,  writing and  positioning operations.
      The  files are  deleted when  the exercise  finishes.  It  is not
      essential that the packs be fully erased initially; the procedure
      for building test files will try to fill up the disk,  just short
      of overflowing.   Each pass  of the  test takes  approximately 20
      minutes per T-80,  60 minutes per T-300,  and 10 minutes  per SA-
      4008.

      One or  more of  the following global  switches may  be specified
      (i.e., a command of the form TFU/switch EXER...):


Trident disk software        June 14, 1980                            9




      /W  Use a systematic data pattern when writing files, rather than
          arbitrary garbage.

      /C  Carefully check  the data  read from  the disk  (implies /W).
          Use of  this switch  makes the  test run  considerably slower
          than normal.

      /D  Leave  the display  on during  Trident disk  transfers.  This
          causes data  late errors to  occur and thereby  exercises the
          error recovery  logic.  (It  also slows down  the test  by at
          least a factor of 10.)

      /E  Turn  the Ethernet  on  during Trident  disk  transfers, with
          results similar to /D.



4. The Tfs software package in more detail


If programmers wish to interface  the the Trident disk at  levels lower
than Operating System streams,  the Tfs package provides  an additional
interface.   The  "disk" object  created  by TFSInit  has  a  number of
abstract operations  defined on it,  which the Tfs  package implements.
Documentation for these operations  can be found in the  Alto Operating
System Manual in  the section labeled "Disks  and Bfs." The  catalog of
available procedures is:

In TfsBase.Br and TfsA.Br:
        ActOnDiskPages(disk, CAs, DAs, ....)
        RealDiskDA(disk, vda, ....)
        VirtualDiskDA(disk, ....)
        InitializeDiskCBZ(disk, cbz, ...)
        DoDiskCommand(disk, cb, ...)
        GetDiskCb(disk, cbz, ...)

In TfsWrite.Br:
        WriteDiskPages(disk, CAs, DAs, ....)
        AssignDiskPage(disk, vda)*

In TfsCreate.Br
        CreateDiskFile(disk, name, ....)*
        DeleteDiskPages(disk, CA, ....)*
        ReleaseDiskPage(disk, vda)*

In TfsClose.Br
        CloseDisk(disk, dontFree)


The items with *'s following may be invoked only if the disk object was
created with the 'allocate'  argument set to true.   WriteDiskPages may
be invoked even if 'allocate' is false, provided it never allocates new
disk space.  It should be noted that the standard Alto  Streams package
invokes WriteDiskPages even for files opened for reading only, and that
TFSInit  uses  Streams to  read  in the  DiskDescriptor.   Hence  it is
necessary  that  all  of  the  Tfs  modules  (TfsBase,  TfsA, TfsWrite,
TfsCreate,  and  TfsDDMgr)  be  loaded  in  order  to  avoid  undefined
'external' references.  However, after initialization is  complete, the
space occupied by TfsCreate and TfsDDMgr may be reclaimed if you do not


Trident disk software        June 14, 1980                           10




intend to allocate  or delete pages, and  TfsWrite may be  discarded if
you  are  not  using  streams  but  rather  are  calling ActOnDiskPages
directly.

The TfsWrite  and TfsCreate modules  require that TfsDDMgr.Br  (or some
equivalent) be  loaded.  This module  provides the  standard primitives
necessary for managing the  DiskDescriptor.  The DDMgr is  an 'object',
so  it may  be replaced  by  one of  your own  devising so  long  as it
provides equivalent operations.  An example of this would be  to manage
pages of the  DiskDescriptor as part of  a more general  virtual memory
mechanism (perhaps through use  of the Alto VMem package).   A complete
description of the required  DDMgr operations may be found  as comments
at the beginning of TfsDDMgr.Bcpl.

In addition to the  standard "actions" defined in Disks.d,  Tfs permits
the following.  These  actions are defined  in Tfs.d and  are available
only on Trident disks.

        DCreadLnD   Read header, read label, no data.

        DCreadnD    Check header, check label, no data.

        DCwriteLnD  Check header, write label, no data.

These actions neither read nor  write the data record and  therefore do
not require a buffer to be provided.

CreateDiskFile has a special feature for operating the Trident disks --
an optional seventh argument.   If this argument (pageBuf)  is present,
it is  assumed to  point to  a 1024-word  buffer that  will be  used to
create the leader page for the file.  This feature may be used  to save
stack space in  CreateDisk file and/or  to write interesting  data into
the portion of the  leader page not used  by the file system  (only the
first  256 words  are used  by the  file system;  the remainder  has no
standard interpretation).

VirtualDiskDA returns fillInDA as  the virtual address for a  real disk
address that  is either  illegal or  outside the  confines of  the file
system.

The procedures for creating and destroying the disk object, TFSInit and
TFSClose,      were      explained      above.       The      procedure
TFSWriteDiskDescriptor(disk)  will write  out onto  the disk  all vital
information about the disk that  is presently saved in memory.   If you
write programs that run the disk for extremely long periods of time, it
is wise to write the disk descriptor occasionally.  The  only automatic
call on TFSWriteDiskDescriptor is performed by TFSClose.

TfsInit.Br  contains a  procedure TFSDiskModel(disk)  that  returns the
model number of the drive referenced by the disk handle (80 = T-80, 300
= T-300, 4004 = SA-4004,  4008 = SA-4008).  This is useful  in deciding
whether to open a second or third file system on a T-300.

A   lower   level   of   access   is   permitted   with   the  routines
InitializeDiskCBZ, GetDiskCb, and  DoDiskCommand, analogous to  the Bfs
routines  described in  the Operating  System Manual.   Users  of these
routines may  wish to  retrieve source  files for  the Tfs  package and
examine the definitions in Tfs.D and the actual disk operation  in some
detail. Sources are on TfsSources.Dm.


Trident disk software        June 14, 1980                           11




4.1. TFSNewDisk

The  TFSNewDisk procedure,  defined in  TfsNewDisk.Br, "erases"  a disk
(formatting it  and making  all its  pages appear  free) and  creates a
virgin Alto file system (SysDir and DiskDescriptor).  It is called by:

        success = TFSNewDisk(zone, driveNumber [0], diskSize [default],
ddVDA [diskSize/2])

The zone passed to TFSNewDisk  must be capable of supplying  about 3500
words of storage.  If the drive is a T-300, the driveNumber may include
a file  system number (0  to 2) in  its left byte,  as is the  case for
TFSInit.   The diskSize  argument is  the number  of disk  pages  to be
included in the file system; it defaults to the maximum possible, which
is all of any disk besides a  T-300 or a little less than half of  a T-
300.   ddVDA  is  the  virtual disk  address  at  which  to  locate the
DiskDescriptor file; see the TFU ERASE command for elaboration on this.

TFSNewDisk returns true if successful.


4.2. DiskFindHole

The procedure DiskFindHole, in DiskFindHole.Br, can be used to locate a
"hole" of available space in the disk bit table.  The call:

        virtualDA = DiskFindHole(disk, nPages)

will attempt to locate a contiguous hole nPages long.  If it fails, the
procedure returns -1, otherwise  the virtual disk address of  the first
page of the hole.

In order to create a  contiguous file, it is first necessary  to create
the minimal file with a leader page at the given disk address  and then
to use Operating  System or Tfs routines  to extend the  file properly.
The first step is achieved by calling

ReleaseDiskPage(disk, AssignDiskPage(disk, vda-1))

where 'vda' is the desired  disk address (i.e., the result  returned by
DiskFindHole).  This  value will  control the  selection of  an initial
disk address for the leader page.  Once the file is created, it is wise
to extend it to its final length immediately, as other disk allocations
might encroach on the "hole" that was located.

For example, if we are using the Operating System, we might  proceed as
follows:

        let nPages=433          //Number of data pages needed.
        let vda=DiskFindHole(disk, nPages+2)
                                //(+2= 1 for leader, 1 for last page)
        test vda eq -1
                ifso Ws("Cannot find a hole big enough") ]
                ifnot ReleaseDiskPage(disk, AssignDiskPage(disk,vda-1))

        let s=OpenFile("New.Contiguous",ksTypeWriteOnly,0,verNew,0,0,0,
                        TFSzone, 0, disk)
        PositionPage(s, nPages) //Make the file the right length
        Closes(s)


Trident disk software        June 14, 1980                           12




5. File structure on the Trident disk


The  file structure  built on  the Trident  disk by  Tfs  (Trident File
System) is as exact a copy of the Alto file structure built  Bfs (Basic
File System)  as is  possible.  Certain exceptions  are present  due to
hardware  and  microcode   differences.   The  Alto   Operating  System
Reference Manual should be consulted for all file formats  and internal
information not presented here.


5.1. Disk Format

The Trident or Shugart disk drives are set up to run with the following
parameters:

        Disk            Cylinders Heads     Sectors
        T-80            815       5         9
        T-300           815       19        9
        SA-4004         202       4         8
        SA-4008         202       8         8

TFU CERTIFY  will format each  sector of the  disk in the  standard Tfs
format:

        header words per sector:        2
        label words per sector:         10
        data words per sector:          1024

Thus, for  example, a T-80  disk will have  9*5*815 = 36,675  sectors =
37,555,200 words.  Sector 0 will not be used by Tfs.  All but  sector 0
will be available to the file system.

Ordinarily, Tfs utilizes only the first 383 cylinders (= 65,493 sectors
= 67,064,032  words) of  a T-300  disk.  This  is the  largest integral
number of cylinders that can  be addressed using a 16-bit  virtual disk
address.  The 16-bit virtual  address limitation is deeply  embedded in
all existing  higher-level Alto file  system software, so  changing the
Tfs  interface  to  permit  a larger  virtual  address  space  would be
impractical.

Instead, Tfs permits one  to obtain another, entirely  independent disk
object  for referencing  the second  383 cylinders  of the  same T-300,
thereby  permitting  a  separate,  self-contained  file  system  to  be
constructed.  This is  done by passing  a '1' in  the left byte  of the
'driveNumber' argument to TFSInit or TFSNewDisk (that is,  drive '#400'
refers to the second file system  on a T-300 pack mounted on  drive 0).
A  third  file  system   (number  '2',  drive  '#1000')  may   also  be
constructed, but it  contains only 49 cylinders  (= 8379 pages,  only 6
percent of  the disk's  total capacity),  so doing  so is  probably not
worthwhile.


5.2. Disk Header and Label

On the  Trident, a  real disk  address requires  two words  to express,
rather  than  the  single  word  on  the  Diablo  31.   Also, microcode
considerations gave rise to a  reordering of the entries in  the Label.
The result is that both the header and label formats are  different for


Trident disk software        June 14, 1980                           13




the Trident.   The Trident  format follows.  If  you are  interested in
this level  of detail, the  file Tfs.d (contained  within Tfs.dm)
should be consulted.

        // disk header
        structure DH:
                [
                track word
                head byte
                sector byte
                ]

        // disk label
        structure DL:
                [
                fileid word lFID
                packID word
                numChars word
                pageNumber word
                previous @DH
                next @DH
                ]
                manifest lDL = size DL/16


5.3. Disk Descriptor

Every valid Tfs disk has on  it two files which must contain  the state
information necessary  to maintain  the integrity  of the  file system.
The Tfs system directory, "SysDir.", is identical in format and purpose
with  its  Bfs  counterpart.  However  the  Tfs  disk  descriptor file,
"DiskDescriptor.", while identical in purpose, is formatted differently
to allow easy  manipulation of the bit  table (which, for  the Trident,
has  to be  paged in  and out  of memory).   This difference  in format
should not be evident to even low-level Trident users (unless you write
your own DDMgr), but is mentioned here for completeness.


5.4. Bad Page Table

Tfs  and  Tfu  observe  the standard  Alto  file  system  convention of
recording -2's in the labels of all known bad pages.  However,  if this
were the only location of such information, "erasing" a disk (to create
a virgin file  system) would require two  passes over the  entire disk:
one to collect the addresses of all known bad pages and one to mark all
remaining pages  deleted.  This  would require  an excessive  amount of
time, particularly on a T-300.

A duplicate table of known bad pages is therefore recorded  on physical
page zero (= cylinder 0, head  0, sector 0) of the disk.  This  page is
not available to  the file system for  other reasons having to  do with
end-of-file detection.   The format of  the table is  given by  the BPL
structure, which is defined in  Tfs.d.  Note that the entries  are REAL
disk  addresses  and  can  therefore refer  to  any  page  on  the disk
regardless of whether or not such a page is accessible through the file
system.  (A  T-300 has  only one bad  page table,  even if  it contains
several file systems.)

The  TFU  CERTIFY  command  is responsible  for  testing  the  pack and


Trident disk software        June 14, 1980                           14




building the bad page  table.  The TFSNewDisk procedure (called  by TFU
ERASE)  is  careful  not  to clobber  this  information  but  rather to
propagate it to the other  places where it is needed (namely,  the disk
bit table and  the labels of the  bad pages themselves).  As  a result,
the bad  page information,  once initialized,  will survive  across all
normal operations on the disk, including "erase" operations.

There does not presently  exist any facility for manually  appending to
this list when new bad  pages are discovered.  Experience to  date with
the Trident disks (which provide  correction for error bursts of  up to
11  bits in  length) has  shown that  such a  facility is  probably not
needed.  Thorough testing of  disks (using TFU CERTIFY)  is recommended
before putting them into regular use, however.



6. Revision History


July 24, 1977

Incompatibilities:

The format of  DiskDescriptor has changed.   The new Tfs  cannot access
old disks or vice versa.  See description under "TFU CONVERT".

There  is  now  another  file,  TfsA.Br,  that  is  logically  part  of
TfsBase.Br and  must be  loaded along with  it.  It  contains assembly-
language code formerly included as "tables" in TfsBase.Br.

New Features:

Partial support for T-300 disks.

Conforms  to new  conventions for  maintaining addresses  of  known bad
pages.

TFSInit checks for valid SysDir leader page and DiskDescriptor version.

Count of bit table  discrepancies added to DiskDescriptor.   (These are
pages falsely claimed to be free in the bit table.)

VirtualDiskDA returns fillInDA for illegal real disk addresses.

Additional Trident-specific disk actions.

Tfs is now entirely reentrant,  so it is safe for the  Idle() procedure
to give control to another process that in turn calls Tfs procedures.

October 21, 1977

Incompatibilities:

The former TfsWrite module has been broken into four  pieces: TfsWrite,
TfsCreate, TfsClose, and TfsDDMgr.  In most applications, all four must
be loaded.

The  'sharedBT' argument  to  TFSInit has  been replaced  by  a 'ddMgr'
argument.  The mechanism for sharing a bit table buffer  among multiple


Trident disk software        June 14, 1980                           15




drives has  been entirely changed.   (Programs that omit  this argument
are unaffected by the change.)

The  TFSCreateVDA static  has  been removed.   In  its place  is  a new
procedure TFSSetStartingVDA(disk, vda) that serves the same purpose.

The syntax  of the TFU  EXERCISE command has  been changed.  It  is now
'TFU EXERCISE  ', and  defaults
to all drives that are on-line.

New features:

Complete  support  for  T-300 disks.   In  conjunction  with  this, the
TFSDiskModel procedure has been added.

It is now  possible for DiskDescriptor  pages to be  managed externally
(perhaps through  some sort of  virtual memory mechanism)  by use  of a
user-defined 'DiskDescriptor Manager' object.

TFSSilentBoot procedure added.

November 9, 1977

Incompatibilities: None.

New features:

TFU CERTIFY and TFU  BADSPOTS commands added.  TFU  CERTIFY initializes
the headers on a virgin disk pack and then runs repeated tests over the
entire pack, permanently recording  any bad spots that it  finds.  This
command  replaces   all  the   normal  uses   of  the   Triex  program,
documentation for which has been removed.

Microcode modified  for more  efficient reading  on Alto-IIs  (by about
25%).

February 26, 1978

Incompatibilities: Software updated to new time standard; will  not run
under OS versions earlier than 14.

New  features:  Microcode  source  now  in  two  parts,  to  facilitate
combining it with other microprograms.

December 15, 1978

Incompatibilities:  some  of  the TFS  DDMgr  procedures  renamed (used
internally).

New  features: returnIfNoCb  argument  to TFSGetCb;  ddVDA  argument to
TFSNewDisk; TFU ERASE/B option to maximize contiguous free storage; TFU
RESETBADSPOTS command added; TFS and TFU should run on Dorado.

June 25, 1979

Incompatibilities: none.

Changes:  Optional  "hintLastPage"  argument  added  to ActOnDiskPages,
WriteDiskPages, and DeleteDiskPages; several minor bugs fixed.


Trident disk software        June 14, 1980                           16




July 17, 1979

Incompatibilities:  The structure  of a  DSK (and  therefore  a TFSDSK)
changed,   so   programs   that  get   "Tfs.d"   must   be  recompiled;
TFSSetStartingVDA(disk,    vda)    procedure    removed--instead    use
ReleaseDiskPage(disk, AssignDiskPage(disk, vda-1)).

Changes: New operations InitializeDiskCBZ, DoDiskCommand, and GetDiskCb
added to the DSK  object in preparation for  OS 17.  Note that  the new
TFS will work under  earlier versions of the  OS, but the old  TFS will
not work under OS 17.

November 24, 1979

Incompatibilities: The manner  in which the  TFS turns the  display off
and on has been changed so  that it works correctly even if  the caller
accesses the  disk at  the DoDiskCommand/GetDiskCb  level, and  even if
there are multiple contexts making calls to the TFS.  Existing software
that uses the low-level procedures may require modification.

The microcode has  been modified, so  recompilation is required  of any
microprograms that include TriConMc.mu or TriConBody.mu as a component.
(The  interface  to the  microcode  has changed  slightly;  consult the
revised documentation in AltoTrident.press.)

Changes:  This  release  includes  some  substantial  changes  in error
recovery at both the microcode and the software level.   Formerly there
were  problems that  could  cause the  software  to get  hung  up under
extreme conditions such as operating the disk with the display on.

Unrecoverable  disk  errors   are  now  reported  with   more  complete
information.  (This requires new versions of Swat and Sys.errors, being
released simultaneously.) Additionally, if the currently-selected drive
goes   not-ready,  TFS   generates   an  error   rather   than  hanging
indefinitely.  Finally, attempting to write on a read-only  drive gives
rise to a distinct error.

TFU has been cleaned up somewhat.  It always generates a  typescript in
file TFU.log  (this replaces the  former TFU.ExerciseLog).   Disk drive
names are  now standardized: TP0  for Trident drive  0, DP0  for Diablo
drive 0.  TFU DELETE  can take multiple arguments.  TFU  RENAME command
has been added.

June 14, 1980

Incompatibilities: none.

Changes: The software  is now capable  of dealing with  Shugart SA-4004
and SA-4008 disk drives, interfaced through a Shugart  controller card.
The TFSDiskModel procedure has been changed appropriately.

Note: This  version of  the software must  be compiled  with the  OS 18
system definitions files (Disks.d, etc.), but may be operated  under OS
releases as old as OS 16.