diff options
Diffstat (limited to 'src/lib/formats/thom_cas.cpp')
-rw-r--r-- | src/lib/formats/thom_cas.cpp | 146 |
1 files changed, 77 insertions, 69 deletions
diff --git a/src/lib/formats/thom_cas.cpp b/src/lib/formats/thom_cas.cpp index 45f89ac2a29..f6f9e317d4f 100644 --- a/src/lib/formats/thom_cas.cpp +++ b/src/lib/formats/thom_cas.cpp @@ -8,13 +8,12 @@ **********************************************************************/ -#include <math.h> -#include <assert.h> - -#include "pool.h" -#include "cassimg.h" #include "thom_cas.h" +#include <cmath> +#include <cstdio> +#include <cstring> + /***************************** configuration **************************/ @@ -59,6 +58,8 @@ static uint8_t* to7_k7_bits; and so, is used by emulators that bypass the BIOS routine. It is generally hacked from the raw image more or less by hand (in particular, to by-pass special loaders and copy-protection schemes). + Many of these hacks use emulator-exclusive 6809 instructions and will + not work in MAME. As we run the original BIOS routine, we need to hack back the k7 file into the original stream. @@ -86,18 +87,18 @@ static uint8_t* to7_k7_bits; -static const struct CassetteModulation to7_k7_modulation = +static const cassette_image::Modulation to7_k7_modulation = { - CASSETTE_MODULATION_SQUAREWAVE, + cassette_image::MODULATION_SQUAREWAVE, 4000.0, 4500.0, 5000.0, 5500.0, 6300.0, 7500.0 }; -static cassette_image::error to7_k7_identify ( cassette_image *cass, struct CassetteOptions *opts ) +static cassette_image::error to7_k7_identify ( cassette_image *cass, cassette_image::Options *opts ) { - cassette_image::error e = cassette_modulation_identify( cass, &to7_k7_modulation, opts ); + cassette_image::error e = cass->modulation_identify( to7_k7_modulation, opts ); return e; } @@ -109,9 +110,9 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) static const int8_t square_wave[] = { -128, 127 }; double time = 0.; #endif - size_t size = cassette_image_size( cass ), pos = 0; + size_t size = cass->image_size( ), pos = 0; int i, sz, sz2, bitmax = 1024, invalid = 0; - uint8_t in, typ, block[264]; + uint8_t 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 )); @@ -133,8 +134,8 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) do \ { \ cassette_image::error err; \ - err = cassette_put_samples( cass, 0, time, (PERIOD), 2, 1, \ - square_wave, CASSETTE_WAVEFORM_8BIT ); \ + err = cass->put_samples( 0, time, (PERIOD), 2, 1, \ + square_wave, cassette_image::WAVEFORM_8BIT ); \ if ( err != cassette_image::error::SUCCESS ) \ return err; \ time += (PERIOD); \ @@ -202,7 +203,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) } while (0) /* check format */ - cassette_image_read( cass, block, 0, 64 ); + cass->image_read( block, 0, 64 ); for ( i = 3; ; i++ ) { if ( ( i >= size ) || ( i >= 64 ) ) @@ -227,8 +228,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* skip to first 0xff filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); - if ( in == 0xff ) + if ( cass->image_read_byte( pos ) == 0xff ) break; } if ( sz > 0 ) @@ -241,7 +241,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* skip 0xff filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); + uint8_t in = cass->image_read_byte( pos ); /* actually, we are bit laxist and treat as 0xff bytes with at least 5 bits out of 8 set to 1 */ @@ -257,7 +257,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) pos -= sz; break; } - cassette_image_read( cass, block, pos, 4 ); + cass->image_read( block, pos, 4 ); typ = block[2]; sz2 = block[3]+1; if ( block[0] != 0x01 || block[1] != 0x3c || ( typ != 0x00 && typ != 0x01 && typ != 0xff ) ) @@ -268,7 +268,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) pos += 4; /* get block */ - cassette_image_read( cass, block+4, pos, sz2 ); + cass->image_read( block+4, pos, sz2 ); pos += sz2; /* 1-filler and 0xff-filler */ @@ -323,17 +323,16 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) /* put block */ for (; pos < size; pos++ ) { - cassette_image_read( cass, &in, pos, 1 ); + uint8_t in = cass->image_read_byte( pos ); for ( sz = 0; pos < size && in == 0xff; sz++ ) { pos++; - cassette_image_read( cass, &in, pos, 1 ); + in = cass->image_read_byte( pos ); } if ( invalid < 10 && sz > 4 && in == 0x01 && pos + 4 <= size ) { - uint8_t in1,in2; - cassette_image_read( cass, &in1, pos+1, 1 ); - cassette_image_read( cass, &in2, pos+2, 1 ); + uint8_t in1 = cass->image_read_byte( pos+1 ); + uint8_t in2 = cass->image_read_byte( pos+2 ); if ( (in1 == 0x3c) && ((in2 == 0x00) || (in2 == 0x01) ) ) { /* seems we have a regular block hidden in raw data => rebounce */ @@ -365,7 +364,7 @@ static cassette_image::error to7_k7_load( cassette_image *cass ) -static const struct CassetteFormat to7_k7 = +static const cassette_image::Format to7_k7 = { "k7", to7_k7_identify, to7_k7_load, nullptr /* no save */ }; @@ -375,9 +374,9 @@ static const struct CassetteFormat to7_k7 = static cassette_image::error to7_wav_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { - cassette_image::error e = wavfile_format.identify( cass, opts ); + cassette_image::error e = cassette_image::wavfile_format.identify( cass, opts ); return e; } @@ -385,9 +384,7 @@ static cassette_image::error to7_wav_identify ( cassette_image *cass, static cassette_image::error to7_wav_load ( cassette_image *cass ) { - cassette_image::error e = wavfile_format.load( cass ); - struct CassetteInfo info; - double len; + cassette_image::error e = cassette_image::wavfile_format.load( cass ); if ( to7_k7_bits ) { @@ -398,9 +395,9 @@ static cassette_image::error to7_wav_load ( cassette_image *cass ) if ( e != cassette_image::error::SUCCESS ) return e; - cassette_get_info( cass, &info ); + cassette_image::Info info = cass->get_info( ); - len = (double) info.sample_count / info.sample_frequency; + double len = (double) info.sample_count / info.sample_frequency; PRINT (( "to7_wav_load: loading cassette, length %imn %is, %i Hz, %i bps, %i bits\n", (int) len / 60, (int) len % 60, @@ -412,17 +409,17 @@ static cassette_image::error to7_wav_load ( cassette_image *cass ) -static cassette_image::error to7_wav_save ( cassette_image *cass, const struct CassetteInfo *info ) +static cassette_image::error to7_wav_save ( cassette_image *cass, const cassette_image::Info *info ) { int len = info->sample_count / info->sample_frequency; PRINT (( "to7_wav_save: saving cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info->sample_frequency, info->bits_per_sample )); - return wavfile_format.save( cass, info ); + return cassette_image::wavfile_format.save( cass, info ); } /* overloaded wav: dump info */ -static const struct CassetteFormat to7_wav = +static const cassette_image::Format to7_wav = { "wav", to7_wav_identify, to7_wav_load, to7_wav_save }; @@ -432,7 +429,7 @@ static const struct CassetteFormat to7_wav = static cassette_image::error mo5_k5_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { opts -> bits_per_sample = 8; opts -> channels = 1; @@ -464,10 +461,11 @@ static cassette_image::error mo5_k5_identify ( cassette_image *cass, static cassette_image::error mo5_k5_load( cassette_image *cass ) { - size_t size = cassette_image_size( cass ), pos = 0; + size_t size = cass->image_size( ), pos = 0; int i, sz, sz2, hbit = 0; - uint8_t in, in2, in3, typ, block[264], sum; - int invalid = 0, hbitsize = 0, dcmoto = 0; + uint8_t typ, block[264], sum; + int invalid = 0, hbitsize = 0; + bool dcmoto = false, dcmoto_old = false; LOG (( "mo5_k5_load: start conversion, size=%li\n", (long)size )); PRINT (( "mo5_k5_load: open cassette, length: %li bytes\n", (long) size )); @@ -476,7 +474,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) #define K5_PUT_HBIT \ do \ { \ - cassette_put_sample ( cass, 0, hbitsize * MO5_HBIT_LENGTH, MO5_HBIT_LENGTH, (hbit ? 1 : -1) << 30 ); \ + cass->put_sample ( 0, hbitsize * MO5_HBIT_LENGTH, MO5_HBIT_LENGTH, (hbit ? 1 : -1) << 30 ); \ hbitsize++; \ } while ( 0 ) @@ -534,7 +532,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) } while (0) /* check format */ - cassette_image_read( cass, block, 0, 64 ); + cass->image_read( block, 0, 64 ); for ( i = 3; ; i++ ) { if ( ( i >= size ) || ( i >= 64 ) ) @@ -556,9 +554,11 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) } } - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( block, pos, 6 ); if ( ! memcmp( block, "DCMOTO", 6 ) || ! memcmp( block, "DCMO5", 5 ) || ! memcmp( block, "DCMO6", 5 ) ) - dcmoto = 1; + dcmoto = true; + if ( block[0] == 0xdc && block[1] == 0x01 ) + dcmoto_old = true; /* loop over regular blocks */ while ( pos < size ) @@ -567,7 +567,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) /* skip DCMOTO header*/ if ( dcmoto ) { - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( block, pos, 6 ); if ( ! memcmp( block, "DCMOTO", 6 ) ) { LOG (( "mo5_k5_load: DCMOTO signature found at off=$%x\n", (int)pos )); @@ -579,12 +579,17 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) pos += 5; } } + else if ( dcmoto_old ) + { + cass->image_read( block, pos, 1 ); + if ( block[0] == 0xdc ) + pos++; + } /* skip 0x01 filler */ for ( sz = 0; pos < size; pos++, sz++ ) { - cassette_image_read( cass, &in, pos, 1 ); - if ( in != 0x01 ) + if ( cass->image_read_byte(pos) != 0x01 ) break; } @@ -594,7 +599,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) pos -= sz; break; } - cassette_image_read( cass, block, pos, 4 ); + cass->image_read( block, pos, 4 ); typ = block[2]; sz2 = (uint8_t) (block[3]-1); if ( block[0] != 0x3c || block[1] != 0x5a || ( typ != 0x00 && typ != 0x01 && typ != 0xff ) || pos+sz2 > size ) @@ -605,7 +610,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) pos += 4; /* get block */ - cassette_image_read( cass, block+4, pos, sz2 ); + cass->image_read( block+4, pos, sz2 ); pos += sz2; /* 0-fillers and 0x01-fillers */ @@ -665,33 +670,33 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) 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 ); + uint8_t in = cass->image_read_byte( pos ); if ( dcmoto && in=='D' ) { /* skip DCMOTO header*/ - cassette_image_read( cass, block, pos, 6 ); + cass->image_read( 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 ); + in = cass->image_read_byte( pos ); } 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 ); + in = cass->image_read_byte( pos ); } } for ( sz = 0; pos < size && in == 0x01; sz++ ) { pos++; - cassette_image_read( cass, &in, pos, 1 ); + in = cass->image_read_byte( pos ); } if ( sz > 6 ) { - cassette_image_read( cass, &in2, pos+1, 1 ); - cassette_image_read( cass, &in3, pos+2, 1 ); + uint8_t in2 = cass->image_read_byte( pos+1 ); + uint8_t in3 = cass->image_read_byte( pos+2 ); if ( invalid < 10 && in == 0x3c && in2 == 0x5a && (in3 == 0x00 || in3 == 0x01 || in3 == 0xff ) ) { /* regular block found */ @@ -699,7 +704,12 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) 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) ) ) + if ( invalid < 10 && sz > 6 && + ( (in == 0x3c && in2 == 0x5a) || + (in == 0xc3 && in2 == 0x5a) || + (in == 0xc3 && in2 == 0x3c) || + (in == 0x87 && in2 == 0x4a) || + (in == 0x3c && in2 == 0x55) ) ) // Androïdes { /* special block found */ K5_FILL_0( 1200 ); @@ -729,7 +739,7 @@ static cassette_image::error mo5_k5_load( cassette_image *cass ) -static const struct CassetteFormat mo5_k5 = +static const cassette_image::Format mo5_k5 = { "k5,k7", mo5_k5_identify, mo5_k5_load, nullptr /* no save */ }; @@ -738,9 +748,9 @@ static const struct CassetteFormat mo5_k5 = static cassette_image::error mo5_wav_identify ( cassette_image *cass, - struct CassetteOptions *opts ) + cassette_image::Options *opts ) { - cassette_image::error e = wavfile_format.identify( cass, opts ); + cassette_image::error e = cassette_image::wavfile_format.identify( cass, opts ); return e; } @@ -748,13 +758,11 @@ static cassette_image::error mo5_wav_identify ( cassette_image *cass, static cassette_image::error mo5_wav_load ( cassette_image *cass ) { - cassette_image::error e = wavfile_format.load( cass ); - struct CassetteInfo info; - int len; + cassette_image::error e = cassette_image::wavfile_format.load( cass ); if ( e == cassette_image::error::SUCCESS ) { - cassette_get_info( cass, &info ); - len = info.sample_count / info.sample_frequency; + cassette_image::Info info = cass->get_info( ); + int len = info.sample_count / info.sample_frequency; PRINT (( "mo5_wav_load: loading cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info.sample_frequency, info.bits_per_sample )); } return e; @@ -762,17 +770,17 @@ static cassette_image::error mo5_wav_load ( cassette_image *cass ) -static cassette_image::error mo5_wav_save ( cassette_image *cass, const struct CassetteInfo *info ) +static cassette_image::error mo5_wav_save ( cassette_image *cass, const cassette_image::Info *info ) { int len = info->sample_count / info->sample_frequency; PRINT (( "mo5_wav_save: saving cassette, length %imn %is, %i Hz, %i bps\n", len / 60, len % 60, info->sample_frequency, info->bits_per_sample )); - return wavfile_format.save( cass, info ); + return cassette_image::wavfile_format.save( cass, info ); } /* overloaded wav: dump info */ -static const struct CassetteFormat mo5_wav = +static const cassette_image::Format mo5_wav = { "wav", mo5_wav_identify, mo5_wav_load, mo5_wav_save }; @@ -780,9 +788,9 @@ static const struct CassetteFormat mo5_wav = /********************* formats ************************/ -const struct CassetteFormat *const to7_cassette_formats[] = +const cassette_image::Format *const to7_cassette_formats[] = { &to7_wav, &to7_k7, nullptr }; -const struct CassetteFormat *const mo5_cassette_formats[] = +const cassette_image::Format *const mo5_cassette_formats[] = { &mo5_wav, &mo5_k5, nullptr }; |