Skip to content

LowLevel

dfgordon edited this page Nov 21, 2022 · 9 revisions

Low Level Services

This deals with low level disk operations and associated types.

File Images and the any Type

File images are a way of abstracting any file that could exist on the file systems that a2kit handles, including sparse files. When you want to specify that an item is a file image you use the any type. A file image is as a collection of hex strings within a JSON structure. As an example, suppose we have a binary file named thechip containing the 4 byte sequence 6,5,0, and 2. We can get the any representation using

a2kit get -f thechip -t any -d mydos33.dsk

Assume console output, this would display

{
    "file_system": "a2 dos",
    "chunk_len": "00010000",
    "eof": "00000000",
    "fs_type": "04000000",
    "aux": "00000000",
    "access": "00000000",
    "created": "00000000",
    "modified": "00000000",
    "version": "00000000",
    "min_version": "00000000",
    "chunks": {
        "0": "00030400060500020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    }
}

In this case there is only one "chunk," but generally there could be many. Unused metadata fields are zero. The same file retrieved from ProDOS would look different:

{
    "file_system": "a2 prodos",
    "chunk_len": "00020000",
    "eof": "04000000",
    "fs_type": "06000000",
    "aux": "00030000",
    "access": "E3000000",
    "created": "712D0000",
    "modified": "712D0000",
    "version": "24000000",
    "min_version": "00000000",
    "chunks": {
        "0": "0605000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    }
}

A few things to note:

  • The metadata is padded to 4 bytes with nulls. The interpretation of the bytes is dependent on the file system.
  • For DOS 3.3, the starting address and length of the data are in the first two words of chunk 0. This is a characteristic of the file system, not the file image representation.
  • For ProDOS, the starting address is in the aux value, and the length is in the eof value.
  • The chunk numbers do not have to be in an unbroken sequence. This is what allows the file image to handle sparse files.

You can pass file images through the a2kit pipeline the same as any other object, but you cannot move data between disparate file systems this way. For that you must use the high level file types.

Track Operations

This allows you to look at the track data that is stored with WOZ images. As of this writing, you can only get a track. To get the bytes exactly as they are stored in the WOZ track buffer use

a2kit get -t raw_track -f 17 -d mydos33.woz

Here the "file type" is raw_track and the "path" is the track number. You can also process the bytes through a "soft latch" which skips over certain null-bits:

a2kit get -t track -f 17 -d mydos33.woz

The output for track is easier to interpret, and also will display the following mnemonics alongside:

Mnemonic Pattern Meaning Comment
>... repeated $FF sync bytes false matches are possible
(A: $D5AA96 address prolog fragments are accepted
(D: $D5AAAD data prolog fragments are accepted
::) $DEAAEB either epilog fragments are accepted
0-F address field decoded address nibbles e.g. FF FE displays as FE
R $D5 or $AA reserved bytes in case they appear outside prologs/epilogs
? bad byte not a valid 6-2 nibble 5-3 is a subset of 6-2

N.b. this is geared toward 16-sector disks, and the data is only valid after the first sync gap is processed (often this will be at the start of the track buffer).

Chunk Operations

The term "chunk" refers to either a sector or block (not to be confused with WOZ metadata chunks), depending on the file system considered. The chunk is always identified by a single unsigned integer. For this reason, if the file system is sector-oriented, one needs the following formula to relate track and sector numbers to the chunk number:

// if sectors per track is constant
chunk_number = track_number * sectors_per_track + sector_number;
// if not (rare, maybe never)
chunk_number = sector_number;
for (track=0; track<track_number; track++)
    chunk_number += sectors_per_track[track];

In order to get a chunk, simply specify the chunk "file type" and use the chunk number as the "path":

a2kit get -f 272 -t chunk -d mydos33.dsk

This will display the VTOC if the disk is a 5.25 inch DOS 3.3 floppy.

You can also write a chunk by pipelining some data into put:

a2kit get -f some_local_file | a2kit put -f 272 -t chunk -d mydos33.dsk

It is important to understand this is a blind write, no checks of any kind are made. The above example (overwriting the VTOC) would generally break the file system.

Clone this wiki locally