EXOS 2.1 Cassette Driver Specification

6. Cassette Data Format

As mentioned before a file consists of a series of chunks, the first of which is a header chunk and the rest of which are data chunks. The section describes the format of a chunk in some detal. A header chunk is in fact a special case of a data chunk with a special block count as will be explained later.

6.1 Cassette Signals

Each byte is stored on tape as a series of 8 bits, least significant bit first, with no start or stop bits. Each bit is stored as a single cycle, with a different frequency to indicate whether the bit is set or clear. These frequencies are in a ratio of 2:3 which is large enough to allow the software to distinguish them when reading in, but small enough to keep the data rate high.

An intermediate frequency is used for the leader tone which comes before the data, and this leader is used to determine the data rate when reading.

A single cycle of lower frequency is used to indicate the start of the data and also establish the phase of the signal (since it may or may not be inverted).

When the data is being read back, all timing is done in terms of whole cycles rather than half cycles. This ensures that it is relatively insensitive to changes in duty cycle which can result from level changes (drop­outs, etc).

The actual whole cycle times and frequencies used for the two tape speeds are:

                   Fast Speed        Slow Speed

    leader cycle   424µs (2358 Hz)   1000µs (1000 Hz)
    one bit        344µs (2907 Hz)    800µs (1250 Hz)
    zero bit       504µs (1984 Hz)   1200µs ( 883 Hz)
    sync bit       696µs (1437 Hz)   1600µs ( 625 Hz)

6.2 Overall Chunk Format

Each chunk starts with a synchronisation sequence. This consists of several seconds of leader frequency to allow the cassette recorder amplifiers and automatic recording level circuits to stabilise, and to establish the data rate. This is followed by a single low frequency sync cycle to establish the phase of the signal, and then one unused byte to recover from this one long pulse. The next byte always has the value 06Ah and is to ensure that false synchronisation does not occur.

After this byte is the data of the chunk, followed by a few cycles of leader frequency (the trailer) to ensure a clean end to the data. The overall format is shown in this diagram:

    +--------+------+-------+------+--· · ·--+---------+
    | Leader | Sync | Dummy | 06Ah |   Data  | Trailer |
    +--------+------+-------+------+--· · ·--+---------+

6.3 Internal Chunk Format

The data within a chunk is split up into a maximum of sixteen 256 byte blocks, each starting with a byte count and ending with a two byte CRC check. These blocks are preceded in the chunk by a single, one byte, block count which defines how many blocks there are in the chunk.

The format of the data within a chunk is therefore as shown in this diagram:

    +-------------+-------+-------+-· · ·-+-------+
    | Block Count | BLOCK | BLOCK |       | BLOCK |
    +-------------+-------+-------+-· · ·-+-------+
       __________/         \____________________
      /                                         \
     +------------+--· · ·--+---------+----------+
     | Byte Count |   Data  | Low CRC | High CRC |
     +------------+--· · ·--+---------+----------+

A data chunk has a block count of 0 to 16, and each block is always 256 bytes long, except for the last block in the last chunk of the file. A block containg 256 bytes of data has a byte count of zero, which cannot be misinterpreted because zero is not a valid quantity.

6.4 Header Chunk Format

A header chunk always contains exactly one data block (of varying size), but has a block count of 255. This block count is used to recognise that it is a header chunk. The format of the data within the header chunk is:

byte 0 - Protection byte

000h : protected file
0FFh : inprotected file

byte 1 - Length of filename, 0..28
byte 2 and up - Filename.

6.5 Crc Checking

Each data block ends with a 16 bit CRC check. This calculated by treating all bytes of the data block (not including the byte­count byte) as a bit stream. A 16 bit CRC register is initialised to zero at the start of the block and the following process carried out on each bit:

  1. XOR the new bit into bit 15 of the CRC register
  2. If the new bit 15 is set then XOR the CRC with 0810h
  3. Rotate the CRC one bit left, putting bit 15 into bit 0

Note that this is the same CRC algorithm as that used by the network driver.

Next Chapter: Quick Reference Summary.

David Bouman. (dsbouma@cs.vu.nl)