==DDL Disk Description Language Specification 1.0==

This is the specification of DDL 1.0, an XML language that describes data stored on floppy disks.

The purpose of DDL is to provide an open standard for preserving the digital content of copy-protected floppy disks. The advantages of DDL are accuracy, readability, modifiability, expandability and ease of implementation.

DDL does not describe data from the point of view of the storage medium (floppy disk) but from the perspective of the storage access device (disk drive). It stores the necessary instructions for producing a (hopefully accurate) copy of a floppy disk. This includes the data stored on the floppy disk and associated properties like the type of storage medium, the tracks per inch reference and the state of the write protection tab.

When dealing with single-sided floppy disks, or double-sided floppy disks where both sides are part of the same filesystem, a single DDL file should be produced. Otherwise separate DDL files should be produced for each side.

DDL uses as fundamental unit the bit cell, the area of disk surface on which a single bit is recorded.

The XML DTD is available here:

  http://www.openemulator.org/DTD/ddl-1.0.dtd

Notes:

* DDL attempts to describe all known means of copy protection for floppy disk drives. These include isolated bit cells, bit cells of different duration, weak bit cells and areas with no magnetic coating (laser holes). If a new kind of description is needed, request-for-comments shall be initiated.

* For comments or suggestions please contact: Marc S. Ressl (mressl at umich . edu)

==Legal==

The DDL specification is licensed under the Creative Commons "attribution CC BY" license 3.0. For more information please refer to:

  http://creativecommons.org/licenses/by/3.0/

==Nomenclature==

This specification uses square brackets to denote information that should be replaced.

Real numbers should use the dot character '.' as decimal mark.

==DDL files==

DDL filenames should always end with the extension .ddl.

The information stored in a DDL file follows the XML specification. For more information please refer to:

  http://www.w3.org/TR/REC-xml/

==DDL header==

DDL files should begin with the following XML header:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ddl PUBLIC "-//DDL//DTD DDL 1.0//EN" "http://www.openemulator.org/DTD/ddl-1.0.dtd">

==DDL tag==

The DDL tag is the top-level of the floppy disk description:

<ddl version="1.0" creator="[CREATOR]" label="[LABEL]" description="[DESCRIPTION]" medium="[MEDIUM]" tracksPerInch="[TRACKSPERINCH]" writeEnabled="[WRITEENABLED]">

* [CREATOR] is a string that describes the name of the author, or the name and version of the software that created this DDL file.
* [LABEL] is a short description of the content stored in this DDL file.
* [DESCRIPTION] is a longer description of the content stored in this DDL file.
* [MEDIUM] describes the kind of storage medium. Valid storage mediums are: "8 inch disk", "5.25 inch disk" and "3.5 inch disk".
* [TRACKSPERINCH] is a real number that describes the magnetic resolution of the storage medium (this is sometimes found on a label on the disk). Common values are "48", "62.5", "96" and "100".
* [WRITEENABLED] may take the values "0" or "1", and determines if the storage medium may be modified (is not write protected).

==DDL track tag==

Within the DDL tag a series of track tags may exist, each describing a track's content:

<track index="[TRACKINDEX]">

* [TRACKINDEX] is a real number that describes the track's location according to the tracks per inch reference of the storage medium. The fractional part can be used to describe non-standard locations.

An example: an Apple II standard-formatted 5.25" floppy disks should be imaged with tracksPerInch="48". Its track indices should be numbered from 0 to 34 (for 35 track disks) or 0 to 39 (for 40 track disks). If there are half- or quarter- tracks, indices ending in .5, .25 or .75 should be used, like "3.25" for example.

==DDL side tag==

Every track tag contains one or more side tags, each describing the content of a track/side:

<side index="[SIDEINDEX]">

* [SIDEINDEX] describes the side number. It may be "0" or "1".

==DDL data tag==

Every side tag contains one or more data tags, each containing actual data:

<data cellLength="[CELLLENGTH]" cellWidth="[CELLWIDTH"]>

* cellLength is optional. If used, the real number [CELLLENGTH] specifies the relative length of each bit cell contained in this tag. The default bit cell length is "1.0".
* cellWidth is optional. If used, the real number [CELLWIDTH] specifies the width of each bit cell contained in this tag according to the tracks per inch reference. The default bit cell width is "1.0".

It is possible to use several data tags in sequence to describe parts of a track with different cell length and width.

==DDL data==

Data is stored as standard ASCII text, and may be composed of the following symbols:

