diff options
author | 2015-11-08 12:56:12 +0100 | |
---|---|---|
committer | 2015-11-08 12:56:12 +0100 | |
commit | 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch) | |
tree | f310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/lib/formats/coco_cas.c | |
parent | a57b46ae933badd7441ce1644711dbb851e2b504 (diff) |
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/lib/formats/coco_cas.c')
-rw-r--r-- | src/lib/formats/coco_cas.c | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/src/lib/formats/coco_cas.c b/src/lib/formats/coco_cas.c deleted file mode 100644 index e70b28d69c0..00000000000 --- a/src/lib/formats/coco_cas.c +++ /dev/null @@ -1,298 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nathan Woods -/************************************************************************** - - coco_cas.c - - Format code for CoCo CAS (*.cas) files - - This is the actual code that processes the CAS data. CAS files are a - problem because they are a legacy of previous CoCo emulators, and most - of these emulators patch the system as a shortcut. Thus, the ones and - zeroes in the file do not truly represent modulated pulses in the - waveform, but what the BIOS reads and writes. - - In doing so, they make the CoCo more tolerant of short headers and lack - of delays between blocks. This legacy is reflected in most CAS files in - use, and thus presents a problem for a pure hardware emulation like MESS. - - One alternative is to preprocess the data on the CAS, file by file, but - this proves to be problematic because in the process, legitimate data - that is unrecognized by the preprocessor may get dropped. - - The approach taken here is a hybrid approach - it retrieves the data - block by block until an error occurs; be it the end of the CAS or a - corrupt (?!) block. When "legitimate" blocks are done processing, the - remainder of the data is added to the waveform in a traditional manner. - The result has proven to work quite well. - - 2005-May-04, P.Harvey-Smith, improved handling of some "copy protected" - Dragon games that have odd blocks in odd places, this has slightly - increased loading time but does mean games like "Rommel's Revenge" will - now load. - -**************************************************************************/ - -#include "emu.h" // PAIR -#include "coco_cas.h" - -#define COCO_WAVESAMPLES_HEADER (1.0) -#define COCO_WAVESAMPLES_TRAILER (1.0) -#define COCO_LONGSILENCE (5.0) - -//some games load with only 5s, but most games need 15s -#define ALICE32_WAVESAMPLES_HEADER (15.0) - -static int synccount; - -const struct CassetteModulation coco_cas_modulation = -{ - CASSETTE_MODULATION_SINEWAVE, - 600.0, 1200.0, 1500.0, - 1500.0, 2400.0, 3000.0 -}; - - - -static casserr_t coco_cas_identify(cassette_image *cassette, struct CassetteOptions *opts) -{ - return cassette_modulation_identify(cassette, &coco_cas_modulation, opts); -} - - - -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; -} - - - -static casserr_t cas_load(cassette_image *cassette, UINT8 silence) -{ - casserr_t err; - UINT64 offset; - UINT64 image_size; - UINT8 block[258]; /* 255 bytes per block + 3 (type, length, checksum) */ - int block_length = 0; - UINT8 last_blocktype; - double time_index = 0.0; - double time_displacement; - static const UINT8 magic_bytes[2] = { 0x55, 0x3C }; - -#if 0 - { - static const UINT8 dummy_bytes[] = - { - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x3C, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A - }; - time_index = 10.0; - return cassette_put_modulated_data(cassette, 0, time_index, dummy_bytes, sizeof(dummy_bytes), &coco_cas_modulation, &time_displacement); - } -#endif - - err = cassette_put_sample(cassette, 0, time_index, COCO_WAVESAMPLES_HEADER, 0); - if (err) - return err; - time_index += COCO_WAVESAMPLES_HEADER; - - offset = 0; - last_blocktype = 0; - image_size = cassette_image_size(cassette); - - /* try to find a block that we can untangle */ - while(get_cas_block(cassette, &offset, block, &block_length)) - { - /* Forcing a silence before a filename block, improves the ability to load some */ - /* copy protected Dragon games, e.g. Rommel's Revenge */ - /* was the last block a filename block? */ - if ((last_blocktype == 0) || (last_blocktype == 0xFF) || (block[0] == 0)) - { - /* silence */ - err = cassette_put_sample(cassette, 0, time_index, silence, 0); - if (err) - return err; - time_index += silence; - - /* sync data */ - err = cassette_put_modulated_filler(cassette, 0, time_index, 0x55, 128, &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - } - else if (synccount != 0) /* If we have multiple sync bytes in cas file, make sure they */ - { /* are passed through */ - /* sync data */ - err = cassette_put_modulated_filler(cassette, 0, time_index, 0x55, synccount, &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - } - - /* now fill in the magic bytes */ - err = cassette_put_modulated_data(cassette, 0, time_index, magic_bytes, sizeof(magic_bytes), &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - - /* now fill in the block */ - err = cassette_put_modulated_data(cassette, 0, time_index, block, block_length, &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - - /* and the last magic byte */ - err = cassette_put_modulated_filler(cassette, 0, time_index, 0x55, 1, &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - - last_blocktype = block[0]; - } - - /* all futher data is undecipherable, so output it verbatim */ - err = cassette_read_modulated_data(cassette, 0, time_index, offset, image_size - offset, &coco_cas_modulation, &time_displacement); - if (err) - return err; - time_index += time_displacement; - - return CASSETTE_ERROR_SUCCESS; -} - -static casserr_t coco_cas_load(cassette_image *cassette) -{ - return cas_load(cassette, COCO_WAVESAMPLES_HEADER); -} - -static casserr_t alice32_cas_load(cassette_image *cassette) -{ - return cas_load(cassette, ALICE32_WAVESAMPLES_HEADER); -} - -const struct CassetteFormat coco_cas_format = -{ - "cas", - coco_cas_identify, - coco_cas_load, - NULL -}; - -const struct CassetteFormat alice32_cas_format = -{ - "cas,c10,k7", - coco_cas_identify, - alice32_cas_load, - NULL -}; - - -CASSETTE_FORMATLIST_START(coco_cassette_formats) - CASSETTE_FORMAT(coco_cas_format) -CASSETTE_FORMATLIST_END - -CASSETTE_FORMATLIST_START(alice32_cassette_formats) - CASSETTE_FORMAT(alice32_cas_format) -CASSETTE_FORMATLIST_END |