Square waves with a 50% duty cycle, often referred to as pulses. A sequence of bits is therefore encoded as a sequence of square waves on tape, back-to-back.
The standard Commodore ROM encoding method uses three distinct pulses.
- “Short pulses” at 2840 Hz (period = 352 microseconds about). (S)hort : TAP value $30.
- “Medium pulses” at 1953 Hz (period = 512 microseconds about). (M)edium : TAP value $42.
- “Long pulses” with a frequency of 1488 Hz (period = 672 microseconds about). (L)ong : TAP value $56.
Any definition of these durations would be more appropriately expressed in clock cycles, rather than absolute timings. The reason for this is that the number of clock cycles that make up each pulse is independent of the machine. Where the actual duration in seconds depends on the CPU frequency of the machine itself.
Also pulses are always interpreted as a pair:
- (S,M) = 0 bit
- (M,S) = 1 bit
- (L,M) = new-data marker
- (L,S) = end-of-data marker
Leader and Framing
A ten second leader is written on the tape before recording of the data or program commences.
This leader has two functions:
- First it allows the tape motor to reach the correct speed.
- Secondly the sequence of short pulses written on the leader is used to synchronize the read routine timing to the timing on the tape.
The operating system can thus produce a correction factor which allows a very wide variation in tape speed without affecting reading.
Each data byte is organized as follows:
(B0) (B1) (B2) (B3) (B4) (B5) (B6) (B7) (CB) (DM)
bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 Checkbit Data marker
Each byte is encoded as a sequence of 20 pulses (10 pairs):
8 bits of information in LSbF format.
1 checkbit which is computed as: 1 XOR bit0 XOR bit1 XOR bit2 XOR bit3 XOR bit4 XOR bit5 XOR bit6 XOR bit7.
1 data marker: the data is finished when you read an "end-of-data marker" (L,S) instead of (L,M).
When a VIC20 or a C64 save a "BASIC program" or a "PRG file" to tape with the following:
- SAVE "MY PROGRAM", 1 (BASIC program)
- SAVE "MY PROGRAM", 1, 1 (PRG file)
It creates 4 files:
- HEADER REPEATED silence (roughly 0.4 seconds)
- DATA REPEATED
Sometimes the header is segmented and if required then encapsulated into HEADER files.
A padding is automatically done, if required, since HEADER payload has a standard length (191 bytes).
An empty HEADER (all "File name" and "body" bytes are $20) comes before data:
HEADER - SEQ file header HEADER - SEQ file header, REPEATED.
One or more of these follow, depending on the SEQ data size:
silence (duration is variable) HEADER - Data block for SEQ file HEADER - Data block for SEQ file, REPEATED.
If an "End-of-tape marker" is requested the OS saves an additional empty HEADER just after the last "Data block for SEQ file"
Silence (around 0.34 seconds) HEADER - End-of-tape marker HEADER - End-of-tape marker, REPEATED.
Pilot, Sync, Header, Data, Trailer
Pilot is the various amount of Short pulses.
The amount of pulses are:
- $6A00 for HEADER.
- $1A00 for DATA, and HEADER when it contains "Data block for SEQ file".
- $4F for HEADER REPEATED and DATA REPEATED.
Sync: a new data marker, followed by a sync chain (9 bytes):
Alas HEADER and DATA blocks have the following sequence:
- $89 $88 $87 $86 $85 $84 $83 $82 $81
Both HEADER REPEATED and DATA REPEATED blocks have the same sequence with bit 7 clear:
- $09 $08 $07 $06 $05 $04 $03 $02 $01
For any HEADER the following information is sent after the sync sequence:
- 1 Byte, File type
- $01= BASIC program
- $02= Data block for SEQ file
- $03= PRG file
- $04= SEQ file header
- $05= End-of-tape marker
Here starts what is referred to as HEADER "payload".
In case File type is not $02, the following informations are sent too:
- 2 Bytes : Start Address (LSBF)
- 2 Bytes : End Address+1 (LSBF)
- 16 Bytes : File Name
When File type is $02, SEQ file data starts immediately after File Type thus allowing the use of those 20 bytes to store additional data, After the File Name there is HEADER "body", 171 bytes, often used by commercial loaders to store executable loader code or pretty much any additional data or code the loader or program may require. It encapsulates Data for segmented SEQ files too, as discussed above.
- Data checkbyte (its data marker is "end-of-data marker").
- Compiled as: 0 XOR all other HEADER bytes, from "File type" to end of "body".
For any DATA the following information is sent after the sync sequence:
DATA body Last Byte:
Data checkbyte (its data marker is "end-of-data marker"), compiled as: 0 XOR all DATA "body" bytes.
Some trailing tones ('S' pulses) follow both HEADER REPEATED and DATA REPEATED.
The standard amount is $4E pulses. C64.
HEADER blocks always load into the Tape Buffer at $033C.
If the File Type is 'BASIC Program' the start address for loading will be $0801 regardless of what may be written in the 'Start Address' field.
Turbo Load and Conclusion
Almost every marketed C64 tape software uses some form of Turbo Loader. The origin of these Turbo Loaders is rather obscure since many of the software houses use the same routines.A Turbo Loader is a routine which must be loaded into C64 RAM before being executed and therefore every Turbo Loader routine is stored in a Standard CBM encoded “boot” file. Usually a part of the Turbo Loader routines is stored in the CBM file Header and therefore loaded in the tape buffer (at $033C-$03FB). When the standard LOAD ends, the operating system executes various operations, one of which is printing the “READY.” message on the C64 screen.By default, at $0326/$0327 there's the start address of the onscreen print routine (remember any of the 64K memory addresses can be identified by 2 bytes, low significant part first and then most significant. When executed, a Turbo Loader “replaces” the existing LOAD and allows a program or data to be loaded from tape at a faster speed than the normal LOAD and to not be misled it was executed with left arrow + L.