Skip to content

SpecialFormats

dfgordon edited this page Oct 15, 2025 · 3 revisions

Special Formats

This deals with how to create, read, and write disks with your own special formats, or unlock an existing special format. N.b. this is an advanced topic.

As of this writing we are only concerned with Apple GCR disks, namely WOZ images. The system has been designed such that it can (hopefully) be expanded later to encompass other soft sector formats.

About Copy Protection (or, "why do this")

There is no attempt here to defeat copy protection. It is possible to do the opposite, i.e., defeat copy programs, but why bother, since one can always copy the image directly. So the motivations that remain are:

  • protect a disk from inspection or modification by casual users
  • allow a disk to be inspected or modified by expert users

Overview

We do not pretend to handle every possible special format, the ones we can handle must follow a certain pattern.

To enable a special format, provide a2kit with a JSON string that describes the special format. As an example, if we put the format string in a file special.fmt.json, we could create a disk in this format with

a2kit mkdsk --pro special.fmt.json -d special.woz -o dos33 -v 254 -t woz2

All other manipulations are carried out the same way, simply provide the --pro argument. In general, this disk is "protected" because standard DOS will not be able to interpret it. In fact, other a2kit users will not be able to interpret it either, unless you provide the format file, or they "crack" it themselves.

Preparing the JSON string involves the following:

  • Define nibble tables
  • Define sector markers
  • Map standard addresses to special addresses

These may be further broken up into

  • formatting
  • seeking
  • physical zone

Custom synchronization bits are also allowed for.

Examples

If you are familiar with this sort of thing, it may be fastest to have a look at the examples in the repository. Please see here.

Timing Resolution

Although the underlying track engine allows for arbitrary timing resolution, the special format system only allows you to specify what is expected at the bit cell level. This means you cannot deliberately move a flux transition around within a bit cell.

Starting Template

Rather than create the JSON string from scratch, it is recommended you start from a standard one. To do this, select an existing WOZ image that is expected to be close to what you want (e.g. DOS 3.3 master). Then run something like

a2kit geometry -d some_baseline.woz --abstract --indent 4 > my_fmt.json

Remember to use a WOZ image, things like DSK will not work.

You can now use my_fmt.json as a basis for modification.

Short Hand Notation

Some of the JSON values support a nested list of the form [[item,repetitions]]. So for example

"capacity": [[256,16]]

means the same as

"capacity": [256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256]

The keys that support this are sync_trk_beg, sync_sec_end, sync_dat_end, and capacity.

Add a Zone

The baseline will only have one zone. For a special format you usually want two zones, one standard zone that includes the boot sector, and another for everything else. To create the new zone just copy the existing one to create a second object in the zones list. Then edit the motor_range in both zones according to your specification.

The three numbers in the motor_range value are [begin,end,step]. Here, end is exclusive. Remember with 5.25 inch Apple disks you will normally be stepping by 4.

Nibble Type

When it comes to Apple disks, you can independently control the kind of nibble used in address and data fields. This is done by editing the values of the addr_nibs and data_nibs keys. The system supports whatever peculiar combination you like. For example, nothing stops you from using 5&3 nibbles in the address field, and 4&4 nibbles in the data field. However, the real disk hardware can have limitations, e.g. early Apple hardware will not handle 6&2 nibbles. Don't forget the choice of data nibbles will affect the number of sectors you can fit on a track, so make sure capacity is consistent.

Sector Markers and Nibbles

Nibble tables and sector markers are connected because reserved nibbles figure into the choice of sector markers. It is especially important that the address prologue (marker that immediately precedes the address) be unique.

It is assumed that the new nibble table will be close to the standard one. Therefore the new table is most efficiently defined using nibble swaps. Edit swap_nibs to include the set of tuples that will be swapped, e.g.,

"swap_nibs": [["aa","96"],["d5","9b"]]

You can swap any nibble, whether reserved or not, with any other nibble.

Next define the four markers. The markers key is an ordered list consisting of address prolog, address epilog, data prolog, data epilog. The marker_masks follow the same order, and allow you to ignore selected bits when matching markers during a seek operation.

In this process it is up to you to make sure that the selections you make satsify all the uniqueness requirements that are involved in decoding a sector.

File System Access

The way a2kit protects or enables file system access is by transforming the sector addresses that the ordinary file system is seeking. The transformation is defined by two expressions that are keyed by addr_fmt_expr and addr_seek_expr. The former is used during formatting, the latter during seeking.

Each expression is actually a list of expressions, one for each byte in the sector address. The terms or factors that can be used in the expressions are as follows.

  • vol is the volume number of the disk, often this is used during formatting, but not during seeking
  • cyl is the geometric cylinder number (radius), any quarter-decimals are truncated
  • head is the read/write head number (height), always zero for single-sided drives
  • sec is the sector number that the standard file system has requested
  • a0 - a3 are the values actually found at each byte position, these can only be used during seeking
  • any literal decimal value

The operations that are available are defined in the math-parse crate. Be sure to use integer division (//), floating point division (/) is not accepted.

Note that the terms/factors defined above can be used anywhere in the sector address, you can scramble the data however you wish. As with sector markers, it is up to you to ensure uniqueness of sector addresses.

Special DOS

If this is your own format, you can only use it in emulation (or on real hardware) if you also provide a version of DOS that knows how to encode and decode it. It is currently outside the scope of a2kit to help with creating the modified DOS. If you are trying to unlock an existing disk, then this is not an issue.

Conclusion

Once you have done all this you should be able to create and work with disks in this new format exactly the same way as any other disk, provided you include the --pro argument. The --pro argument can accept either a path to a file containing the JSON string, or the JSON string itself.

Clone this wiki locally