Harston Advanced Disk Filing System
for Version 0.32
The HADFS is a full hierarchial filing system similar to the NFS and
ADFS systems. It runs on any 6502 based BBC computer, with any disk
hardware. It is independent of the hardware configuration, adapting
its operation to different requirements. HADFS formatted disks
contain the Rom image for the system, allowing it to be easily
distributed. The only requirements needed are a DFS (any sort) that
supports Osword &7F to read and write sectors of the disk, and 16k of
sideways ram. As an alternative to the sideways ram, the Rom image
can be blown into an Eprom and permanently installed in the machine.
HADFS was written and is under continuing revision by:
70 Camm Street
and remains wholly copyrighted, (C) 1990. The program is Public
Domain, and can be freely distibuted, as long as the code is not
modified, and all copyright and authorship messages remain, and no
charge is charged, other than legitimate disk purchase and copying
costs. Ownership can be registered by writing to the above address,
enclosing 10. This entitles you to a full printed reference manual
and to immediate code updates. You are under no obligation to
register, and you can probably manage with the manual contained in
Within this text, the following terms are used:
'press' means press, ie put your finger on the key, push down, and
then release, as in: 'Press "X"' 'type' means a succession of
'press'es, ie pressing each individual key, as in: 'Type "fred"'. It
does not mean press Return at the end. 'enter' means 'type', and then
'press' the Return key, ie enter in something, as in: 'Enter the
'Return' refers to the key labelled 'RETURN' (or sometimes 'ENTER').
'Shift' refers to the key labelled 'SHIFT' 'Ctrl' refers to the key
labelled 'CTRL', and is called the control key. 'Delete' refers to
the key labelled 'DELETE'
'Break' refers to the Break key. 'Shift-Break' means press the Break
key while holding down the Shift key. The Shift key on its own does
not do anything, so don't be afraid to hold it down longer than
neccessary. In fact, this is to be recommended. 'Ctrl-Break' means
press the Break key while holding down the Ctrl key, similar to above.
There are two types of HADFS disk. These are an HADFS data disk,
which just contains data, and an HADFS system disk. An HADFS system
disk contains three things. A DFS !Boot file to bootstrap the HADFS
Rom, the HADFS Rom image, and the HADFS disk data. There is also a
'SPARE' file which is currently unused, but may be used in future
versions. On booting up an HADFS disk for the first time with
Shift-Break (or Shift-D-Break), the HADFS Rom image is loaded in and
the machine is reset again. This only needs to be done if the Rom
image is not present in an Eprom. If it is, then it is already
present at power-on. Unless otherwise stated, the manual will assume
that the Rom image is in the machine, either in sideways ram, or in an
Eprom. If a second processor is attached when loading in the Rom
image, then the message 'Press Break to reset Tube' is given, and the
Break key should be pressed to reset the second processor. There is
no way to universally reset a second processor from software, so you
have to press the Break key yourself. An HADFS data disk does not
have the rom image on, thereby releasing 16k of space for extra files.
In all other respects, HADFS data and system disks are identical.
On power-up, or a simulated power-up caused by *FX151,78,127 followed
by a Break, the authorship and copyright message is displayed. On all
other resets this message is not displayed, so giving the standard
startup display. Once HADFS is in your machine, it can be selected by
*HADFS or by H-Break.
In the following section and in the *HELP messages, the following
abbreviations are used:
<afsp> ambiguous file specifier. A filename that can include
the wildcard characters '#' and '*'.
<fsp> file specifier. A filename that does not include the
wildcard characters '#' and '*'.
<src> source filename/drive.
<dest> destination filename/drive.
<dir> a directory.
<user> a user number.
<drv> a drive number.
Filenames can consist of one to ten alphanumeric characters,
containing no spaces, and none of the following special characters
which are reserved and cannot be used in filenames: ", #, $, %, &, ^,
:, *, . and @. The following characters are valid in filenames and
will be valid in future versions: A-Z, a-z, 0-9, !, _, (, ), ?, +, -.
Any other characters not specifically mentioned in this list may in
future not be recognised.
Pathnames consist of one or more filenames separated by '.',
optionally including the following absolute directory reference
$ root directory, and disk prefix. Identical to ':'.
: root directory, and disk prefix. Identical to '$'.
% library directory (LIB).
& user root directory (URD).
@ currently selected directory (CSD).
^ parent directory.
So the pathname '%.FREDDY' refers to the file 'FREDDY' in the library
directory, and ':1.HELLO' or '$1.HELLO' refers to the file 'HELLO' in
the root directory of drive 1. The '$' and ':' can be used
interchangably. The following wildcard characters are used:
# matches any one character
* maches any characters
*ACCESS <afsp> <access>
This command changes the access string on a file, eg.
*ACCESS MATHS WR/R
Each letter in the access string refers to a different type of access
allowed to the file:
L - Locked => The file cannot be deleted or overwritten or
W - Write => The file can be written to using random access.
R - Read => The file can be read with LOAD, RUN or random
P - Private => The file cannot be seen by non-owners.
E - Execute => The file can be executed with *, */ or *RUN. When
you use this option, the read and write options
are disabled to make the file a run-only file.
Setting the 'R' option allows you the same access as the 'E' option,
but does not make the file run-only. The '/' character separates the
owner's access (on the left) from the public access (on the right).
You are the owner of a file if you own the directory that it is in.
When a disk is *INSTALLed, you own the whole disk. Ownership is
changed using the *SETUSER command, and allows you to segregate files
and simulate an Econet environment using local disk drives. Saving a
file on top of an existing file does not change the file's access
*BACKUP <src> <dest>
This command has not yet been implemented, and you should use the
supplied Basic program 'COPYFILES' or 'TREECOPY' or 'BACKUP' instead.
This closes any open files and dismounts all the disks. You should
always use this (or *MOUNT) before changing a disk.
This command creates a subdirectory. If the specified subdirectory
already exists, then the command returns with no errors. If a file
already exists with the same name then a 'File exists' error will be
generated. The created directory has its access locked.
This command has not yet been implemented, and you should use the
supplied Basic program 'COMPACT' instead.
*COPY <src> <dest>
This command has not yet been implemented, and you should use the
supplied Basic program 'COPYFILES' or 'TREECOPY' instead.
This simply deletes a file from the directory, eg:
If the file is locked, the error 'File locked' is generated. If you
try to delete a directory that has entries in, the error 'Dir. not
empty' is generated. You can only delete files in directories that
This command allows you to move between directories, eg:
The example selects PROGRAMS to be the Currently Selected Directory
(CSD). Doing *DIR with no name will reset the CSD to the User Root
Directory (URD), this usually being '$', or the directory selected
with *I AM. The CSD can be refered to in pathnames with '@', eg:
This command is used to enable the dangerous commands *BACKUP,
*COMPACT and *INSTALL with the '$' parameter. It should be given
before the command is used, eg:
*BACKUP 0 1
If a command is not enabled, then you are asked 'Go? (Y/N)' and a
keypress is waited for. Pressing anything other than 'Y' or 'y' will
result in the command being abandoned, and a 'Not Enabled' error being
This command is similar to doing a *INFO on all the files in the
directory. If no directory is given, the CSD is listed. An example
$ (69) Owner 00
MyDiskOne Option 0 (Off) Dir. $ Lib. $
!ReadMe 67542742 26533684 002DAD WR/R 08/10/89 004A
Manual1 65524372 38573523 001029 WR/R 08/10/89 0078
COMPACT FFFF1900 FFFF8023 00055E LWR/R 17/10/89 00A2
COPYFILES FFFF1900 FFFF8023 000652 LWR/ 18/10/89 00A8
This displays the free space available on the disk, or the disk the
CSD is on if no drive is given. An example would be:
04AD Sectors = 306432 bytes used
0193 Sectors = 103168 bytes free
This displays the file information for a particular file, eg:
produces a string of information about the file MATHS. The format is:
<name> <load address> <execution address> <size> <access> <date -
dd/mm/yy> <system internal name>
For example, the above command may produce the following output:
MATHS FFFF1900 FFFF8023 000734 WR/R 22/05/88 0092
When you do a *INFO on the root directory, you are given information
on that drive, eg:
Drive 0: WordProcessing 06/2/91 Size: 0640 ID: 7632 HADFS 0.27
This gives the disk title, the date is was created, its size and ID
code, and what version of the HADFS rom is installed on it.
*INSTALL (<drv>) ($) (<name>) (D) (<size>)
This very important command creates an HADFS disk, installing on it
the required DFS files to partition it and setting up the root
directory ($). *INSTALL can be used on disks that already have HADFS
installed on them to install the current version of the software, or
to change the disk name. If the disk is not an HADFS one, then a new
root directory is created. If the disk is an HADFS one, and the '$'
parameter is given, then a new root directory is created, effectively
deleting everything on the disk. If no name is given, and a new root
is being created, then the disk title is set to '(UntitledDisk)', else
the supplied name is used. If a new root is to be created, the
command must first be ENABLEd. The disk must already be formatted as
a standard DFS disk, either 40 or 80 track, single or double sided.
HADFS works best with 80 track double sided disks, but you can specify
other size disks with the <size> parameter in either number of tracks
or number of sectors. Recognised values are:
640 or 160 - 80 track, double sided
320 or 80 - 80 track, single sided
190/2 or 40/2 - 40 track, double sided
190 or 40 - 40 track, single sided
You can also specify the size as a the total number of sectors on the
disk by using '=xxxx', where 'xxxx' is the total number, in
hexadecimal. This is especially useful for INSTALLing disks on the
non-floppy drives (2 to 7), or INSTALLing disks with more than 80
tracks. As an example,
*INSTALL 4 $ FRED'S_DISK =0800
would initialise a disk in drive 4 with &800 sectors, and the
*INSTALL 0 $ LargeDisk =0668
would initialise an 82 track disk. If no size is given, then the
default of '160' is used. Using the 'D' parameter makes the disk a
data-only disk, leaving off the DFS installation files, and giving you
a bit of extra space on the disk. You can only use this option when
creating a new disk. You cannot use it to change a system disk to a
data disk, or vis versa! As an example,
*INSTALL 0 $ DataDisk D 40
would install a 40 track disk as a 98.5k HADFS data disk.
Note: there are a couple of non-fatal bug in current version of HADFS.
If the disk title given is exactly 16 characters long, the command
hangs. To get out of that, just press Break. Also, when *INSTALLing
a new disk for the first time, the Rom image is not correctly written.
You can tell this as the disk drive activity is over very quickly. To
solve this, do the *INSTALL command twice.
*I AM <dir>
This command is used to log on to a specified directory on a disk. An
example would be:
*I AM PROGRAMS
which would set the User Root Directory and the CSD to $.PROGRAMS on
drive 0. A directory $.Library is looked for on drive 0 and the
logged on drive if different, and if found, the library directory is
set to it. The autostart command is then executed (see *OPT 4). A
drive other than drive 0 may be logged on by prefixing with a drive
identifier, and subdirectories can be logged on to, eg:
*I AM :1.WORK.SHEETS
would log into the directory WORK.SHEETS on drive 1, and look for a
library directory on drive 1 and drive 0. If the specified directory
cannot be found, then :0.$ is logged into instead.
This sets the library directory to the directory given. The library
directory is where machine code command files are searched for if they
cannot be found in the current directory with * and */. The search
path followed is:
*command */name *RUN name
MOS looks in MOS rom
Look at sideways rom
Look at filing system
----------------- ------- -------
HADFS looks in CSD HADFS looks in CSD
Does filename include
--Yes---- $, %, &, @ or :
HADFS looks in LIB
HADFS looks in &.Library (*)
Master computers check
'Bad command' error 'File not found' error
If a file is found, it is loaded and executed, else the search path
above is followed onwards towards the end. So '*KEY' is matched as
the MOS command to reprogram a function key, '*/KEY' bypasses the MOS
and is sent to HADFS to search for a general command file, and '*RUN
KEY' would look for a machine code file in the current directory only.
After a *MOUNT, the LIB is set to :0.Library if it exists, or to :0.$
if it doesn't. (*) - Searching in &.Library has not yet been
This displays the free space map for the selected drive, or the drive
of the CSD, if none is given.
This abandons any open files and dismounts all the disks preparatary
to inserting a new disk. You should always use this command, or *BYE,
before changing a disk, as directory information is kept in memory to
speed up disk accesses. After a *MOUNT, the CSD and URD are set to
:0.$ and LIB is set to :0.Library if it exists, or :0.$ if is doesn't.
*RENAME <old fsp> <new fsp>
This command has not yet been implemented and will either generate a
'Bad rename' error or a 'File not found' error.
*SETUSER <dir> <user>
This sets the user number of a directory. When a disk is *MOUNTed,
your user number is reset to 0, so to own any directories that have
had the user number changed, you must log into them using *I AM.
This is used to set various file options. These are:
*OPT 0 - This resets OPT1, OPT2 and OPT3 to their default values.
*OPT 1 - Sets level of file information messages given on LOAD and
*OPT 1,0 gives no messages (default)
*OPT 1,1 gives detailed messages
*OPT 2 - Sets the filing system number returned by OSARGS 0,0.
With this you can make HADFS pretend to be a different
filing system, eg setting *OPT 2,5 will make it be
recognised as NFS. Default is 15, and you cannot set to
4, as that is the value of DFS.
*OPT 3 - Sets the additional filing system recognition number. A
filing system can be selected with service call &12, and
HADFS recognises the OSARGS 0,0 number set with *OPT 2 and
the number set with this call.
*OPT 4 - This sets the autostart action as follows:
*OPT 4,0 ignores !BOOT
*OPT 4,1 *LOADs !BOOT
*OPT 4,2 *RUNs !BOOT
*OPT 4,3 *EXECs !BOOT
*OPT 5 Set the max. number of channels used. Default 5.
*OPT 6 Sets the drive 1 status flag. If zero, then
drive 1 is provided by the DFS rom. If
non-zero, then an external routine is used.
*OPT 7 Currently unused.
The *CAT command provides a list (catalogue) of the files in the
selected directory. The files are currently not listed in
alphabetical order, but it is intented that they will be in the
future. The top three lines contain information about the directory
be catalogued. With the example below, the first line shows that the
directory being catalogued is called 'PROGRAMS' and the disk it is on
is called 'MyDiskOne'. The CSD is the root ($) and the library
directory is called 'Library'.
PROGRAMS (33) Owner 00
MyDiskOne Option 0 (Off)
Dir. $ Lib. Library
MATHS WR/R GAMES DL/
STARTUP LR/R START2 R/E
This command, which needs to be *ENABLEd, will format a disk in drive
0 or 1. The number of tracks is specified by nn, this can be from 10
to 255, though sensible values would be 40, 80 and 160. The formatted
disk is a blank data disk with the title '(Untitled)'. The command
can be used without HADFS selected, and if so, the drive parameter can
be 0 to 3 and it will create a blank DFS disk. As an example,
will format a double-sided 80 track disk. Most disks and disk-drives
can actually access about 82 tracks, so you could use
to format a double-sided 82 track disk.
This command selects the HADFS. When selected, the HADFS checks to
see if it can find a DFS which it needs to perform the disk accesses.
If it cannot find a DFS, then the error 'DFS not present' is
generated, after selecting itself. If you use the '#' parameter, then
this checking is missed out, and so no error can be generated. The
(now obsolete) Acorn DFS 0.90 fails to respond to the call used to
check if the DFS is present, and so *HADFS # should be used.
This command completely disables the HADFS rom, in effect unplugging
it. It can be turned back on be a *FX90,6 command or by
Shift-Breaking an HADFS disk.
When files are created, they are date-stamped. On the Master
computers, the date for this is fetched from the on-board Real-Time
Clock. The pre-Master BBCs, however, do not have this feature, and so
using this command simulates the date part of it. After using the
*HSETDATE command, you can read the date using the OSWORD 14 call, as
on the Master. If there is an on-board Real-Time Clock, this will
take precedence to the date set with *HSETDATE as long as the code to
access it is in a higher priority rom than the HADFS. Using *HSETDATE
with no date disables the function.