diff options
Diffstat (limited to 'src/lib/formats/dvk_mx_dsk.cpp')
-rw-r--r-- | src/lib/formats/dvk_mx_dsk.cpp | 145 |
1 files changed, 92 insertions, 53 deletions
diff --git a/src/lib/formats/dvk_mx_dsk.cpp b/src/lib/formats/dvk_mx_dsk.cpp index 981bed010e7..c384dc38e00 100644 --- a/src/lib/formats/dvk_mx_dsk.cpp +++ b/src/lib/formats/dvk_mx_dsk.cpp @@ -23,65 +23,45 @@ #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 noexcept -{ - return "mx"; -} - -const char *dvk_mx_format::description() const noexcept -{ - return "DVK MX: floppy image"; -} - -const char *dvk_mx_format::extensions() const noexcept -{ - return "mx"; -} - -bool dvk_mx_format::supports_save() const noexcept -{ - return false; -} - void dvk_mx_format::find_size(util::random_read &io, uint8_t &track_count, uint8_t &head_count, uint8_t §or_count) { uint64_t size; @@ -95,17 +75,17 @@ void dvk_mx_format::find_size(util::random_read &io, uint8_t &track_count, uint8 { 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: @@ -123,8 +103,7 @@ int dvk_mx_format::identify(util::random_read &io, uint32_t form_factor, const s if (track_count) { uint8_t sectdata[512]; - size_t actual; - io.read_at(512, sectdata, 512, actual); + /*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 (get_u16le(§data[0724]) == 6) return FIFID_SIGN|FIFID_SIZE; @@ -143,22 +122,21 @@ bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std: 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++) { - size_t actual; - io.read_at((track * head_count + head) * track_size, sectdata, track_size, actual); + /*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); } } @@ -182,4 +160,65 @@ bool dvk_mx_format::load(util::random_read &io, uint32_t form_factor, const std: return true; } +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; |