diff options
Diffstat (limited to 'src/lib/formats/jvc_dsk.cpp')
-rw-r--r-- | src/lib/formats/jvc_dsk.cpp | 117 |
1 files changed, 76 insertions, 41 deletions
diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp index 5035e989f22..fcc5d97a5b5 100644 --- a/src/lib/formats/jvc_dsk.cpp +++ b/src/lib/formats/jvc_dsk.cpp @@ -1,4 +1,4 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Dirk Best /*************************************************************************** @@ -8,7 +8,7 @@ Used by Jeff Vavasour's CoCo Emulators - Documentation taken from Tim Linder's web site: + Documentation taken from Tim Lindner's web site: http://tlindner.macmess.org/?page_id=86 A. Header length @@ -104,43 +104,51 @@ ***************************************************************************/ -#include "emu.h" -#include "imageutl.h" #include "jvc_dsk.h" +#include "ioprocs.h" + +#include "osdcore.h" // osd_printf_* + + jvc_format::jvc_format() { } -const char *jvc_format::name() const +const char *jvc_format::name() const noexcept { return "jvc"; } -const char *jvc_format::description() const +const char *jvc_format::description() const noexcept { return "JVC disk image"; } -const char *jvc_format::extensions() const +const char *jvc_format::extensions() const noexcept { return "jvc,dsk"; } -bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id) +bool jvc_format::parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int §ors, int §or_size, int &base_sector_id) { // The JVC format has a header whose size is the size of the image modulo 256. Currently, we only // handle up to five header bytes - uint64_t size = io_generic_size(io); + uint64_t size; + if (io.length(size) || !size) + return false; header_size = size % 256; uint8_t header[5]; - // if we know that this is a header of a bad size, we can fail - // immediately; otherwise read the header - if (header_size >= sizeof(header)) + // if we know that this is a header of a bad size, we can fail immediately; otherwise read the header + if (header_size >= sizeof(header)) // TODO: wouldn't this make more sense with > than >=? The first case in the following switch statement is unreachable as-is. return false; if (header_size > 0) - io_generic_read(io, header, 0, header_size); + { + auto const [err, actual] = read_at(io, 0, header, header_size); + if (err || (actual != header_size)) + return false; + } // default values heads = 1; @@ -150,41 +158,69 @@ bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int switch (header_size) { - case 5: emu_fatalerror("jvc_format: sector attribute flag unsupported\n"); - break; + case 5: + osd_printf_info("jvc_format: sector attribute flag unsupported\n"); + return false; case 4: base_sector_id = header[3]; - // no break + [[fallthrough]]; case 3: sector_size = 128 << header[2]; - // no break + [[fallthrough]]; case 2: heads = header[1]; - // no break + [[fallthrough]]; case 1: sectors = header[0]; - // no break + [[fallthrough]]; case 0: tracks = (size - header_size) / sector_size / sectors / heads; break; } - osd_printf_verbose("Floppy disk image geometry: %d tracks, %d head(s), %d sectors with %d bytes.\n", tracks, heads, sectors, sector_size); + if (tracks > 82) + { + osd_printf_info("jvc_format: track count of %d unsupported\n", tracks); + return false; + } + + osd_printf_verbose("jvc_format: Floppy disk image geometry: %d tracks, %d head(s), %d sectors with %d bytes.\n", tracks, heads, sectors, sector_size); return tracks * heads * sectors * sector_size == (size - header_size); } -int jvc_format::identify(io_generic *io, uint32_t form_factor) +int jvc_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { int header_size, tracks, heads, sectors, sector_size, sector_base_id; - return parse_header(io, header_size, tracks, heads, sectors, sector_size, sector_base_id) ? 50 : 0; + if (parse_header(io, header_size, tracks, heads, sectors, sector_size, sector_base_id)) + return FIFID_SIZE; + else + return 0; } -bool jvc_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +bool jvc_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { int header_size, track_count, head_count, sector_count, sector_size, sector_base_id; + int max_tracks, max_heads; if (!parse_header(io, header_size, track_count, head_count, sector_count, sector_size, sector_base_id)) return false; // safety check if (sector_count * sector_size > 10000) - emu_fatalerror("jvc_format: incorrect track layout\n"); + { + osd_printf_error("jvc_format: incorrect track layout\n"); + return false; + } + + image.get_maximal_geometry(max_tracks, max_heads); + + if (track_count > max_tracks) + { + osd_printf_error("jvc_format: Floppy disk has too many tracks for this drive (floppy tracks=%d, drive tracks=%d).\n", track_count, max_tracks); + return false; + } + + if (head_count > max_heads) + { + osd_printf_error("jvc_format: Floppy disk has too many sides for this drive (floppy sides=%d, drive sides=%d).\n", head_count, max_heads); + return false; + } int file_offset = header_size; @@ -208,7 +244,7 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) sectors[interleave[i]].bad_crc = false; sectors[interleave[i]].data = §or_data[sector_offset]; - io_generic_read(io, sectors[interleave[i]].data, file_offset, sector_size); + /*auto const [err, actual] =*/ read_at(io, file_offset, sectors[interleave[i]].data, sector_size); // FIXME: check for errors and premature EOF sector_offset += sector_size; file_offset += sector_size; @@ -221,15 +257,12 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) return true; } -bool jvc_format::save(io_generic *io, floppy_image *image) +bool jvc_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - uint8_t bitstream[500000/8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; uint64_t file_offset = 0; int track_count, head_count; - image->get_actual_geometry(track_count, head_count); + image.get_actual_geometry(track_count, head_count); // we'll write a header if the disk is two-sided if (head_count == 2) @@ -237,7 +270,7 @@ bool jvc_format::save(io_generic *io, floppy_image *image) uint8_t header[2]; header[0] = 18; header[1] = 2; - io_generic_write(io, header, file_offset, sizeof(header)); + /*auto const [err, actual] =*/ write_at(io, file_offset, header, sizeof(header)); // FIXME: check for errors file_offset += sizeof(header); } @@ -246,17 +279,19 @@ bool jvc_format::save(io_generic *io, floppy_image *image) { for (int head = 0; head < head_count; head++) { - int track_size; - generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + auto bitstream = generate_bitstream_from_track(track, head, 2000, image); + auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < 18; i++) { - if (sectors[1 + i].size != 256) - emu_fatalerror("jvc_format: invalid sector size: %d\n", sectors[1 + i].size); - - io_generic_write(io, sectors[1 + i].data, file_offset, sectors[1 + i].size); - file_offset += sectors[1 + i].size; + if (sectors[1 + i].size() != 256) + { + osd_printf_error("jvc_format: invalid sector size: %d\n", sectors[1 + i].size()); + return false; + } + + /*auto const [err, actual] =*/ write_at(io, file_offset, sectors[1 + i].data(), 256); // FIXME: check for errors + file_offset += 256; } } } @@ -264,9 +299,9 @@ bool jvc_format::save(io_generic *io, floppy_image *image) return true; } -bool jvc_format::supports_save() const +bool jvc_format::supports_save() const noexcept { return true; } -const floppy_format_type FLOPPY_JVC_FORMAT = &floppy_image_format_creator<jvc_format>; +const jvc_format FLOPPY_JVC_FORMAT; |