zx81: added tzx cassette format

This commit is contained in:
Nigel Barnes 2017-02-01 18:42:55 +00:00
parent 51992a75ec
commit d5bba41ed6
6 changed files with 63 additions and 64 deletions

View file

@ -8,7 +8,6 @@ TODO:
Add support for the remaining block types:
case 0x15: Direct Recording
case 0x18: CSW Recording
case 0x19: Generalized Data Block
case 0x21: Group Start
case 0x22: Group End
case 0x23: Jump To Block
@ -31,7 +30,7 @@ Notes:
TZX format specification lists
8064 pulses for a header block and 3220 for a data block
but the documentaiton on worldofspectrum lists
but the documentation on worldofspectrum lists
8063 pulses for a header block and 3223 for a data block
see http://www.worldofspectrum.org/faq/reference/48kreference.htm#TapeDataStructure
@ -315,7 +314,6 @@ static int tzx_handle_direct(int16_t **buffer, const uint8_t *bytes, int pause,
tzx_output_wave(buffer, samples);
size += samples;
}
}
@ -342,8 +340,6 @@ static inline int tzx_handle_symbol(int16_t **buffer, const uint8_t *symtable, u
uint8_t starttype = cursymb[0];
// printf("start polarity %01x (max number of symbols is %d)\n", starttype, maxp);
switch (starttype)
{
case 0x00:
@ -371,7 +367,6 @@ static inline int tzx_handle_symbol(int16_t **buffer, const uint8_t *symtable, u
for (int i = 0; i < maxp; i++)
{
uint16_t pulse_length = cursymb[1 + (i*2)] | (cursymb[2 + (i*2)] << 8);
// printf("pulse_length %04x\n", pulse_length);
// shorter lists can be terminated with a pulse_length of 0
if (pulse_length != 0)
@ -380,7 +375,6 @@ static inline int tzx_handle_symbol(int16_t **buffer, const uint8_t *symtable, u
tzx_output_wave(buffer, samples);
size += samples;
toggle_wave_data();
}
else
{
@ -390,8 +384,6 @@ static inline int tzx_handle_symbol(int16_t **buffer, const uint8_t *symtable, u
}
}
//toggle_wave_data();
return size;
}
@ -405,7 +397,6 @@ static inline int stream_get_bit(const uint8_t *bytes, uint8_t &stream_bit, uint
if (byte & 0x80) retbit = 1;
stream_bit++;
if (stream_bit == 8)
@ -433,34 +424,26 @@ static int tzx_handle_generalized(int16_t **buffer, const uint8_t *bytes, int pa
{
uint8_t symbol = table2[i + 0];
uint16_t repetitions = table2[i + 1] + (table2[i + 2] << 8);
//printf("symbol %02x repititions %04x\n", symbol, repetitions); // does 1 mean repeat once, or that it only occurs once?
//printf("symbol %02x repetitions %04x\n", symbol, repetitions); // does 1 mean repeat once, or that it only occurs once?
for (int j = 0; j < repetitions; j++)
{
size += tzx_handle_symbol(buffer, symtable, symbol, npp);
// toggle_wave_data();
}
}
// advance to after this data
bytes += ((2 * npp + 1)*asp) + totp * 3;
}
else
{
printf("no pilot block\n");
}
if (totd > 0)
{
printf("data block table %04x (has %0d symbols, max symbol length is %d)\n", totd, asd, npd);
// printf("data block table %04x (has %0d symbols, max symbol length is %d)\n", totd, asd, npd);
const uint8_t *symtable = bytes;
const uint8_t *table2 = bytes + (2 * npd + 1)*asd;
int NB = ceil(compute_log2(asd)); // number of bits needed to represent each symbol
printf("NB is %d\n", NB);
uint8_t stream_bit = 0;
uint32_t stream_byte = 0;
@ -475,16 +458,8 @@ static int tzx_handle_generalized(int16_t **buffer, const uint8_t *bytes, int pa
}
size += tzx_handle_symbol(buffer, symtable, symbol, npd);
//toggle_wave_data();
}
}
else
{
printf("no data block\n");
}
/* pause */
if (pause > 0)
@ -505,9 +480,7 @@ static int tzx_handle_generalized(int16_t **buffer, const uint8_t *bytes, int pa
static void ascii_block_common_log( const char *block_type_string, uint8_t block_type )
{
LOG_FORMATS("%s (type %02x) encountered.\n", block_type_string, block_type);
LOG_FORMATS("This block contains info on the .tzx file you are loading.\n");
LOG_FORMATS("Please include the following info in your bug reports, if the image has issue in M.E.S.S.\n");
LOG_FORMATS("%s (type %02x) encountered:\n", block_type_string, block_type);
}
static const char *const archive_ident[] =
@ -744,20 +717,18 @@ static int tzx_cas_do_work( int16_t **buffer )
{
// having this missing is fatal
// used crudely by batmanc in spectrum_cass list (which is just a redundant encoding of batmane ?)
printf("Unsupported block type (0x19 - Generalized Data Block) encountered.\n");
data_size = cur_block[1] + (cur_block[2] << 8) + (cur_block[3] << 16) + (cur_block[4] << 24);
pause_time= cur_block[5] + (cur_block[6] << 8);
uint32_t totp = cur_block[7] + (cur_block[8] << 8) + (cur_block[9] << 16) + (cur_block[10] << 24);
int npp = cur_block[11];
int asp = cur_block[12];
if (asp == 0) asp = 256;
if (asp == 0 && totp > 0) asp = 256;
uint32_t totd = cur_block[13] + (cur_block[14] << 8) + (cur_block[15] << 16) + (cur_block[16] << 24);
int npd = cur_block[17];
int asd = cur_block[18];
if (asd == 0) asd = 256;
if (asd == 0 && totd > 0) asd = 256;
size += tzx_handle_generalized(buffer, &cur_block[19], pause_time, data_size, totp, npp, asp, totd, npd, asd);
@ -840,7 +811,7 @@ static int tap_cas_to_wav_size( const uint8_t *casdata, int caslen )
{
int data_size = p[0] + (p[1] << 8);
int pilot_length = (p[2] == 0x00) ? 8064 : 3220; /* TZX specification */
// int pilot_length = (p[2] == 0x00) ? 8063 : 3223; /* worldofspectrum */
// int pilot_length = (p[2] == 0x00) ? 8063 : 3223; /* worldofspectrum */
LOG_FORMATS("tap_cas_to_wav_size: Handling TAP block containing 0x%X bytes", data_size);
p += 2;
size += tzx_cas_handle_block(nullptr, p, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
@ -859,7 +830,7 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes )
{
int data_size = bytes[0] + (bytes[1] << 8);
int pilot_length = (bytes[2] == 0x00) ? 8064 : 3220; /* TZX specification */
// int pilot_length = (bytes[2] == 0x00) ? 8063 : 3223; /* worldofspectrum */
// int pilot_length = (bytes[2] == 0x00) ? 8063 : 3223; /* worldofspectrum */
LOG_FORMATS("tap_cas_fill_wave: Handling TAP block containing 0x%X bytes\n", data_size);
bytes += 2;
size += tzx_cas_handle_block(&p, bytes, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
@ -871,34 +842,34 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, uint8_t *bytes )
static const struct CassetteLegacyWaveFiller tzx_legacy_fill_wave =
{
tzx_cas_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
tzx_cas_to_wav_size, /* chunk_sample_calc */
-1, /* chunk_size */
0, /* chunk_samples */
tzx_cas_to_wav_size, /* chunk_sample_calc */
TZX_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
0, /* header_samples */
0 /* trailer_samples */
};
static const struct CassetteLegacyWaveFiller tap_legacy_fill_wave =
{
tap_cas_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
tap_cas_to_wav_size, /* chunk_sample_calc */
-1, /* chunk_size */
0, /* chunk_samples */
tap_cas_to_wav_size, /* chunk_sample_calc */
TZX_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
0, /* header_samples */
0 /* trailer_samples */
};
static const struct CassetteLegacyWaveFiller cdt_legacy_fill_wave =
{
cdt_cas_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
tzx_cas_to_wav_size, /* chunk_sample_calc */
-1, /* chunk_size */
0, /* chunk_samples */
tzx_cas_to_wav_size, /* chunk_sample_calc */
TZX_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
0, /* header_samples */
0 /* trailer_samples */
};
static cassette_image::error tzx_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts )
@ -931,7 +902,7 @@ static cassette_image::error cdt_cassette_load( cassette_image *cassette )
return cassette_legacy_construct(cassette, &cdt_legacy_fill_wave);
}
static const struct CassetteFormat tzx_cassette_format =
const struct CassetteFormat tzx_cassette_format =
{
"tzx",
tzx_cassette_identify,

View file

@ -12,6 +12,8 @@
#include "cassimg.h"
extern const struct CassetteFormat tzx_cassette_format;
CASSETTE_FORMATLIST_EXTERN(tzx_cassette_formats);
CASSETTE_FORMATLIST_EXTERN(cdt_cassette_formats);

View file

@ -34,6 +34,7 @@ medium transfer rate is approx. 307 bps (38 bytes/sec) for files that contain
#include <assert.h>
#include "zx81_p.h"
#include "tzx_cas.h"
#define WAVEENTRY_LOW -32768
@ -197,13 +198,13 @@ static int zx81_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes)
static const struct CassetteLegacyWaveFiller zx81_legacy_fill_wave =
{
zx81_cassette_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
zx81_cassette_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
zx81_cassette_calculate_size_in_samples, /* chunk_sample_calc */
ZX81_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
ZX81_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
};
static cassette_image::error zx81_p_identify(cassette_image *cassette, struct CassetteOptions *opts)
@ -233,6 +234,11 @@ CASSETTE_FORMATLIST_START(zx81_p_format)
CASSETTE_FORMAT(zx81_p_image_format)
CASSETTE_FORMATLIST_END
CASSETTE_FORMATLIST_START(zx81_cassette_formats)
CASSETTE_FORMAT(zx81_p_image_format)
CASSETTE_FORMAT(tzx_cassette_format)
CASSETTE_FORMATLIST_END
/* ZX-80 functions */
static int zx80_cassette_calculate_size_in_samples(const uint8_t *bytes, int length)
@ -265,11 +271,11 @@ static int zx80_cassette_fill_wave(int16_t *buffer, int length, uint8_t *bytes)
static const struct CassetteLegacyWaveFiller zx80_legacy_fill_wave =
{
zx80_cassette_fill_wave, /* fill_wave */
zx80_cassette_fill_wave, /* fill_wave */
-1, /* chunk_size */
0, /* chunk_samples */
zx80_cassette_calculate_size_in_samples, /* chunk_sample_calc */
ZX81_WAV_FREQUENCY, /* sample_frequency */
ZX81_WAV_FREQUENCY, /* sample_frequency */
0, /* header_samples */
0 /* trailer_samples */
};

View file

@ -14,6 +14,7 @@
#include "cassimg.h"
CASSETTE_FORMATLIST_EXTERN(zx81_p_format);
CASSETTE_FORMATLIST_EXTERN(zx81_cassette_formats);
CASSETTE_FORMATLIST_EXTERN(zx80_o_format);
#endif /* ZX81_P_H */

View file

@ -339,11 +339,15 @@ static MACHINE_CONFIG_START( zx80, zx_state )
MCFG_CASSETTE_ADD( "cassette" )
MCFG_CASSETTE_FORMATS(zx80_o_format)
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED)
MCFG_CASSETTE_INTERFACE("zx80_cass")
/* software lists */
MCFG_SOFTWARE_LIST_ADD("cass_list", "zx80_cass")
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("1K")
MCFG_RAM_EXTRA_OPTIONS("16K,32K,48K")
MCFG_RAM_EXTRA_OPTIONS("1K,2K,3K,16K")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( zx81, zx80 )
@ -352,7 +356,16 @@ static MACHINE_CONFIG_DERIVED( zx81, zx80 )
MCFG_CPU_IO_MAP(zx81_io_map)
MCFG_CASSETTE_MODIFY( "cassette" )
MCFG_CASSETTE_FORMATS(zx81_p_format)
MCFG_CASSETTE_FORMATS(zx81_cassette_formats)
MCFG_CASSETTE_INTERFACE("zx81_cass")
/* software lists */
MCFG_SOFTWARE_LIST_MODIFY("cass_list", "zx81_cass")
/* internal ram */
MCFG_RAM_MODIFY(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("1K")
MCFG_RAM_EXTRA_OPTIONS("16K,32K,48K")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( zx81_spk, zx81 )
@ -368,6 +381,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( ts1000, zx81 )
MCFG_PALETTE_MODIFY("palette")
MCFG_PALETTE_INIT_OWNER(zx_state, ts1000)
/* internal ram */
MCFG_RAM_MODIFY(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("2K")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( ts1500, ts1000 )
@ -473,6 +490,7 @@ ROM_END
/* Game Drivers */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1980, zx80, 0, 0, zx80, zx80, zx_state, zx, "Sinclair Research Ltd", "ZX-80", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )
COMP( 1981, zx81, 0, 0, zx81, zx81, zx_state, zx, "Sinclair Research Ltd", "ZX-81", MACHINE_NO_SOUND_HW )
COMP( 1982, ts1000, zx81, 0, ts1000, zx81, zx_state, zx, "Timex Sinclair", "Timex Sinclair 1000", MACHINE_NO_SOUND_HW )
@ -482,4 +500,4 @@ COMP( 1983, ringo470, zx81, 0, ts1000, zx81, zx_state, zx,
COMP( 1984, pc8300, zx81, 0, pc8300, pc8300, zx_state, zx, "Your Computer", "PC8300", MACHINE_NOT_WORKING )
COMP( 1983, pow3000, zx81, 0, pow3000, pow3000, zx_state, zx, "Creon Enterprises", "Power 3000", MACHINE_NOT_WORKING )
COMP( 1982, lambda, zx81, 0, pow3000, pow3000, zx_state, zx, "Lambda Electronics Ltd", "Lambda 8300", MACHINE_NOT_WORKING )
COMP( 1997, zx97, zx81, 0, zx81, zx81, zx_state, zx, "Wilf Rigter", "ZX97", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_UNOFFICIAL )
COMP( 1997, zx97, zx81, 0, zx81, zx81, zx_state, zx, "Wilf Rigter", "ZX97", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_UNOFFICIAL )

View file

@ -15,6 +15,7 @@
#include "sound/wave.h"
#include "imagedev/cassette.h"
#include "formats/zx81_p.h"
#include "formats/tzx_cas.h"
#include "machine/ram.h"