BBC Micro Acorn DFS floppy disk image maintenance utility
This package contains a command-line utility and a Python module dedicated for maintenance of BBC Micro disk image files. Those files usually have extensions .ssd - for single sided disk image, or .dsd - for double sided disk image.
This package allows indexing contents of the disk images, importing files to and exporting from the disk images, modifying disk images in place, such as renaming files or changing disk title and transferring data between disk images.
The dfsimage
module also supports MMB files. MMB files are containers for
large number of .ssd disk images, designed for storing disk images on a
MMC or SD card. All commands that work with .ssd FILES can be also used on a disk
image contained within an MMB file. Index of a disk image within an MMB file can be
either specified using index option, or appended to the MMB file name, following
a colon character, e.g. beeb.mmb:12
. Commands list
, dump
and digest
can
take a range of disk images, e.g. beeb.mmb:10-20
or an entire MMB file. In that
case command will be applied to all initialized disk image in the specified range.
There are few commands intended specially for MMB files, such as donboot
or
drecat
.
dfsimage COMMAND IMAGE [options]...
dfsimage --help [COMMAND]
dfsimage --help-options
dfsimage --help-format
examples:
Index all floppy images with contents from the 'images' directory to 'index.json' file
dfsimage index -f json images/*.ssd images/*.dsd > index.json
Covert a linear double sided image to a '.dsd' file
dfsimage convert --from -D -L linear.img --to inter.dsd
Import all files from the 'files' directory to a new image 'games.ssd'
dfsimage import --new games.ssd --title="GAMES" files/*
Export all files from the disk image at index 12 in 'beeb.mmb' file to the 'files' directory
dfsimage export beeb.mmb:12 -o files/
Index all floppy image contents from the 'images' directory to text table file
dfsimage index --only-files -f table images/*.ssd images/*.dsd > files.csv
At this point the package is not yet available in the PyPI repository, so it has to be build and installed manually:
Make sure that pip and dependencies are installed. If you are running Debian, Ubuntu or derived Linux distribution, install the python3-pip package like this.
~$ sudo apt-get install python3-pip
Upgrade pip to latest version.
~$ python -m pip install --upgrade pip
Clone the repository
~/src$ git clone https://github.com/monkeyman79/dfsimage.git
~/src$ cd dfsimage
Build and install package
~/src/dfsimage$ python -m pip install .
Before installing this package on a Windows machine, make sure that both Python and Git are installed on your system.
- Python can be downloaded from here: https://www.python.org/downloads/
- Git for Windows can be downloaded from here: https://gitforwindows.org/
Make sure to add both Python and Git to your PATH when asked by the installer.
Execute steps below in either Command Prompt or Windows PowerShell.
PS C:\Users\you> mkdir Documents\src
PS C:\Users\you> cd Documents\src
PS C:\Users\you\Documents\src> git clone "https://github.com/monkeyman79/dfsimage.git"
PS C:\Users\you\Documents\src> cd dfsimage
PS C:\Users\you\Documents\src\dfsimage> python -m pip install --user .
During installation, you may see the following warning message:
WARNING: The script dfsimage.exe is installed in
'C:\Users\you\AppData\Local\Packages\...\Scripts'
which is not on PATH.Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
This means that the 'dfsimage'
command will not be directly available. There are two options here:
- Always execute dfsimage via
python -m dfsimage COMMAND...
- Add the Scripts directory to your PATH variable
Adding Scripts directory to your PATH variable
We can combine powers of Python and PowerShell to automatically add your local Scripts directory to PATH. Execute the steps below in the Windows PowerShell:
PS C:\Users\you> $USER_SITE = python -m site --user-site
PS C:\Users\you> $USER_SCRIPTS = (Get-ChildItem (Split-Path -Path $USER_SITE -Parent) Scripts).FullName
PS C:\Users\you> [Environment]::SetEnvironmentVariable("PATH",
>> [Environment]::GetEnvironmentVariable("PATH", "User") + ";$USER_SCRIPTS", "User")
Now close your console window and open it again to make the change take effect.
list
(cat
,index
)- List files or disk image properties.
create
(modify
)- Create new floppy disk image or modify existing image.
backup
(convert
,copy-disk
)- Copy (and convert) image or one floppy side of image.
import
- Import files to floppy image.
export
- Export files from floppy image.
dump
(read
)- Dump file or sectors contents
build
(write
)- Write to file or sectors.
copy-over
- Copy files from one image to another.
format
- Format disk image removing all files.
copy
- Copy single file.
rename
- Rename single file.
delete
- Delete single file.
destroy
- Delete multiple files.
lock
- Lock files.
unlock
- Unlock files.
attrib
- Change existing file attributes.
digest
- Display digest (hash) of file or sectors contents
validate
- Check disk for errors.
create-mmb
- Create a new MMB file.
dkill
- Mark disk image as uninitialized in the MMB index.
drestore
- Restore disk image marked previously as uninitialized.
drecat
- Refresh image titles in MMB file catalog.
donboot
- Display or set images mounted in drives on boot.
--warn={none,first,all}
Validation warnings display mode. (default: first)
none
- Don't display validation warnings.first
- Display first warning and skip further validationall
- Display all validation warning. Some warnings may be redundant.
-v, --verbose
- Verbose mode - list copied files.
-q, --quiet
- Quiet mode - don't report successful operations.
-s, --silent
- Don't generate error if a file doesn't exist.
--continue, --no-continue
- Continue on non-fatal errors. (default: True)
-p, --pattern=PATTERN
File name or pattern. The fnmatch function is used for pattern matching. If the directory-matching part (e.g.
'?.'
) is not present in the pattern, only files in the default directory are matched.- pattern
'*'
matches any string, - pattern
'?'
matches any single character, - pattern
'[seq]'
matches any character in seq, - pattern
'[!seq]'
matches any character not in seq.
- pattern
--inf={always,auto,never}
Use of inf files.
always
- always create .inf files, fail import if inf file doesn't exist.auto
- create .inf file if either load or exec address is not 0, file is locked or filename cannot be directly translated to OS filename.never
- never create .inf files and ignore existing inf files on import.
--replace, --no-replace
Allow replacing existing files. (default: False)
--ignore-access, --no-ignore-access
Allow deleting or replacing locked files. (default: False)
Commands: import, build, copy-over, copy, rename, delete, destroy
--preserve-attr, --no-preserve-attr
Preserve
'locked'
attribute on copying. (default: False)
-f, --format={raw,ascii,hex}
Data format. (default: raw)
raw
- read or write raw bytes.text
- convert line endings to and from BBC's'\r'
ascii
- escape all non-readable or non-ascii characters.hex
- hexadecimal dump.
--sector=[TRACK/]SECTOR[-[TRACK/]SECTOR]
Process sectors instead of files. Argument can be a range of sectors, with start and end separated by a dash. Physical sector address format is
'track/sector'
.
--track=TRACK[-TRACK]
Process tracks instead of files. Argument can be a range of tracks, with start and end separated by a dash.
--title=TITLE
- Set disk title.
--new-title=TITLE
- Set disk title for newly created disk images.
--bootopt={off,LOAD,RUN,EXEC}
Set disk boot option.
- off - No action.
- LOAD - Execute
*LOAD $.!BOOT
command. - RUN - Execute
*RUN $.!BOOT
command. - EXEC - Execute
*EXEC $.!BOOT
command.
--sequence=SEQUENCE
- Set catalog sequence number. Sequence number is a Binary Coded Decimal value incremented by the Disk Filing System each time the disk catalog is modified.
--compact, --no-compact
- Coalesce fragmented free space on disk. Default is to compact disk if needed to make space for new file.
--shrink
- Shrink disk image file to minimum size by trimming unused sectors. Such image files are smaller, but cannot be memory-mapped and may have to be resized in flight by tools.
--expand
- Expand disk image file to maximum size.
--dlock
- Set disk image locked flag in MMB index.
--dunlock
- Reset disk image locked flag in MMB index.
Image file options apply to the first following disk image file. Those options must be specified before the corresponding image file name.
--new
- Create new image file. Fail if file already exists.
--existing
- Open existing image. Fail if file doesn't exist.
--always
- Create new image or open existing image,. This is the default.
-4, -8, --tracks={80,40}
- Select between 80 and 40 track disks. Default for existing disk images is try to determine current disk format based on the image file size. Default for new disk images is 80 tracks.
-S, -D, --sides={1,2}
- Select between single and double sided disk images. Default is to try to
determine number of sides from disk extension and size: files with extension
.dsd
are open as double sided, other files are open as double sided based on their size. Default for new images is two sides for images with.dsd
extension and one side for all other. -I, -L, --interleaved, --linear
- Select double sided disk data layout between interleaved and linear. The
interleaved format is more common and more widely supported. In the
interleaved format, track data of each floppy side is interleaved - side 1
track 1, side 2 track 1, side 1 track 2 etc... Image files with extension
.dsd
are normally interleaved. Double sided image files with extension.ssd
are normally linear (in this cases
stands for "sequential"). Double sided.ssd
are distinguished from single sided by file size. For the theoretical 40 tracks, double sided.ssd
files, you would have to manually specify-40
,-D
and--linear
, because they cannot be reliably distinguished from 80 track single sided disk images. -1, -2, --side={1,2}
- Select disk side for double sided disks.
-i, --index=INDEX
- Select image index for MMB files. In case of double sided disks, index
0
selects first side and index1
selects second side. Alternatively index can be appended to the image file name separated by colon. For examplemy_disk.dsd:1
orbeeb.mmb:253
. -d, --directory=DIRECTORY
- Default DFS directory.
File options apply to the first following file name. Those options override values read from the inf file.
--load-address=ADDRESS
- Load address for the following file. Must be a hexadecimal number.
--exec-address=ADDRESS
- Exec address for the following file. Must be a hexadecimal number.
--locked, --no-locked
- Set locked attribute.
--dfs-name=NAME
- DFS name for the imported file.
List files or disk image properties.
synopsis:
dfsimage list [global options] [listing options] ([image file options] IMAGE)... dfsimage cat [global options] [listing options] ([image file options] IMAGE)... dfsimage index [global options] [listing options] ([image file options] IMAGE)...
examples:
dfsimage cat image.ssd
dfsimage list --image-header="Image {filename}" --header="Side {side}" --list-format="{fullname:12} {sha1}" img/*.dsd
dfsimage index -f json images/*.ssd images/*.dsd > index.json
listing options:
-f, --list-format={cat,info,raw,inf,json,xml,table,CUSTOM_FORMAT}
Listing format. (default:
cat
)raw
- List file namesinfo
- As displayed by*INFO
commandinf
- Format of.inf
filescat
- As displayed by*CAT
commandjson
- JSONxml
- XMLdcat
- As displayed by MMC*DCAT
commandtable
- Text table. Columns are separated with'|'
character.- CUSTOM_FORMAT - Formatting string - e.g.
"{fullname:9} {size:06}"
.
See file properties for list of keyword available for custom format.
--sort, --no-sort
- Sort files by name.
--header-format={cat,table,CUSTOM_FORMAT}
Listing header format. (default: based of list format)
cat
- As displayed by*CAT
command.table
- text table- CUSTOM_FORMAT - Formatting string - e.g.
"{title:12} {side}"
.
See disk side properties for list of keywords available for custom format.
--footer-format=CUSTOM_FORMAT
- Listing footer format. See disk side properties for list of keywords available for custom format.
--image-header-format=CUSTOM_FORMAT
Listing header common for entire image file.
- CUSTOM_FORMAT - Formatting string - e.g.
"{basename} {tracks}"
.
See image file properties for list of keywords available for custom format.
- CUSTOM_FORMAT - Formatting string - e.g.
--image-footer-format=CUSTOM_FORMAT
- Image Listing footer format. See image file properties for list of keywords available for custom format.
--only-files
- Include only files in listing - useful mainly for JSON, XML and table format
--only-sides
- Include only disk sides in listing - useful mainly for JSON, XML and table format
--only-images
- Include only disk images in listing - useful mainly for JSON, XML and table format
Create new floppy disk image or modify existing image.
synopsis:
dfsimage create [global options] [image modify options] [image file options] IMAGE dfsimage modify [global options] [image modify options] [image file options] IMAGE
examples:
dfsimage create --new -D -L --title=Side1 --title=Side2 linear.img
dfsimage modify --existing image.ssd --bootopt=EXEC
Copy (and convert) image or one floppy side of image.
synopsis:
dfsimage backup [global options] [image modify options] --from [image file options] FROM_IMAGE --to [image file options] TO_IMAGE dfsimage convert [global options] [image modify options] --from [image file options] FROM_IMAGE --to [image file options] TO_IMAGE dfsimage copy-disk [global options] [image modify options] --from [image file options] FROM_IMAGE --to [image file options] TO_IMAGE
examples:
dfsimage convert --from -D -L linear.img --to inter.dsd
dfsimage backup --from -2 dual.dsd --to side2.ssd
dfsimage copy-disk --from beeb.mmc:123 --to my_disk.ssd
Import files to floppy image.
synopsis:
dfsimage import [global options] [import options] [image modify options] [image file options] IMAGE ([file options] FILE)...
examples:
dfsimage import --new games.ssd --title="GAMES" files/*
dfsimage import floppy.dsd --replace --ignore-access --load-addr=FF1900 --exec-addr=FF8023 --locked --dfs-name=':2.$.MY_PROG' my_prog.bin
import options:
--ignore-access, --no-ignore-access
Export files from floppy image.
synopsis:
dfsimage export [global options] [export options] -o OUTPUT ([image file options] IMAGE)...
examples:
dfsimage export floppy.ssd -o floppy/ -p 'A.*'
dfsimage export img/*.dsd --create-dir -o 'output/{image_basename}/{drive}.{fullname}'
required arguments:
-o, --output=OUTPUT
- Output directory or file name formatting string for export. Directory name must be terminated with path separator. See file properties for list of keyword available for formatting string.
export options:
--create-dir, --no-create-dir
- Create output directories as needed. (default: False)
--translation={standard,safe}
Mode for translating dfs filename to host filename characters. (default: standard)
standard
- replaces characters illegal on Windows with underscores.safe
- replaces all characters, other than digits and letters with underscores.
--include-drive-name
- Include drive name (i.e. :0. or :2.) in inf files created from double sided floppy images. The resulting inf files will be incompatible with most software. Use this option carefully.
Dump file or sectors contents.
synopsis:
dfsimage dump [global options] [dump options] [image file options] IMAGE FILE... dfsimage read [global options] [dump options] [image file options] IMAGE FILE...
examples:
dfsimage dump image.ssd -f hex MY_PROG
dfsimage dump image.ssd -f raw --sector=0-1 > cat-sectors.bin
dump options:
--ellipsis, --no-ellipsis
- Skip repeating lines in the hex dump. (default: True)
--width=WIDTH
- Bytes per line in the hex dump.
--sector=[TRACK/]SECTOR[-[TRACK/]SECTOR]
Write data to file or sectors.
synopsis:
dfsimage build [global options] [build options] [image modify options] [image file options] IMAGE ([file options] FILE)... dfsimage write [global options] [build options] [image modify options] [image file options] IMAGE ([file options] FILE)...
examples:
dfsimage list image.ssd | tr '\n' '\r' | dfsimage build image.ssd CATALOG
dfsimage write image.ssd --sector=0-1 < cat-sectors.bin
build options:
--ignore-access, --no-ignore-access
--sector=[TRACK/]SECTOR[-[TRACK/]SECTOR]
Copy files from one image to another.
synopsis:
dfsimage copy-over [global options] [copy-over options] [image modify options] --from [image file options] FROM_IMAGE --to [image file options] TO_IMAGE FILES...
examples:
dfsimage copy-over --from image.ssd --to another.ssd '?.BLAG*'
copy-over options:
--ignore-access, --no-ignore-access
--preserve-attr, --no-preserve-attr
Format disk image removing all files.
synopsis:
dfsimage format [global options] [image modify options] [image file options] IMAGE
examples:
dfsimage format image.ssd --title 'Games'
Copy single file.
synopsis:
dfsimage copy [global options] [copy options] [image modify options] [image file options] IMAGE FROM TO
copy options:
--ignore-access, --no-ignore-access
--preserve-attr, --no-preserve-attr
Rename single file.
synopsis:
dfsimage rename [global options] [rename options] [image modify options] [image file options] IMAGE FROM TO
rename options:
--ignore-access, --no-ignore-access
Delete single file.
synopsis:
dfsimage delete [global options] [delete options] [image modify options] [image file options] IMAGE FILE
delete options:
--ignore-access, --no-ignore-access
Delete multiple files.
synopsis:
dfsimage destroy [global options] [destroy options] [image modify options] [image file options] IMAGE FILES...
examples:
dfsimage destroy image.ssd --ignore-access 'A.*' '!BOOT'
destroy options:
--ignore-access, --no-ignore-access
Lock files.
synopsis:
dfsimage lock [global options] [image modify options] [image file options] IMAGE FILES...
Unlock files.
synopsis:
dfsimage unlock [global options] [image modify options] [image file options] IMAGE FILES...
Change existing file attributes.
synopsis:
dfsimage attrib [global options] [image modify options] [image file options] IMAGE ([file options] FILE)...
examples:
dfsimage attrib image.ssd --locked --load-addr=FF1900 'B.*'
Display digest (hash) of file or sectors contents
synopsis:
dfsimage digest [global options] [digest options] [image file options] IMAGE FILE...
examples:
dfsimage digest -a md5 image.ssd MY_PROG
dfsimage digest -n image.ssd '*.*'
dfsimage digest -nn --sector=0/0-0/1 image.ssd
digest options:
-n, --name
- Display each file or object name. Repeat for image name.
-m, --mode={all,used,file,data}
Digest mode for file:
all
- include all attributes.file
- include load and execution addresses, but not access mode.data
- only file contents, don't include load and execution addresses or access mode.
Digest mode for disk side:
all
- include all sectors.used
- include used portions of catalog sectors and file sectors.file
- files sorted alphabetically; Load and exec addresses are included in the digest. File access mode and disk attributes are not included.
-a, --algorithm=ALGORITHM
- Digest algorithm, e.g.
sha1
,sha256
,md5
--sector=[TRACK/]SECTOR[-[TRACK/]SECTOR]
Check disk for errors. Runs the same cursory disk check that is executed before any other disk operation.
synopsis:
dfsimage validate [global options] [image file options] IMAGE
Create a new MMB file.
synopsis:
dfsimage create-mmb [global options] MMB_FILE
Mark disk image as uninitialized in the MMB index.
synopsis:
dfsimage dkill [global options] [--dunlock] [-i|--index=INDEX] IMAGE
examples:
dfsimage dkill beeb.mmb:300
Restore disk image marked previously as uninitialized.
synopsis:
dfsimage drestore [global options] [--dlock] [-i|--index=INDEX] IMAGE
examples:
dfsimage drestore --dlock -i 302 beeb.mmb
Refresh image titles in MMB file catalog.
synopsis:
dfsimage drecat [global options] MMB_FILE
Display or set images mounted in drives on boot.
synopsis:
dfsimage donboot [global options] [--set DRIVE IMAGE]... MMB_FILE
File properties can be used as keyword arguments in formatting string passed as
--list-format
argument for list
command or --output
argument for
export
command.
File properties are:
index
- File entry index.fullname
- Full file name including directory name.load_addr
- File load address.exec_addr
- File execution address.access
- File access mode -'L'
if file is locked, empty otherwise.size
- File length in bytes.start_sector
- Logical number of the first sector containing file data.end_sector
- Logical number of the first sector after file data.sectors
- Number of sectors occupied by file datasha1
- SHA1 digest of file data including load and execution addresses.sha1_data
- SHA1 digest of file data not including load and execution addresses.sha1_all
- SHA1 digest of file data including load and execution addresses and access mode.image_path
- Full path of the floppy disk image file.image_filename
- File name of the floppy disk image file.image_basename
- File name of the floppy disk image file without extension.image_index
- Index of the disk image in the MMB file.side
- Floppy disk side number - 1 or 2.image_displayname
- File name of the floppy disk image with MMB index or double sided disk head number appended.image_index_or_head
- Disk image index for MMB file or head number (0 or 1) for double sided disk.directory
- File directory name.filename
- File name not including directory name.fullname_ascii
- Full file name without translation of ASCII code 0x60 to unicode Pound sign.displayname
- File name as displayed by*CAT
locked
- File access mode - True if file is locked.dir_str
- Directory prefix as displayed by*CAT
command.drive
- Drive number according to DFS: 0 for side 1, 2 for side 2.head
- Head index: 0 for side 1, 1 for side 2.
Floppy disk side properties can be used as keyword arguments in formatting
string passed as --header-format
or --footer-format
for list
command.
Disk side properties are:
side
- Floppy disk side number - 1 or 2.title
- Floppy title string.sequence
- Sequence number incremented by the Acorn DFS each time the disk catalog is modified.opt_str
- Boot option string - one ofoff
,LOAD
,RUN
,EXEC
.is_valid
- Disk validation result.number_of_files
- Number of files on the floppy disk side.sectors
- Number of sectors on disk reported by the catalog.free_sectors
- Number of free sectors.free_bytes
- Number of free bytes.used_sectors
- Number of used sectorsmax_free_blk_sectors
- Number of sectors in largest continuous free block.max_free_blk
- Size of largest continuous free block in bytes.sha1
- SHA1 digest of the entire floppy disk side surface.sha1_files
- SHA1 digest of all files on the floppy disk side including their names and attributes.sha1_used
- SHA1 digest of floppy disk side surface excluding unused areas.path
- Full path of the floppy disk image file.filename
- File name of the floppy disk image file.basename
- File name of the floppy disk image file without extension.index
- Index of the disk image in the MMB filedisplayname
- File name of the floppy disk image with MMB index or double sided disk head number appended.index_or_head
- Disk image index for MMB file or head number (0 or 1) for double sided disk.tracks
- Number of tracks on the floppy disk side.drive
- Drive number according to DFS: 0 for side 1, 2 for side 2.head
- Head index: 0 for side 1, 1 for side 2.end_offset
- Last entry offset byte in catalog sector. Indicates number of files on the floppy disk image side.opt_byte
- Options byte in catalog sectors. Contains among other boot option value.opt
- Boot options value.last_used_sector
- Last used sector on floppy disk side.current_dir
- Current directory -'$'
by default.locked
- Image locked flag in the MMB catalog - True if image is locked.initialized
- Image initialized flag in the MMB catalog - True if image is initialized.mmb_status
- Image status in the MMB catalog:'L'
if image is locked,'U'
if image is uninitialized,'I'
if status flag is invalid, empty string otherwise.mmb_status_byte
- Raw MMB status byte value in the MMB catalog.
Image file properties can be used as keyword arguments in formatting string
passed as --image-header-format
or --image-footer-format
for list
command.
Image file properties are:
path
- Full path of the floppy disk image file.filename
- File name of the floppy disk image file.basename
- File name of the floppy disk image file without extension.index
- Index of the disk image in the MMB file.displayname
- File name of the floppy disk image with an MMB index appended.number_of_sides
- Number of floppy disk image sides.tracks
- Number of tracks on each side.size
- Current disk image size.min_size
- Minimum disk image size to include last used sector.max_size
- Maximum disk image size.is_valid
- True if disk validation succeeded.is_linear
- True if floppy disk image file has linear layout.locked
- Image locked flag in the MMB catalog - True if image is locked.initialized
- Image initialized flag in the MMB catalog - True if image is initialized.mmb_status
- Image status in the MMB catalog:'L'
if image is locked,'U'
if image is uninitialized,'I'
if status flag is invalid, empty string otherwise.mmb_status_byte
- Raw MMB status byte value in the MMB catalog.sha1
- SHA1 digest of the entire disk image file.
The package is functionally complete, but lacks tests and Python module documentation.