summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/jvc_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/jvc_dsk.cpp')
-rw-r--r--src/lib/formats/jvc_dsk.cpp117
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 &sectors, int &sector_size, int &base_sector_id)
+bool jvc_format::parse_header(util::random_read &io, int &header_size, int &tracks, int &heads, int &sectors, int &sector_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 = &sector_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;