summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/dvk_mx_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/dvk_mx_dsk.cpp')
-rw-r--r--src/lib/formats/dvk_mx_dsk.cpp177
1 files changed, 112 insertions, 65 deletions
diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp
index 477dd07690f..c384dc38e00 100644
--- a/src/lib/formats/dvk_mx_dsk.cpp
+++ b/src/lib/formats/dvk_mx_dsk.cpp
@@ -18,88 +18,74 @@
************************************************************************/
-#include <assert.h>
-
-#include "flopimg.h"
#include "formats/dvk_mx_dsk.h"
+#include "ioprocs.h"
+#include "multibyte.h"
+
+constexpr uint32_t ID_PATTERN = 0xaaaaffaf;
+
const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_new_desc[] = {
/* 01 */ { FM, 0x00, 8*2 }, // eight 0x0000 words
- /* 03 */ { FM, 0x00, 1 },
- /* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
- /* 05 */ { FM, 0x00, 1 },
- /* 04 */ { TRACK_ID_FM }, // track number word
- /* 05 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
+ /* 02 */ { FM, 0x00, 1 },
+ /* 03 */ { FM, 0xf3, 1 }, // word 0x00f3
+ /* 04 */ { FM, 0x00, 1 },
+ /* 05 */ { TRACK_ID_FM }, // track number word
+ /* 06 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
/* 07 */ { SECTOR_DATA_MX, -1 },
- /* 10 */ { SECTOR_LOOP_END },
- /* 13 */ { FM, 0x83, 1 },
+ /* 08 */ { SECTOR_LOOP_END },
+ /* 09 */ { FM, 0x83, 1 },
+ /* 10 */ { OFFSET_ID_FM },
+ /* 11 */ { FM, 0x83, 1 },
/* 12 */ { OFFSET_ID_FM },
- /* 15 */ { FM, 0x83, 1 },
+ /* 13 */ { FM, 0x83, 1 },
/* 14 */ { OFFSET_ID_FM },
- /* 17 */ { FM, 0x83, 1 },
- /* 16 */ { OFFSET_ID_FM },
- /* 18 */ { END }
+ /* 15 */ { END }
};
const floppy_image_format_t::desc_e dvk_mx_format::dvk_mx_old_desc[] = {
/* 01 */ { FM, 0x00, 30*2 },
- /* 03 */ { FM, 0x00, 1 },
- /* 02 */ { FM, 0xf3, 1 }, // word 0x00f3
- /* 05 */ { FM, 0x00, 1 },
- /* 04 */ { TRACK_ID_FM }, // track number word
+ /* 02 */ { FM, 0x00, 1 },
+ /* 03 */ { FM, 0xf3, 1 }, // word 0x00f3
+ /* 04 */ { FM, 0x00, 1 },
+ /* 05 */ { TRACK_ID_FM }, // track number word
/* 06 */ { SECTOR_LOOP_START, 0, 10 }, // 11 sectors
/* 07 */ { SECTOR_DATA_MX, -1 },
- /* 10 */ { SECTOR_LOOP_END },
- /* 13 */ { FM, 0x83, 1 },
- /* 11 */ { FM, 0x01, 1 },
- /* 15 */ { FM, 0x83, 1 },
- /* 14 */ { FM, 0x01, 1 },
- /* 16 */ { END }
+ /* 08 */ { SECTOR_LOOP_END },
+ /* 09 */ { FM, 0x00, 1 },
+ /* 10 */ { FM, 0116, 1 },
+ /* 11 */ { FM, 0x00, 4*2 }, // four 0x0000 words
+ /* 12 */ { END }
};
dvk_mx_format::dvk_mx_format()
{
}
-const char *dvk_mx_format::name() const
-{
- return "mx";
-}
-
-const char *dvk_mx_format::description() const
-{
- return "DVK MX: floppy image";
-}
-
-const char *dvk_mx_format::extensions() const
-{
- return "mx";
-}
-
-bool dvk_mx_format::supports_save() const
+void dvk_mx_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
{
- return false;
-}
-
-void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &head_count, uint8_t &sector_count)
-{
- uint64_t size = io_generic_size(io);
+ uint64_t size;
+ if (io.length(size))
+ {
+ track_count = head_count = sector_count = 0;
+ return;
+ }
switch (size)
{
case 112640:
track_count = 40;
- sector_count = 11;
+ sector_count = MX_SECTORS;
head_count = 1;
break;
case 225280:
track_count = 40;
- sector_count = 11;
+ sector_count = MX_SECTORS;
head_count = 2;
break;
case 450560:
track_count = 80;
- sector_count = 11;
+ sector_count = MX_SECTORS;
head_count = 2;
break;
default:
@@ -108,7 +94,7 @@ void dvk_mx_format::find_size(io_generic *io, uint8_t &track_count, uint8_t &hea
}
}
-int dvk_mx_format::identify(io_generic *io, uint32_t form_factor)
+int dvk_mx_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
{
uint8_t track_count, head_count, sector_count;
@@ -117,61 +103,122 @@ int dvk_mx_format::identify(io_generic *io, uint32_t form_factor)
if (track_count)
{
uint8_t sectdata[512];
- io_generic_read(io, sectdata, 512, 512);
+ /*auto const [err, actual] =*/ read_at(io, 512, sectdata, 512); // FIXME: check for errors and premature EOF
// check value in RT-11 home block. see src/tools/imgtool/modules/rt11.cpp
- if (pick_integer_le(sectdata, 0724, 2) == 6)
- return 100;
+ if (get_u16le(&sectdata[0724]) == 6)
+ return FIFID_SIGN|FIFID_SIZE;
else
- return 75;
+ return FIFID_SIZE;
}
return 0;
}
-bool dvk_mx_format::load(io_generic *io, uint32_t form_factor, floppy_image *image)
+bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const
{
uint8_t track_count, head_count, sector_count;
find_size(io, track_count, head_count, sector_count);
if (track_count == 0) return false;
- uint8_t sectdata[11 * 256];
- desc_s sectors[11];
+ uint8_t sectdata[MX_SECTORS * MX_SECTOR_SIZE];
+ desc_s sectors[MX_SECTORS];
for (int i = 0; i < sector_count; i++)
{
- sectors[i].data = sectdata + 256 * i;
- sectors[i].size = 256;
+ sectors[i].data = sectdata + MX_SECTOR_SIZE * i;
+ sectors[i].size = MX_SECTOR_SIZE;
sectors[i].sector_id = i;
}
- int track_size = sector_count * 256;
+ int track_size = sector_count * MX_SECTOR_SIZE;
for (int track = 0; track < track_count; track++)
{
for (int head = 0; head < head_count; head++)
{
- io_generic_read(io, sectdata, (track * head_count + head) * track_size, track_size);
+ /*auto const [err, actual] =*/ read_at(io, (track * head_count + head) * track_size, sectdata, track_size); // FIXME: check for errors and premature EOF
generate_track(dvk_mx_new_desc, track, head, sectors, sector_count, 45824, image);
}
}
if (head_count == 1)
{
- image->set_variant(floppy_image::SSDD);
+ image.set_variant(floppy_image::SSDD);
}
else
{
if (track_count > 40)
{
- image->set_variant(floppy_image::DSQD);
+ image.set_variant(floppy_image::DSQD);
}
else
{
- image->set_variant(floppy_image::DSDD);
+ image.set_variant(floppy_image::DSDD);
}
}
return true;
}
-const floppy_format_type FLOPPY_DVK_MX_FORMAT = &floppy_image_format_creator<dvk_mx_format>;
+bool dvk_mx_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const
+{
+ int tracks;
+ int heads;
+ bool res = false;
+ image.get_actual_geometry(tracks, heads);
+
+ for (int cyl = 0; cyl < tracks; cyl++)
+ {
+ for (int head = 0; head < heads; head++)
+ {
+ auto bitstream = generate_bitstream_from_track(cyl, head, 4000, image, 0);
+ uint8_t sector_data[MX_SECTORS * MX_SECTOR_SIZE];
+ if (get_next_sector(bitstream, sector_data))
+ {
+ unsigned const offset_in_image = (cyl * heads + head) * MX_SECTOR_SIZE * MX_SECTORS;
+ res = true;
+ // FIXME: check for errors
+ /*auto const [err, actual] =*/ write_at(io, offset_in_image, sector_data, MX_SECTOR_SIZE * MX_SECTORS);
+ }
+ }
+ }
+ return res;
+}
+
+bool dvk_mx_format::get_next_sector(const std::vector<bool> &bitstream, uint8_t *sector_data)
+{
+ uint32_t sr = 0;
+ int pos = 0;
+ while (pos < bitstream.size() && sr != ID_PATTERN)
+ {
+ sr = (sr << 1) | bitstream[pos];
+ pos++;
+ }
+ if (pos == bitstream.size())
+ {
+ // End of track reached
+ return false;
+ }
+ unsigned to_dump = MX_SECTORS * (MX_SECTOR_SIZE + 2);
+ pos += 32; // skip track ID
+ for (unsigned i = 0, k = 0; i < to_dump && pos < bitstream.size(); i++)
+ {
+ uint8_t byte = 0;
+ unsigned j;
+ for (j = 0; j < 8 && pos < bitstream.size(); j++)
+ {
+ bool bit = bitstream[pos + 1];
+ pos += 2;
+ byte <<= 1;
+ byte |= bit;
+ }
+ if (j == 8 && (i % (MX_SECTOR_SIZE + 2)) < MX_SECTOR_SIZE)
+ {
+ sector_data[k ^ 1] = byte;
+ k++;
+ }
+ }
+ return true;
+}
+
+const dvk_mx_format FLOPPY_DVK_MX_FORMAT;