Atari XL tape preservation and autopsy
My first-ever computer was the Atari 600XL with an Atari 1010 Datasette. Recently I stumbled upon some old cassette tapes, one of which I used with my Atari (while the others were utilized with my Sharp MZ-800, which I will cover in a later story). Let’s see if I can recover the data from the tapes after such a long time and if it’s possible to make the actual bits visible with an audio editing software like Audacity.
My plan is as follows: 1. Capture the audio stored on the tape to a WAV file 2. Transform the WAV file to something an Atari emulator can read, or directly use the WAV file in the emulator.
Overall, the workflow is as follows:
ATARI XL
Tape conversion workflow
+----------+ +----------+ +---------+
+----------+ | |(optional)| | | |
| O TAPE O | Capture | Mono WAV | Process | Enhanced | Convert | CAS |
| ______ |--------->| File |--------->| Mono WAV |---------->| File |
+-/------\-+ Tenacity | | Tenacity | File | Altirra, | |
| | | | wav2cas | |
+----------+ +----------+ +---------+
Capturing the tape to a WAV file
I use a cheap USB cassette capture device, which advertises itself as an audio device when connected. On the software side, I use Tenacity (an Audacity fork), to capture the audio data to WAV files. In Tenacity, I captured the tapes with the following format: 44.1 KHz, 16-Bits, Mono.
For some tapes I got from eBay, I did a post-processing after the capturing step to improve the quality:
- Apply a low-pass filter (5600Hz)
- Apply a high-pass filter (3700Hz)
- Normalize (-6Db)
How to identify an Atari tape
Before proceeding, we must be sure that the captured tape is really an Atari
tape. For that, we can have a look at the
spectrogram. Atari uses
frequencies of 5327Hz (Mark
or 1
) and 3995Hz (Space
or 0
) to encode
data on the tape. Switching to the frequency domain (by enabling the
spectrogram in Tenacity), these distinct frequencies become clearly visible:
We see that the 20s lead tone is in the 5.3KHz range and that the other active frequency is somewhere right below 4KHz, which is characteristic for the Atari tape format.
Converting using Altirra or A8CAS tools
After successfully capturing the tape to a WAV file, we can start to
investigate what is actually stored on it. The WAV file can be loaded as a
virtual tape directly into Altirra. Since normally multiple programs are stored
on a single cassette tape, we need to position the tape on the desired
position first using Altirras Tape Control
dialog
(under File > Cassette > Tape Control ...
), or start at the beginning of
the tape and proceed by trial&error.
From my memory I remember that I stored BASIC programs on the tape. The
commands to load BASIC programs from tape on the Atari are CLOAD
, LOAD
and
ENTER
, depending on how they were stored before (see below for a more
detailed explanation on the differences). Since CLOAD
is the fastest format,
let’s try that first.
That looks good, a BASIC program was found and read without errors. Will it
also RUN
?
Finally we save the program in CAS
(an efficient storage format for tapes)
format using the File > Cassette > Save ...
command and selecting the CAS
format. The CAS
file, which is much smaller in size, can later be used
instead of the WAV file.
Fine tuning Altirra settings like disabling cassette turbo support or disabling
SIO acceleration for cassette or (System > Configure System ... > Acceleration > SIO device patches
)
might help on problems and should be used when saving data back as a WAV file.
Another possibility to convert a WAV file to a CAS file is to use the A8CAS-Tools:
$ a8cas-convert program.wav program.cas
Running the above command creates a CAS
file from the WAV
file that can be
directly used in an emulator.
How data is stored
Physical Atari tape format
The data is stored on the tape using Frequency-shifting
Keying (FSK) with 600 Baud
(physical bits per second). Two frequencies are used: Mark
(1-Bit) with 5327Hz
and Space
(0-Bit) with 3995Hz.
The format of a single byte is a sequence of start
bit (Space
), 8 data bits (starting with the LSB) and finally 1 stop bit
(Mark
). In total that is 10 bits written per byte. Every recording starts with
a ca. 20 seconds lead tone (Mark
).
Data is written in records of 132 bytes: 2 Marker bytes for synchronization
(0x55
or 0b01010101
in binary), a control byte followed by 128 data bytes
and finally a CRC byte for error detection. After and before every record,
gaps are written with the Mark
tone. The length depends on the logical
format (see below).
Go to The Atari Archives for a more detailed description.
Atari BASIC tape commands
Depending on how the data was saved to the tape, there are three different commands to load the data:
CLOAD
loads (BASIC) data stored withCSAVE
command previously. The data is stored in a tokenized format. Since only very short inter record gaps are used, this is the fastest format.LOAD
also uses a tokenized format, but has a 3s inter record gap between blocks. UseLOAD
when the data was stored with theSAVE
command.ENTER
loads data stored with theLIST
command, which stores a basic program in plain ATASCII code. This format uses also 3s inter record gaps and is therefore slower.
The longer inter record gaps in LIST
and SAVE
commands are needed to give
the Atari time to process a data block just read from the tape (e.g. tokenizing
BASIC code).
The difference between CLOAD
and LOAD
and ENTER
formats on the other
side, can easily be seen in the waveform:
Decoding a tape the hard way
Let’s see if we can read actual tape contents from the captured WAV directly.
For this, I saved a Basic program using the LIST
command, which writes the
code in plain ATASCII code to the tape. The first line of the basic program is
The following shows the zoomed in spectrogram with a window of size 64. Now the encoding of the individual bits becomes visible:
According to the Atari tape specification, the following on-tape byte sequence is expected for the first part of the above listing:
0x55
(Marker byte 1)0x55
(Marker byte 2)0xfc
(control byte)0x35
character5
(line number in the BASIC program)0x32
space character0x4f
,0x50
,0x45
,0x4e
- the wordOPEN
, the first command of the BASIC program
As mentioned, each byte starts with 0
(the start bit) and ends with 1
(the
stop bit) and is written with the LSB (least significant bit) first. Overall,
this makes 10 bit written to tape per byte.
Zooming into the spectrum makes the individual bits visible, and decoding
reveals the expected byte sequence of 0x55
,0x55
,…,0x4e
.
Summary
I was able to successfully restore almost 40 year old Atari cassette tapes using the approach described here relatively easy and reliable (however, some programs resisted to load successfully after conversion). Using today’s knowledge and tools like a spectrogram even made it possible to make the data visible in the capture of a tape.