Пример #1
0
static cassette_image::error sc3000_bit_load(cassette_image *cassette)
{
	cassette_image::error err;
	UINT64 image_size = cassette_image_size(cassette);
	UINT64 image_pos = 0;
	double time_index = 0.0;
	double time_displacement;
	UINT8 data;

	while (image_pos < image_size)
	{
		cassette_image_read(cassette, &data, image_pos, 1);

		switch (data)
		{
		case '1':
			MODULATE(1);
			break;

		case '0':
			MODULATE(0);
			break;

		case ' ':
			err = cassette_put_sample( cassette, 0, time_index, 1/1200.0, 0);
			if (err != cassette_image::error::SUCCESS) return err;
			time_index += 1/1200.0;
			break;
		}

		image_pos++;
	}

	return cassette_image::error::SUCCESS;
}
Пример #2
0
static cassette_image::error csw_cassette_identify( cassette_image *cassette, struct CassetteOptions *opts )
{
	uint8_t header[22];

	cassette_image_read(cassette, header, 0, sizeof(header));
	if (memcmp(&header[0], CSW_HEADER, sizeof(CSW_HEADER) - 1)) {
		return cassette_image::error::INVALID_IMAGE;
	}
	return cassette_legacy_identify( cassette, opts, &csw_legacy_fill_wave );
}
Пример #3
0
static casserr_t mo5_k5_load( cassette_image *cass )
{
	size_t size = cassette_image_size( cass ), pos = 0;
	int i, sz, sz2, hbit = 0;
	UINT8 in, in2, in3, typ, block[264], sum;
	int invalid = 0, hbitsize = 0, dcmoto = 0;

	LOG (( "mo5_k5_load: start conversion, size=%li\n", (long)size ));
	PRINT (( "mo5_k5_load: open cassette, length: %li bytes\n", (long) size ));

	/* store a half-bit */
#define K5_PUT_HBIT                         \
	do                              \
	{                               \
		cassette_put_sample ( cass, 0, hbitsize * MO5_HBIT_LENGTH, MO5_HBIT_LENGTH, (hbit ? 1 : -1) << 30 ); \
		hbitsize++;                     \
	} while ( 0 )

	/* store one bit */
#define K5_PUT_BIT( BIT )           \
	do                  \
	{                   \
		if ( BIT )          \
		{               \
			K5_PUT_HBIT;        \
			hbit = !hbit;       \
			K5_PUT_HBIT;        \
		}               \
		else                \
		{               \
			K5_PUT_HBIT;        \
			K5_PUT_HBIT;        \
		}               \
		hbit = !hbit;           \
	} while (0)

	/* store one byte, no start / stop bit, converse order from TO7 */
#define K5_PUT_BYTE( BYTE ) \
	do                          \
	{                           \
		UINT8 b = BYTE;                 \
		int x;                      \
		for ( x = 0; x < 8; x++ )           \
			K5_PUT_BIT( (b >> (7 - x)) & 1 );   \
	} while (0)

	/* store filler */
#define K5_FILL_0( SIZE ) \
	do                              \
	{                               \
		if ( (SIZE) > 0 )                   \
		{                           \
			int j;                      \
			LOG (( "mo5_k5_load: 0-filler size=%i hbitstart=%i\n", (SIZE), hbitsize )); \
			for ( j = 0; j < (SIZE); j++ )          \
				K5_PUT_BIT( 0 );            \
		}                           \
	} while (0)

#define K5_FILL_01( SIZE )                      \
	do                              \
	{                               \
		if ( (SIZE) > 0 )                   \
		{                           \
			int j;                      \
			LOG (( "mo5_k5_load: 0x01 filler size=%i bitstart=%i\n", (SIZE), hbitsize )); \
			for ( j = 0; j < (SIZE); j++ )          \
				K5_PUT_BYTE( 0x01 );            \
		}                           \
	} while (0)

	/* check format */
	cassette_image_read( cass, block, 0, 64 );
	for ( i = 3; ; i++ )
	{
		if ( ( i >= size ) || ( i >= 64 ) )
		{
			/* ? */
			PRINT (( "to5_k5_load: WARNING: this does not look like a MO or TO cassette.\n" ));
			break;
		}
		else if ( ( block[i-3] == 0x01 ) && ( block[i-2] == 0x3c ) && ( block[i-1] == 0x5a ) && ! block[i] )
		{
			/* MO */
			break;
		}
		else if ( ( block[i-3] == 0xff ) && ( block[i-2] == 0x01 ) && ( block[i-1] == 0x3c ) && ! block[i] )
		{
			/* TO */
			PRINT (( "to5_k5_load: WARNING: this looks like a TO cassette, not a MO one.\n" ));
			break;
		}
	}

	cassette_image_read( cass, block, pos, 6 );
	if ( ! memcmp( block, "DCMOTO", 6 ) || ! memcmp( block, "DCMO5", 5 ) || ! memcmp( block, "DCMO6", 5 ) )
		dcmoto = 1;

	/* loop over regular blocks */
	while ( pos < size )
	{
	rebounce:
		/* skip DCMOTO header*/
		if ( dcmoto )
		{
			cassette_image_read( cass, block, pos, 6 );
			if ( ! memcmp( block, "DCMOTO", 6 ) )
			{
				LOG (( "mo5_k5_load: DCMOTO signature found at off=$%x\n", (int)pos ));
				pos += 6;
			}
			else if ( ! memcmp( block, "DCMO", 4 ) )
			{
				LOG (( "mo5_k5_load: DCMO* signature found at off=$%x\n", (int)pos ));
				pos += 5;
			}
		}

		/* skip 0x01 filler */
		for ( sz = 0; pos < size; pos++, sz++ )
		{
			cassette_image_read( cass, &in, pos, 1 );
			if ( in != 0x01 )
				break;
		}

		/* get block header */
		if ( pos + 4 > size )
		{
			pos -= sz;
			break;
		}
		cassette_image_read( cass, block, pos, 4 );
		typ = block[2];
		sz2 = (UINT8) (block[3]-1);
		if ( block[0] != 0x3c || block[1] != 0x5a || ( typ != 0x00 && typ != 0x01 && typ !=  0xff ) || pos+sz2 > size )
		{
			pos -= sz;
			break;
		}
		pos += 4;

		/* get block */
		cassette_image_read( cass, block+4, pos, sz2 );
		pos += sz2;

		/* 0-fillers and 0x01-fillers */
		if ( typ == 0 || typ == 0xff )
			K5_FILL_0( 1200 );
		else
			K5_FILL_0( 300 ); /* for MO6 */
		K5_FILL_01( sz < 10 ? 10 : sz );

		/* put block */
		LOG (( "mo5_k5_load: block off=$%x type=$%02X size=%i hbitstart=%i\n", (int) pos-sz2-4, typ, sz2, hbitsize ));
		VLOG (( "mo5_k5_load: data:" ));
		for ( i = 0; i < sz2 + 4; i ++)
		{
			VLOG (( " $%02X", block[i] ));
			K5_PUT_BYTE( block[i] );
		}
		VLOG (( "\n" ));

		/* checksum */
		for ( i = 0, sum = 0; i < sz2; i++ )
			sum += block[i+4];
		if ( sum )
			LOG(( "mo5_k5_load: invalid checksum $%02X (should be 0)\n", sum ));

		/* if it is a directory enty, says so to the user */
		if ( typ == 0 )
		{
			char name[] = "01234567.ABC";
			UINT8 t = block[15];
			UINT8 u = block[16];
			int p = (hbitsize - sz2 - 4 - sz) * MO5_HBIT_LENGTH;
			memcpy( name, block+4, 8 );
			memcpy( name+9, block+12, 3 );
			for ( i = 0; name[i]; i++)
			{
				if ( name[i] < ' ' || name[i] >= 127 )
					name[i] = '?';
			}
			PRINT (( "mo5_k5_load: file \"%s\" type=%s,%s at %imn %is\n",
					name,
					(t==0) ? "bas" : (t==1) ? "dat" : (t==2) ? "bin" : "???",
					(u == 0) ? "a" : (u == 0xff) ? "b" : "?",
					p / 60, p % 60 ));
		}

		/* 0-fillers */
		if ( typ == 0xff || typ == 0x00 )
			K5_FILL_0( 1800 );
	}

	/* dump trailing bytes, but also look for beginnings of blocks */
	if ( pos < size )
	{
		invalid++;
		K5_FILL_0( 1200 );
		LOG (( "mo5_k5_load: trailing trash off=$%x size=%i hbitstart=%i\n", (int) pos, (int) (size-pos), hbitsize ));
		for ( ; pos < size; pos++ )
		{
			cassette_image_read( cass, &in, pos, 1 );
			if ( dcmoto && in=='D' )
			{
				/* skip DCMOTO header*/
				cassette_image_read( cass, block, pos, 6 );
				if ( ! memcmp( block, "DCMOTO", 6 ) )
				{
					LOG (( "mo5_k5_load: DCMOTO signature found at off=$%x\n", (int)pos ));
					pos += 6;
					cassette_image_read( cass, &in, pos, 1 );
				}
				else if ( ! memcmp( block, "DCMO", 4 ) )
				{
					LOG (( "mo5_k5_load: DCMO* signature found at off=$%x\n", (int)pos ));
					pos += 5;
					cassette_image_read( cass, &in, pos, 1 );
				}
			}
			for ( sz = 0; pos < size && in == 0x01; sz++ )
			{
				pos++;
				cassette_image_read( cass, &in, pos, 1 );
			}
			if ( sz > 6 )
			{
				cassette_image_read( cass, &in2, pos+1, 1 );
				cassette_image_read( cass, &in3, pos+2, 1 );
				if ( invalid < 10 &&  in == 0x3c && in2 == 0x5a && (in3 == 0x00 || in3 == 0x01 || in3 == 0xff ) )
				{
					/* regular block found */
					LOG (( "mo5_k5_load: hidden regular block found\n" ));
					pos -= sz;
					goto rebounce;
				}
				if ( invalid < 10 && sz > 6 && ( (in == 0x3c && in2 == 0x5a) || (in == 0xc3 && in2 == 0x5a) || (in == 0xc3 && in2 == 0x3c) || (in == 0x87 && in2 == 0x4a)  ) )
				{
					/* special block found */
					K5_FILL_0( 1200 );
					LOG (( "mo5_k5_load: special block $%02X $%02X found off=$%x hbitstart=%i\n", in, in2, (int) pos-sz, hbitsize ));
				}
			}

			VLOG (( "mo5_k5_load: special data:" ));
			for ( i = 0; i < sz; i++ )
			{
				K5_PUT_BYTE( 0x01 );
				VLOG (( " $01" ));
			}
			K5_PUT_BYTE( in );
			VLOG (( " $%02X\n", in ));
		}
	}

	if ( invalid )
		PRINT (( "mo5_k5_load: WARNING: the k5 has an unknown structure and may not work\n" ));

	sz = hbitsize * MO5_HBIT_LENGTH;
	PRINT (( "mo5_k5_load: cassette length: %imn %is (%i half-bits)\n", sz / 60, sz % 60, hbitsize ));

	return CASSETTE_ERROR_SUCCESS;
}
Пример #4
0
static casserr_t to7_k7_load( cassette_image *cass )
{
#if ! K7_SPEED_HACK
	static const INT8 square_wave[] = { -128, 127 };
	double time = 0.;
#endif
	size_t size = cassette_image_size( cass ), pos = 0;
	int i, sz, sz2, bitmax = 1024, invalid = 0;
	UINT8 in, typ, block[264];

	LOG (( "to7_k7_load: start conversion, size=%li\n", (long)size ));
	PRINT (( "to7_k7_load: open cassette, length: %li bytes\n", (long) size ));

	if ( to7_k7_bits )
	{
		free( to7_k7_bits );
		to7_k7_bits = NULL;
	}

	to7_k7_bitsize = 0;
	to7_k7_bits = (UINT8*)malloc(bitmax );

/* store one period */
#if K7_SPEED_HACK
#define K7_PUT( PERIOD )
#else
#define K7_PUT( PERIOD ) \
	do                              \
	{                               \
		casserr_t err;                      \
		err = cassette_put_samples( cass, 0, time, (PERIOD), 2, 1, \
						square_wave, CASSETTE_WAVEFORM_8BIT ); \
		if ( err )                      \
			return err;                 \
		time += (PERIOD);                   \
	} while (0)
#endif

/* store one bit */
#define K7_PUT_BIT( BIT ) \
	do                              \
	{                               \
		int b;                          \
		if ( BIT )                      \
		{                           \
			for ( b = 0; b < 7; b++ )           \
				K7_PUT( TO7_PERIOD_CASS_1 );        \
		}                           \
		else                            \
		{                           \
			for ( b = 0; b < 5; b++ )           \
				K7_PUT( TO7_PERIOD_CASS_0 );        \
		}                           \
		if ( to7_k7_bitsize + 1 >= bitmax )         \
		{                           \
			UINT8* a = (UINT8*)malloc(bitmax * 2);      \
			memcpy ( a, to7_k7_bits, bitmax );      \
			bitmax *= 2;                    \
			to7_k7_bits = a;                \
		}                           \
		to7_k7_bits[ to7_k7_bitsize++ ] = (BIT);        \
	} while (0)

/* store one byte, with start / stop bits */
#define K7_PUT_BYTE( BYTE ) \
	do                          \
	{                           \
		UINT8 x;                    \
		K7_PUT_BIT( 0 );                \
		for ( x = 0; x < 8; x++ )           \
			K7_PUT_BIT( ( (BYTE) >> x ) & 1 );  \
		K7_PUT_BIT( 1 );                \
		K7_PUT_BIT( 1 );                \
	} while (0)

#define K7_FILL_1( SIZE ) \
	do                              \
	{                               \
		if ( (SIZE) > 0 ) {                 \
			int ii;                     \
			LOG (( "to7_k7_load: 1-filler size=%i bitstart=%i\n", \
					(SIZE), to7_k7_bitsize ));      \
			for ( ii = 0; ii < (SIZE); ii++ ) K7_PUT_BIT( 1 ); \
		}                           \
	} while (0)

#define K7_FILL_ff( SIZE ) \
	do                              \
	{                               \
		if ( (SIZE) > 0 )                   \
		{                           \
			int ii;                     \
			LOG (( "to7_k7_load: 0xff filler size=%i bitstart=%i\n",  (SIZE), to7_k7_bitsize )); \
			for ( ii = 0; ii < (SIZE); ii++ )       \
				K7_PUT_BYTE( 0xff );            \
		}                           \
	} while (0)

	/* check format */
	cassette_image_read( cass, block, 0, 64 );
	for ( i = 3; ; i++ )
	{
		if ( ( i >= size ) || ( i >= 64 ) )
		{
			/* ? */
			PRINT (( "to7_k7_load: WARNING: this does not look like a MO or TO cassette.\n" ));
			break;
		}
		else if ( ( block[i-3] == 0x01 ) && ( block[i-2] == 0x3c ) && ( block[i-1] == 0x5a ) && ! block[i] )
		{
			/* MO */
			PRINT (( "to7_k7_load: WARNING: this looks like a MO cassette, not a TO one.\n" ));
			break;
		}
		else if ( ( block[i-3] == 0xff ) && ( block[i-2] == 0x01 ) && ( block[i-1] == 0x3c ) && ! block[i] )
		{
			/* TO */
			break;
		}
	}

	/* skip to first 0xff filler */
	for ( sz = 0; pos < size; pos++, sz++ )
	{
		cassette_image_read( cass, &in, pos, 1 );
		if ( in == 0xff )
			break;
	}
	if ( sz > 0 )
		LOG (( "to7_k7_load: skip %i trash bytes\n", sz ));

	/* loop over regular blocks */
	while ( pos < size )
	{
	rebounce:
		/* skip 0xff filler */
		for ( sz = 0; pos < size; pos++, sz++ )
		{
			cassette_image_read( cass, &in, pos, 1 );
			/* actually, we are bit laxist and treat as 0xff bytes with at least
			   5 bits out of 8 set to 1
			*/
			for ( i = 0; in; in >>= 1 )
				i += (in & 1);
			if ( i < 5 )
				break;
		}

		/* get block header */
		if ( pos + 4 > size )
		{
			pos -= sz;
			break;
		}
		cassette_image_read( cass, block, pos, 4 );
		typ = block[2];
		sz2 = block[3]+1;
		if ( block[0] != 0x01 || block[1] != 0x3c || ( typ != 0x00 && typ != 0x01 && typ !=  0xff ) )
		{
			pos -= sz;
			break;
		}
		pos += 4;

		/* get block */
		cassette_image_read( cass, block+4, pos, sz2 );
		pos += sz2;

		/* 1-filler and 0xff-filler */
		if ( typ == 0 || typ == 0xff )
			K7_FILL_1( 1000 );
		K7_FILL_ff( sz );

		/* put block */
		LOG (( "to7_k7_load: block off=$%x type=$%02X size=%i bitstart=%i\n", (int) pos-sz2-4, typ, sz2, to7_k7_bitsize ));
		VLOG (( "to7_k7_load: data:" ));
		for ( i = 0; i < sz2 + 4; i ++)
		{
			VLOG (( " $%02X", block[i] ));
			K7_PUT_BYTE( block[i] );
		}
		VLOG (( "\n" ));

		/* if it is a directory enty, says so to the user */
		if ( typ == 0 )
		{
			char name[] = "01234567.ABC";
			UINT8 t = block[15];
			UINT8 u = block[16];
			int p = (to7_k7_bitsize - sz2 - 4 - sz) * TO7_BIT_LENGTH;
			memcpy( name, block+4, 8 );
			memcpy( name+9, block+12, 3 );
			for ( i = 0; name[i]; i++)
			{
				if ( name[i] < ' ' || name[i] >= 127 )
					name[i] = '?';
			}
			PRINT (( "to7_k7_load: file \"%s\" type=%s,%s at %imn %is\n",
					name,
					(t==0) ? "bas" : (t==1) ? "dat" : (t==2) ? "bin" : "???",
					(u == 0) ? "a" : (u == 0xff) ? "b" : "?",
					p / 60, p % 60 ));
		}

		/* extra 1-fillers */
		if ( typ == 0 || typ == 0xff )
			K7_FILL_1( 1000 );
	}

	/* trailing data with invalid block structure
	   => dump it in a raw form, but stay alert for hidden block starts
	*/
	if ( pos < size )
	{
		invalid++;
		LOG (( "to7_k7_load: trailing raw bytes off=$%x bitstart=%i\n", (int) pos, to7_k7_bitsize ));

		/* put block */
		for (; pos < size; pos++ )
		{
			cassette_image_read( cass, &in, pos, 1 );
			for ( sz = 0; pos < size && in == 0xff; sz++ )
			{
				pos++;
				cassette_image_read( cass, &in, pos, 1 );
			}
			if ( invalid < 10 && sz > 4 && in == 0x01 && pos + 4 <= size )
			{
				UINT8 in1,in2;
				cassette_image_read( cass, &in1,   pos+1, 1 );
				cassette_image_read( cass, &in2, pos+2, 1 );
				if ( (in1 == 0x3c) && ((in2 == 0x00) || (in2 == 0x01) ) )
				{
					/* seems we have a regular block hidden in raw data => rebounce */
					LOG (( "to7_k7_load: hidden regular block found\n" ));
					pos -= sz;
					goto rebounce;
				}
				if ( ( ( in1 == 0x3d ) && ( in2 == 0 ) ) || ( ( in1 == 0x57 ) && ( in2 == 0x49 ) ) )
				{
					/* special block (Infogrames) => just prepend filler */
					K7_FILL_1 ( 500 );
					LOG (( "to7_k7_load: special $%02X $%02X $%02X block found off=$%x bitstart=%i\n", in, in1, in2, (int) pos, to7_k7_bitsize ));
				}
			}
			for ( i = 0; i < sz; i++ )
				K7_PUT_BYTE( 0xff );
			K7_PUT_BYTE( in );
		}
	}

	if ( invalid )
		PRINT (( "to7_k7_load: WARNING: the k7 has an unknown structure and may not work\n" ));

	sz = to7_k7_bitsize * TO7_BIT_LENGTH;
	PRINT (( "to7_k7_load: cassette length: %imn %is (%i samples)\n", sz / 60, sz % 60, to7_k7_bitsize ));

	return CASSETTE_ERROR_SUCCESS;
}
Пример #5
0
static casserr_t wavfile_process(cassette_image *cassette, struct CassetteOptions *opts,
	int read_waveform)
{
	UINT8 file_header[12];
	UINT8 tag_header[8];
	UINT8 format_tag[16];
	UINT32 stated_size;
	UINT64 file_size;
	UINT32 tag_size;
	UINT32 tag_samples;
	UINT64 offset;
	int format_specified = FALSE;

	UINT16 format_type = 0;
	UINT32 bytes_per_second = 0;
//  UINT16 block_align = 0;
	int waveform_flags = 0;

	/* read header */
	cassette_image_read(cassette, file_header, 0, sizeof(file_header));
	offset = sizeof(file_header);

	/* check magic numbers */
	if (memcmp(&file_header[0], magic1, 4))
		return CASSETTE_ERROR_INVALIDIMAGE;
	if (memcmp(&file_header[8], magic2, 4))
		return CASSETTE_ERROR_INVALIDIMAGE;

	/* read and sanity check size */
	stated_size = get_leuint32(&file_header[4]) + 8;
	file_size = cassette_image_size(cassette);
	if (stated_size > file_size)
		stated_size = (UINT32) file_size;

	while(offset < stated_size)
	{
		cassette_image_read(cassette, tag_header, offset, sizeof(tag_header));
		tag_size = get_leuint32(&tag_header[4]);
		offset += sizeof(tag_header);

		if (!memcmp(tag_header, format_tag_id, 4))
		{
			/* format tag */
			if (format_specified || (tag_size < sizeof(format_tag)))
				return CASSETTE_ERROR_INVALIDIMAGE;
			format_specified = TRUE;

			cassette_image_read(cassette, format_tag, offset, sizeof(format_tag));

			format_type             = get_leuint16(&format_tag[0]);
			opts->channels          = get_leuint16(&format_tag[2]);
			opts->sample_frequency  = get_leuint32(&format_tag[4]);
			bytes_per_second        = get_leuint32(&format_tag[8]);
//          block_align             = get_leuint16(&format_tag[12]);
			opts->bits_per_sample   = get_leuint16(&format_tag[14]);

			if (format_type != WAV_FORMAT_PCM)
				return CASSETTE_ERROR_INVALIDIMAGE;
			if (opts->sample_frequency * opts->bits_per_sample * opts->channels / 8 != bytes_per_second)
				return CASSETTE_ERROR_INVALIDIMAGE;

			switch(opts->bits_per_sample)
			{
				case 8:
					waveform_flags = CASSETTE_WAVEFORM_8BIT | CASSETTE_WAVEFORM_UNSIGNED;   // 8-bits wav are stored unsigned
					break;
				case 16:
					waveform_flags = CASSETTE_WAVEFORM_16BITLE;
					break;
				case 32:
					waveform_flags = CASSETTE_WAVEFORM_32BITLE;
					break;
				default:
					return CASSETTE_ERROR_INVALIDIMAGE;
			}
		}
		else if (!memcmp(tag_header, data_tag_id, 4))
		{
			/* data tag */
			if (!format_specified)
				return CASSETTE_ERROR_INVALIDIMAGE;

			if (read_waveform)
			{
				tag_samples = tag_size / (opts->bits_per_sample / 8) / opts->channels;
				cassette_read_samples(cassette, opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency),
					tag_samples, offset, waveform_flags);
			}
		}
		else
		{
			/* ignore other tags */
		}
		offset += tag_size;
	}

	return CASSETTE_ERROR_SUCCESS;
}
Пример #6
0
static int get_cas_block(cassette_image *cassette, UINT64 *offset, UINT8 *block, int *block_len)
{
	UINT8 block_length = 0;
	UINT8 block_checksum = 0;
	UINT64 current_offset;
	UINT64 image_size;
	PAIR p;
	int i;
	int state = 0;
	int phase = 0;

	synccount = 0;
	p.w.l = 0;
	image_size = cassette_image_size(cassette);
	current_offset = *offset;

	while(current_offset < image_size)
	{
		cassette_image_read(cassette, &p.b.h, current_offset, 1);
		current_offset++;

		for (i = 0; i < 8; i++)
		{
			p.w.l >>= 1;

			if (state == 0)
			{
				/* searching for a block */
				if (p.b.l == 0x3C)
				{
					/* found one! */
					phase = i;
					state++;
				}
				else if (p.b.l == 0x55)
				{
					synccount++;
				}
			}
			else if (i == phase)
			{
				*(block++) = p.b.l;
				switch(state) {
				case 1:
					/* found file type */
					block_checksum = p.b.l;
					state++;
					break;
				case 2:
					/* found file size */
					block_length = p.b.l;
					*block_len = ((int) block_length) + 3;
					block_checksum += p.b.l;
					state++;
					break;

				case 3:
					/* data byte */
					if (block_length)
					{
						block_length--;
						block_checksum += p.b.l;
					}
					else
					{
						/* end of block */
						if (p.b.l != block_checksum)
						{
							/* checksum failure */
							return FALSE;
						}
						else
						{
							/* checksum success */
							*offset = current_offset;
							return TRUE;
						}
					}
				}
			}
		}
	}

	/* no more blocks */
	return FALSE;
}
Пример #7
0
static cassette_image::error coladam_ddp_load( cassette_image *cass )
{
	double time = 0.;
	int i, block, prev_sign=-1;
	uint8_t buffer[0x400];
	cassette_image::error err = cassette_image::error::SUCCESS;

	// It would appear that data packs that originally had the type GW data layout and headers work fine when converted to type
	// HE. Thus we set all tapes to type HE.

	int layout_type = TYPE_HE;

	// Track 0
	for ( i = 0; i < 2753; i++ ) // leading zero bytes
	{
		err = coladam_put_byte(cass, 0, &time, 0x00, &prev_sign);
	}

	for (block = 0; block < 128; block++)
	{
		cassette_image_read( cass, buffer, 0x20000+0x400*block, 0x400 );
		err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type);
	}
	for (block = 128; block < 131; block++)
	{
		cassette_image_read( cass, buffer, 0x3f400+0x400*(block-128), 0x400 );
		err = coladam_put_block(cass, 0, &time, &prev_sign, block, buffer, layout_type);
	}

	// Track 1
	time = 0.;
	for ( i = 0; i < 2753; i++ ) // leading zero bytes
	{
		err = coladam_put_byte(cass, 1, &time, 0x00, &prev_sign);
	}
	if (layout_type == TYPE_HE)
	{
		for (block = 0; block < 64; block++)
		{
			cassette_image_read( cass, buffer, 0x10000+0x400*block, 0x400 );
			err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
		}
		for (block = 64; block < 128; block++)
		{
			cassette_image_read( cass, buffer, 0x00000+0x400*(block-64), 0x400 );
			err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
		}
		for (block = 128; block < 131; block++)
		{
			cassette_image_read( cass, buffer, 0x0f400+0x400*(block-128), 0x400 );
			err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
		}
	}
	else
	{
		time = 0;
		for ( i = 0; i < 2753; i++ ) // leading zero bytes
		{
			err = coladam_put_byte(cass, 1, &time, 0x00, &prev_sign);
		}
		for (block = 0; block < 128; block++)
		{
			cassette_image_read( cass, buffer, 0x400*block, 0x400 );
			err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
		}
		for (block = 128; block < 131; block++)
		{
			cassette_image_read( cass, buffer, 0x1f400+0x400*(block-128), 0x400 );
			err = coladam_put_block(cass, 1, &time, &prev_sign, block, buffer, layout_type);
		}
	}

	return err;
}