Skip to content

DiskImages

dfgordon edited this page Jan 17, 2026 · 20 revisions

Disk Image Utilities

This page deals mainly with files, for tracks and sectors see Low Level.

Creating Disks

You can create a disk image using the mkdsk subcommand:

a2kit mkdsk -o dos33 -v 254 -t woz1 -d mydisk.woz

The argument -o dos33 tells a2kit to create a DOS 3.3 file system, -v 254 is the volume number, and -t woz1 specifies the image type as WOZ version 1. The disk kind is selected automatically based on the file system. You can explicitly select a compatible disk kind as follows:

a2kit mkdsk -o prodos -v test.disk -t po -k 3.5in-apple-800 -d mydisk.po

Here an 800K ProDOS disk is created as a PO image. There are a great many possibilities, the below table lists the possible arguments. Not all combinations of arguments are allowed, a2kit will return an error if an illegal combination of arguments is attempted.

argument flag argument value comment
-v number or name volume designation per OS
-o dos32 DOS 3.2 operating system
-o dos33 DOS 3.3 operating system
-o prodos ProDOS operating system
-o pascal Pascal operating system
-o cpm2 CP/M v2 operating system
-o cpm3 CP/M v3 operating system (adds label and timestamps)
-o fat FAT file system (notably MS-DOS)
-t 2mg wrapper for do, po, or nib images, see -w option
-t do DSK/DO, direct dump of DOS ordered sectors, already decoded
-t po DSK/PO, direct dump of ProDOS blocks, already decoded
-t d13 similar to do, but for 13 sector disks (DOS 3.2)
-t imd structured sector data, already decoded
-t img DSK/IMG/IMA, direct dump of FAT sectors, already decoded
-t nib disk tracks are emulated down to the nibble level
-t td0 structured sector data, already decoded
-t woz1 WOZ version 1, disk tracks are emulated down to the bit level
-t woz2 WOZ version 2, more flexible version of woz1
-k 3in-amstrad-ssdd Amstrad 184K floppy
-k 3.5in-apple-400 Apple 400K floppy
-k 3.5in-apple-800 Apple 800K floppy
-k 3.5in-ibm-720 IBM 720K (MS-DOS)
-k 3.5in-ibm-1440 IBM 1440K (MS-DOS)
-k 3.5in-ibm-2880 IBM 2880K (MS-DOS, rare)
-k 5.25in-apple-13 Apple 114K floppy
-k 5.25in-apple-16 Apple 140K floppy
-k 5.25in-ibm-ssdd8 IBM 160K (MS-DOS)
-k 5.25in-ibm-ssdd9 IBM 180K (MS-DOS)
-k 5.25in-ibm-dsdd8 IBM 320K (MS-DOS)
-k 5.25in-ibm-dsdd9 IBM 360K (MS-DOS)
-k 5.25in-ibm-dsqd IBM 640K (MS-DOS)
-k 5.25in-ibm-dshd IBM 1200K (MS-DOS)
-k 5.25in-osb-sssd Osborne 100K floppy
-k 5.25in-osb-ssdd Osborne 200K floppy
-k 5.25in-kay-ssdd Kaypro 200K floppy
-k 5.25in-kay-dsdd Kaypro 400K floppy
-k 8in-ibm-sssd IBM 250K floppy (std CP/M)
-k 8in-trs80-ssdd TRS80 M2 600K floppy
-k 8in-nabu-dsdd Nabu 1M floppy
-k hdmax 32MG logical hard disk
-w do use do as the wrapped image (wrapper images only)
-w po use po as the wrapped image (wrapper images only)
-w nib use nib as the wrapped image (wrapper images only)
-b n/a make disk bootable, DOS 3.x only
--blank n/a create pristine media, WOZ only
--empty n/a zero all sectors
--flux CH list tracks that should use flux timings, WOZ only

Bootable Disks

If you want a DOS 3.x disk to be bootable, you must use the -b flag:

a2kit mkdsk -b -o dos33 -v 254 -t do -d my_bootable.dsk
a2kit get -f hello.bas | a2kit tokenize -t atxt -a 2049 | a2kit put -f hello -t atok -d my_bootable.dsk

The second line copies a greeting program - assumed to be in the working directory - to the disk image, with the filename HELLO. The DOS tracks assume this greeting program exists.

In order to make a ProDOS or Pascal disk bootable, you have to copy the necessary files from an existing disk image, see Copying Files. For CP/M you would have to copy the reserved tracks (sector by sector), along with reserved blocks (block by block), if any. For FAT disks (e.g. MS-DOS), reserved sector(s) and boot files must be copied.

Image Formats

The WOZ format is probably the best Apple II image type to work with, because it is widely supported, well defined, supports various metadata, and allows for realistic emulation of disk access. The decoded image types like DSK, or 2MG wrapped DSK, might be chosen if efficiency is important. The NIB and 2MG wrapped NIB format are provided as a matter of historical interest.

