This current concept is tested on the ZX Spectrum only and should permit to deal with a good number of to tape formats at once.
bit_tapion() gets the leading tone and uses it to calibrate the loading speed (which should also permit to support different CPU speeds at once).
It exits as soon as the first start bit is found, so a loader written in C should quickly issue a bit_tapin() sequence to get the next bytes being transmitted.
On exit, bit_tapiof() will restore the interrupts and eventually stop the motor (where supported).
To slightly modify the synchronization and support different formats I provided also bit_tapin_bit(), it will simply skip the next bit (e.g. in case the loading scheme requires 2 start bits).
Here's an example program, it will analyze the MSX tape format.
I think it works also on the Spectravideo SVI, the Philips VG-5000, P-6001 and others.
Similar programs could be written for many other formats.
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <sound.h>
int x;
unsigned int start,end,exec;
char name[6];
int type;
void main()
{
if (bit_tapion()==-1) exit (-1);
type=bit_tapin();
// This approach is valid ONLY on MSX, SVI, VG-5000 and those systems
// with the block type repeated 10 times
for (x=0; x<9; x++) {
if (bit_tapin() != type) exit (-2); // Exit if not a valid header
}
for (x=0; x<6; x++)
name[x]=bit_tapin();
bit_tapiof();
switch (type) {
case 0xD0:
printf ("\nFound BLOAD type block: %s",name);
if (bit_tapion()==-1) exit (1);
start=bit_tapin()+256*bit_tapin();
end=bit_tapin()+256*bit_tapin();
exec=bit_tapin()+256*bit_tapin();
bit_tapiof(); // Put a bit_tapin() loop here to load the data
printf ("\nStart: %u, Length: %u, Exec: %u", start, end-start, exec );
exit(type);
break;
case 0xD3:
printf ("\nFound CLOAD type block: %s",name);
if (bit_tapion()==-1) exit (1);
end=bit_tapin()+256*bit_tapin();
start=bit_tapin()+256*bit_tapin();
bit_tapiof(); // Put a bit_tapin() loop here to load the program data
printf ("\nLength: %u", end-start);
exit(type);
break;
default:
printf ("\nUnknown block type: %x", type );
break;
}
}