diff options
Diffstat (limited to 'src/lib/formats/dfi_dsk.cpp')
-rw-r--r-- | src/lib/formats/dfi_dsk.cpp | 115 |
1 files changed, 67 insertions, 48 deletions
diff --git a/src/lib/formats/dfi_dsk.cpp b/src/lib/formats/dfi_dsk.cpp index 6c9f32cbb31..e2ea1fda0e3 100644 --- a/src/lib/formats/dfi_dsk.cpp +++ b/src/lib/formats/dfi_dsk.cpp @@ -11,9 +11,16 @@ * Correctly note exact index timing. */ -#include "emu.h" // fatalerror #include "dfi_dsk.h" -#include <zlib.h> + +#include "ioprocs.h" +#include "multibyte.h" + +#include "osdcore.h" // osd_printf_* + +#include <tuple> + + #define NUMBER_OF_MULTIREADS 3 // thresholds for brickwall windowing //define DFI_MIN_CLOCKS 65 @@ -35,50 +42,67 @@ dfi_format::dfi_format() : floppy_image_format_t() { } -const char *dfi_format::name() const +const char *dfi_format::name() const noexcept { return "dfi"; } -const char *dfi_format::description() const +const char *dfi_format::description() const noexcept { return "DiscFerret flux dump format"; } -const char *dfi_format::extensions() const +const char *dfi_format::extensions() const noexcept { return "dfi"; } -bool dfi_format::supports_save() const +bool dfi_format::supports_save() const noexcept { return false; } -int dfi_format::identify(io_generic *io, uint32_t form_factor) +int dfi_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { char sign[4]; - io_generic_read(io, sign, 0, 4); - if (memcmp(sign, "DFER", 4)==0) - fatalerror("Old type Discferret image detected; the mess Discferret decoder will not handle this properly, bailing out!\n"); - return memcmp(sign, "DFE2", 4) ? 0 : 100; + auto const [err, actual] = read_at(io, 0, sign, 4); + if(err || (4 != actual)) { + return 0; + } + return memcmp(sign, "DFE2", 4) ? 0 : FIFID_SIGN; } -bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +bool dfi_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - uint64_t size = io_generic_size(io); + std::error_condition err; + size_t actual; + + char sign[4]; + std::tie(err, actual) = read_at(io, 0, sign, 4); + if(err || (4 != actual)) { + return false; + } + if(memcmp(sign, "DFER", 4) == 0) { + osd_printf_error("dfi_dsk: Old type Discferret image detected; the MAME Discferret decoder will not handle this properly, bailing out!\n"); + return false; + } + + uint64_t size; + if(io.length(size)) + return false; + uint64_t pos = 4; std::vector<uint8_t> data; int onerev_time = 0; // time for one revolution, used to guess clock and rpm for DFE2 files unsigned long clock_rate = 100000000; // sample clock rate in megahertz - int rpm=360; // drive rpm + [[maybe_unused]] int rpm=360; // drive rpm while(pos < size) { uint8_t h[10]; - io_generic_read(io, h, pos, 10); - uint16_t track = (h[0] << 8) | h[1]; - uint16_t head = (h[2] << 8) | h[3]; + std::tie(err, actual) = read_at(io, pos, h, 10); // FIXME: check for errors and premature EOF + uint16_t track = get_u16be(&h[0]); + uint16_t head = get_u16be(&h[2]); // Ignore sector - uint32_t tsize = (h[6] << 24) | (h[7] << 16) | (h[8] << 8) | h[9]; + uint32_t tsize = get_u32be(&h[6]); // if the position-so-far-in-file plus 10 (for the header) plus track size // is larger than the size of the file, free buffers and bail out @@ -90,7 +114,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) data.resize(tsize); pos += 10; // skip the header, we already read it - io_generic_read(io, &data[0], pos, tsize); + std::tie(err, actual) = read_at(io, pos, &data[0], tsize); // FIXME: check for errors and premature EOF pos += tsize; // for next time we read, increment to the beginning of next header int index_time = 0; // what point the last index happened @@ -99,7 +123,10 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) int total_time = 0; // total sampled time per track for(int i=0; i<tsize; i++) { uint8_t v = data[i]; - if (v == 0xFF) { fprintf(stderr,"DFI stream contained a 0xFF at t%d, position%d, THIS SHOULD NEVER HAPPEN! Bailing out!\n", track, i); exit(1); } + if (v == 0xFF) { + osd_printf_error("dfi_dsk: DFI stream contained a 0xFF at t%d, position%d, THIS SHOULD NEVER HAPPEN! Bailing out!\n", track, i); + return false; + } if((v & 0x7f) == 0x7f) total_time += 0x7f; else if(v & 0x80) { @@ -118,38 +145,36 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) if (onerev_time == 0) onerev_time = total_time; if(!track && !head) - fprintf(stderr, "%02d:%d tt=%10d it=%10d\n", track, head, total_time, index_time); + osd_printf_verbose("dfi_dsk: %02d:%d tt=%10d it=%10d\n", track, head, total_time, index_time); if(!track && !head) { - fprintf(stderr, "index_count: %d, onerev_time: %d\n", index_count, onerev_time); + osd_printf_verbose("dfi_dsk: index_count: %d, onerev_time: %d\n", index_count, onerev_time); if ((onerev_time > REV25_MIN) && (onerev_time < REV25_MAX)) { - fprintf(stderr, "Guess: speed: 360rpm, clock 25MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 360rpm, clock 25MHz\n"); clock_rate = 25000000; rpm = 360; } else if ((onerev_time > REV25_MIN*1.2) && (onerev_time < REV25_MAX*1.2)) { - fprintf(stderr, "Guess: speed: 300rpm, clock 25MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 300rpm, clock 25MHz\n"); clock_rate = 25000000; rpm = 300; } else if ((onerev_time > REV25_MIN*2) && (onerev_time < REV25_MAX*2)) { - fprintf(stderr, "Guess: speed: 360rpm, clock 50MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 360rpm, clock 50MHz\n"); clock_rate = 50000000; rpm = 360; } else if ((onerev_time > (REV25_MIN*2)*1.2) && (onerev_time < (REV25_MAX*2)*1.2)) { - fprintf(stderr, "Guess: speed: 300rpm, clock 50MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 300rpm, clock 50MHz\n"); clock_rate = 50000000; rpm = 300; } else if ((onerev_time > REV25_MIN*4) && (onerev_time < REV25_MAX*4)) { - fprintf(stderr, "Guess: speed: 360rpm, clock 100MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 360rpm, clock 100MHz\n"); clock_rate = 100000000; rpm = 360; } else if ((onerev_time > (REV25_MIN*4)*1.2) && (onerev_time < (REV25_MAX*4)*1.2)) { - fprintf(stderr, "Guess: speed: 300rpm, clock 100MHz\n"); + osd_printf_verbose("dfi_dsk: Guess: speed: 300rpm, clock 100MHz\n"); clock_rate = 100000000; rpm = 300; } else - fprintf(stderr, "WARNING: Cannot Guess Speed! Assuming 360rpm, 100Mhz clock!\n"); - fprintf(stderr,"Actual rpm based on index: %f\n", ((double)clock_rate/(double)onerev_time)*60); + osd_printf_warning("dfi_dsk: WARNING: Cannot Guess Speed! Assuming 360rpm, 100Mhz clock!\n"); + osd_printf_verbose("dfi_dsk: Actual rpm based on index: %f\n", ((double)clock_rate/(double)onerev_time)*60); } - rpm += 0; // HACK: prevent GCC 4.6+ from warning "variable set but unused" - if(!index_time) index_time = total_time; - std::vector<uint32_t> &buf = image->get_buffer(track, head); + std::vector<uint32_t> &buf = image.get_buffer(track, head); buf.resize(tsize); int cur_time = 0; @@ -162,9 +187,7 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) #endif index_count = 0; //index_polarity = 0; - uint32_t mg = floppy_image::MG_A; int tpos = 0; - buf[tpos++] = mg; for(int i=0; i<tsize; i++) { uint8_t v = data[i]; if((v & 0x7f) == 0x7f) // 0x7F : no transition, but a carry (FF is a board-on-fire error and is checked for above) @@ -184,28 +207,24 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) // cur_time and onerev_time need to be converted to something standard, so we'll stick with 300rpm at the standard 200mhz rate that mfi uses internally // TODO for 4/22/2012: ACTUALLY DO THIS RESCALING STEP // filter out spurious crap - //if (trans_time <= MIN_THRESH) fprintf(stderr, "DFI: Throwing out short transition of length %d\n", trans_time); + //if (trans_time <= MIN_THRESH) osd_printf_verbose("dfi_dsk: Throwing out short transition of length %d\n", trans_time); // the normal case: write the transition at the appropriate time if ((prev_time == 0) || ((trans_time > MIN_THRESH) && (trans_time <= MAX_THRESH))) { - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; - buf[tpos++] = mg | uint32_t((200000000ULL*cur_time)/index_time); + buf[tpos++] = floppy_image::MG_F | uint32_t((200000000ULL*cur_time)/index_time); prev_time = cur_time; } // the long case: we probably missed a transition, stuff an extra guessed one in there to see if it helps if (trans_time > MAX_THRESH) { - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; - if (((track%2)==0)&&(head==0)) fprintf(stderr,"missed transition, total time for transition is %d\n",trans_time); + if (((track%2)==0)&&(head==0)) osd_printf_info("dfi_dsk: missed transition, total time for transition is %d\n",trans_time); #ifndef FAKETRANS_ONE - buf[tpos++] = mg | uint32_t((200000000ULL*(cur_time-(trans_time/2)))/index_time); // generate imaginary transition at half period + buf[tpos++] = floppy_image::MG_F | uint32_t((200000000ULL*(cur_time-(trans_time/2)))/index_time); // generate imaginary transition at half period #else - buf[tpos++] = mg | uint32_t((200000000ULL*(cur_time-((trans_time*2)/3)))/index_time); - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; - buf[tpos++] = mg | uint32_t((200000000ULL*(cur_time-(trans_time/3)))/index_time); + buf[tpos++] = floppy_image::MG_F | uint32_t((200000000ULL*(cur_time-((trans_time*2)/3)))/index_time); + buf[tpos++] = floppy_image::MG_F | uint32_t((200000000ULL*(cur_time-(trans_time/3)))/index_time); #endif - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; - buf[tpos++] = mg | uint32_t(200000000ULL*cur_time/index_time); // generate transition now + buf[tpos++] = floppy_image::MG_F | uint32_t(200000000ULL*cur_time/index_time); // generate transition now prev_time = cur_time; - } + } } } #ifdef TRACK_HISTOGRAM @@ -224,4 +243,4 @@ bool dfi_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) return true; } -const floppy_format_type FLOPPY_DFI_FORMAT = &floppy_image_format_creator<dfi_format>; +const dfi_format FLOPPY_DFI_FORMAT; |