Some WOZ images are reproductions of real disk tracks with proprietary formats. Such reproductions are created using, e.g., Applesauce. Proprietary formats can be handled starting with version 4, see special formats.

The IMD and TD0 formats originate from ImageDisk and Teledisk, respectively. These formats can be used for CP/M and FAT file systems. The IMG format can also be used for FAT disks.

Smart Copy

The simplest way to copy files is with the cp subcommand. Unlike the rest of the a2kit CLI this uses positional arguments and will make some assumptions about what the user wants. The syntax is the same as the cp command familiar to linux users, e.g. a2kit cp report1.txt report2.txt myimage.imd copies two text files to a disk image. There are differences of semantics as follows:

  • disk images are treated as if they were a directory
    • the image can sit in the middle of a path, e.g. /path/to/myimage.td0/prog/calc.bas
  • ProDOS volume names
    • leading single slash means match any volume name, e.g. /path/to/myimage.woz/startup
    • leading double slash means match the given volume name, e.g. /path/to/myimage.woz//volume.name/startup
  • each file will be analyzed and possibly transformed to be readable at the destination
    • this transformation is always invertible, i.e., the reverse copy will undo it
  • glob patterns work with the following caveats
    • shell expansions work as usual if there is no disk image in the path
    • a2kit will perform its own glob expansion for patterns inside the disk image
    • it may be necessary to use quotes or escapes to suppress the shell expansion
  • as usual a2kit forbids overwriting

The copy works for image-to-host, host-to-image, and image-to-image copies.

Converting Images

There is no sub-command for this, but it can be done in two easy steps. See Examples.

Modifying Files

You cannot overwrite a file except by deleting and re-saving. You can modify files as follows.

To delete a file or directory,

a2kit delete -f path/to/item -d mydisk.dsk

If item is a directory it must be empty. To rename,

a2kit rename -f path/to/file -n new.name -d mydisk.dsk

To change the file type and sub-type,

a2kit retype -f path/to/file -t sys -a 8192 -d mydisk.woz

To change permissions or attributes,

# set a password (e.g. with CP/M v3)
a2kit access -f path/to/file -d mydisk.woz --password abc123
# remove delete permission if applicable to this FS
a2kit access -f path/to/file -d mydisk.woz --no-delete

Disk Directory

Authentic Style Directory

The catalog subcommand (aliases: dir, ls) is designed to closely reproduce the given file system's directory display:

a2kit catalog -d mydisk.dsk

You can optionally specify a subdirectory:

a2kit catalog -d mydisk.dsk -f subir1/subdir2

For CP/M you can use wildcards and command tails:

a2kit dir -d mydisk.td0 -f '*.com[exclude]'

For FAT (e.g. MS-DOS) you can use wildcards and/or the /w switch:

a2kit dir -d mydisk.imd -f 'subdir1/subdir2/*.txt /w'

N.b. only the forward slash is accepted, never the backslash.

Generic Style Directory

If you want a disk directory in a standard, easy to parse format, use the --generic option:

a2kit dir -d mydisk.woz --generic

Directory Tree

If you need to get the whole directory tree for processing use the tree subcommand:

a2kit tree -d mydisk.td0 --meta

This will output a JSON string containing the full directory information, including metadata (timestamps, access flags, etc.). This can be a very long string. You can omit the --meta flag to get something more compact, and/or add the --indent option for human readable output:

a2kit tree -d mydisk.td0 --indent 2

The JSON object's subdirectories will have the files key between them. The reason for this is that every node can have the meta key - we need to know if you want the files or the metadata. So the tree path to some metadata will look like files/subdir1/files/subdir2/files/somefile.txt/meta, where path notation has been used. A non-directory node will have no files key. An empty files key means an empty directory.

The particular keys in the meta object depend on the file system.

Getting Single Files

You can get file data from a disk image using the get subcommand:

a2kit get -f subdir/program1 -t atok -d localdir/localfile.dsk

The type of the file is given by the -t argument, which in this example has the value atok, corresponding to tokenized Applesoft. The -d argument tells a2kit that the file is within a disk image, rather in the regular file system. One has to keep straight that the -f argument is a path inside the disk image, while -d is the path to the disk image itself. The output is the tokenized code. In this example it is displayed to the console as a hex dump. If the output is redirected it will contain the raw binary.

Other types are handled similarly, e.g., to get a binary file:

a2kit get -f subdir/binary1 -t bin -d mydisk.dsk

This also will display a hex dump on the console, or write raw binary to a file or other pipeline node. For more on handling of specific file types, see the file types page. When you get a file from the regular file system (perhaps call this a "local" file), the only argument is the path:

a2kit get -f some/local/file

Finally, there is a universal file representation, or file image, with the type any. No matter what the file is, you can always do this:

a2kit get -f somefile -t any -d mydisk.woz

See the spec page for more on file images.

Note that get is always the start of the pipeline, barring input redirection.

Putting Single Files