* A '-' character encodes a 0 bit cell (no magnetic inversion).
* A '+' character encodes a 1 bit cell (a magnetic inversion).
* An 'x' character encodes a bit cell on non-magnetic material (i.e. a laser hole).
* A '?' character encodes a weak bit cell (a 50% chance of magnetic inversion).
* Two characters representing an 8-bit hexadecimal value (characters '0'..'9' and 'a'..'f' or 'A'..'F') encode a sequence of 8 bit cells. The most significant bit of this value (bit 7) encodes the first bit cell, the least significant bit of this value (bit 0) encodes the last bit cell.
* Data may be formatted with space, tab, newline or linefeed.

==Observations==

* A disk is a circular medium. Thus the data of each track/side must be treated circularly as well.
* The first bit cell of each track/side must be synchronized to the index hole of the storage medium. In case the index hole is not available, synchronization should be relative to some arbitrary position.
* Every track/side may contain an arbitrary amount of data.
* The actual duration of a bit cell can be calculated from the relative bit cell length L, the total bit cell length sum T and the disk drive rotation speed S as follows: L / T / S. Example: if a disk track contains 50000 bit cells and the disk spins at 300 RPM, each bit cell takes 1 / 50000 / (300 / 60) = 4 microseconds.
* A track/side with no data or a part of a track/side with no data should be treated as a stream of 0 bit cells (no magnetic inversions).
* Areas with no magnetic material ('x' bit cells) are read-only, as there is no material to store a magnetic state.
* Data should be human-readable. Provisions should exist so that data fields are easy to read, understand and modify (i.e. sectors may be detected and appropriately formatted). Authors of DDL files are encouraged to use XML comments to describe the copy protection within the DDL file.

==Example==

This example illustrates the features of DDL XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ddl PUBLIC "-//DDL//DTD DDL 1.0//EN" "http://www.openemulator.org/DTD/ddl-1.0.dtd">
<ddl version="1.0" creator="libdiskimage 1.0" label="Apple DOS 3.3" description="Apple DOS 3.3 is an operating system for the Apple II series of microcomputers." medium="5.25 inch disk" tracksPerInch="48" writeEnabled="1">

<track index="0">
<side index="0">
<data>
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--
ff-- ff-- ff-- ff-- ff-- ff-- ff-- ff--

d5 aa 96 ff fe aa aa aa aa ff fe de aa eb

<!-- XML comments may be used -->

ff-- ff-- ff-- ff-- ff-- ff--

d5 aa ad b6 db dc f4 f3 bb bd cf 97 9a ae ae 96
ad ac 9a ab 97 b2 b2 ad ab 9a 9b ab 9f 97 b3 9a
b3 9e 97 9f b3 96 ac ae a7 9a b2 96 ad ac 9b b2
a6 97 9f af ac a7 ab 97 9f a6 9e 97 9e a7 af 9e
ae 9e ae 9f 9b 97 9b b2 af b3 ae ac 9a b3 b2 ac
a7 ac 97 ab ab ba f4 ea ad 9e e5 d6 fb ed f5 ef
ec da bd 96 96 96 b4 ef b5 eb dc fd f5 eb ab ea
b9 fd be db fd d7 cd fd e5 b9 fd b2 ab e6 fc b5
da eb fc ae fd e5 b9 fd da df fa ae fd e7 da b5
b9 b3 fb 9d fd f9 9d fd ac e6 ce f6 e9 cb f6 9b
f4 bc da b5 db fd 9a 9b 97 96 9b 96 97 96 9b 96
97 96 9b 96 97 9b 9b a7 b5 b4 dc eb df e6 e6 ab
f3 bf e5 f3 fb bf fc cf de fd d9 fc bf ee fe f9
b9 d9 f9 f3 fb b9 d9 de e6 da f3 bf cf ef ec ea
ae d9 9e d9 da 97 ef ef cb ae bc d6 e9 df fc db
ee f6 9a f4 ee ab ba eb e6 fc f5 b3 db ff 9a f6
f2 ab eb fd de d7 bc cd f3 bf f9 ab fd 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96
96 96 96 96 96 96 96 96 96 96 96 96 96 96 96 96
96 96 96 96 96 96 96 af b3 9a de aa eb
</data>
<data cellLength="1.1">
<!-- Here goes a weak bit copy protection -->

ff-- ff-- ff-- ff-- ff-- de aa +?-+++--

<!-- Here goes a laser hole copy protection -->

00 00 00 00 xxxxxxxx xxxxxxxx 00 00 00 00
</data>
</side>
</track>
</ddl>