You can store a file in a disk image using the put subcommand. It works analogously to get:

a2kit put -f subdir/binary1 -t bin -a 768 -d localdir/localfile.dsk

The load address option (-a) is needed for Apple binaries. Note that put is always the end of the pipeline.

Copying Single Files

To copy files pipe the result of get into put. The main issue is whether to use the any type, or one of the more specific high level types. If you are moving the file between disk images where the file systems are the same (e.g. both are DOS, both are ProDOS, etc.), the any type is the most fool-proof, because it will preserve sparse file structure and metadata. Here is an example:

# copy any kind of file between disk images with the same file system
a2kit get -f sparse.file -t any -d prodos_disk.woz | a2kit put -f sparse.file -t any -d prodos_disk.dsk

It is useful to realize you can save a file image to be restored at a later date:

# save some file image for future use
a2kit get -f sparse.file -t any -d prodos_disk.woz > sparse.file.json
# come back a long time later and restore it to some other disk
a2kit put -f sparse.file -t any -d other_disk.woz < sparse.file.json

If you are moving files between disk images with disparate file systems, the any type cannot be used. Instead use a high level file type, e.g.

# copy a specific file type, OK if file systems are different
a2kit get -f file1 -t txt -d dos33_disk.dsk | a2kit put -f file1 -t txt -d prodos_disk.dsk

The caveat is that these types assume a standard storage pattern, i.e., they assume that only random access text files can be sparse.

Efficiently Processing Many Files

Looping over single file operations is inefficient, because the disk has to be solved and buffered on each iteration. The way to efficiently process many files is to gather bundles of file images with mget or save them using mput.

Getting Many Files

You can get any number of file images at once using mget. The list of paths are piped in:

# using a PowerShell string literal
'["ed.com","type.com"]' | a2kit mget -d mycpm.td0

You can use glob to create a list of paths, and pipe it into mget:

# with some shells the glob has to be quoted
a2kit glob -d mycpm.td0 -f "*.com" | a2kit mget -d mycpm.td0

The output of mget is a JSON list of file images. In order to do something with it you will often need to write a script. Languages like Python make it quite simple to parse a JSON string. You can unpack the data from a single file image using unpack, e.g.:

a2kit get -f some_fimg.json | a2kit unpack -t txt

Putting Many Files

You can put many files using mput, which expects a list of file images to be piped in. The main caveat is that for hierarchical file systems, the destination directory is controlled by the data in the file image itself, unless you explicitly override it. For example, if you try

a2kit glob -d disk.po -f "**" | a2kit mget -d disk.po | a2kit mput -d otherdisk.po

there is a good chance you will get an error, because the directories on disk.po may not match those on otherdisk.po. One way to work around this is to specify a directory into which all the files will go:

a2kit glob -d disk.po -f "**" | a2kit mget -d disk.po | a2kit mput -d otherdisk.po -f otherdirectory

This works as long as there are no duplicate file names.

If the source of the data is local, you can use pack to create file images, e.g.

a2kit get -f doc.txt | a2kit pack -f 4:doc.txt -t txt --os cpm2

Here, 4:doc.txt targets the file image for CP/M user 4. In general, putting many files is a job for a script. See examples.

Automatic Unpacking

In the above examples, we assumed the user knows the desired file type. Sometimes a file system provides clues on how a file should be unpacked. To take advantage of this you can try the auto type:

a2kit get -d disk.woz -t auto -f mystery

If the file image is local this can be done as follows:

a2kit get -f mystery.json | a2kit unpack -t auto

Making Directories

You cannot create directories using put, instead use mkdir:

a2kit mkdir -f path/to/subdir -d mydisk.dsk

The parent directories must already exist.

Piping Disk Images

Some subcommands that read a disk image can accept it from either a file (-d option) or an input pipe. The subcommand will examine the provided options and the state of the pipe to decide where to get the disk image.

Non-standard Filenames

DOS 3.x filenames are ordinarily negative ASCII strings, but in general, the 30-byte buffer that holds the string is unrestricted. For example, the CATALOG of the DOS 3.1 system master displays HELLO in inverse video, because the filename buffer contains 0x08050c0c0f. If you want to do something like this with a2kit, you can use hex escapes (only for DOS 3.x). Remember that you may need to "escape the escape," depending on your shell. As an example, to make a file HELLO appear in inverse video:

a2kit put -f \\x08\\x05\\x0c\\x0c\\x0f -t itok -d mydisk.d13 < hello.itok

N.b. this has the consequence that the file cannot be readily accessed through direct commands.

ProDOS Paths

The path into a ProDOS disk image should be formed according to ProDOS rules. The prefix is always set to the first volume name found on the disk image. You can also give a full path that includes a volume name explicitly.

MS-DOS Paths

The path into a FAT disk image is formed using the forward slash and omitting the drive specification. The working directory is always the root directory. You can include or omit the leading forward slash as desired. The volume label is never part of the path.

Clone this wiki locally