diff options
Diffstat (limited to 'src/lib/formats/vt_dsk.cpp')
-rw-r--r-- | src/lib/formats/vt_dsk.cpp | 212 |
1 files changed, 108 insertions, 104 deletions
diff --git a/src/lib/formats/vt_dsk.cpp b/src/lib/formats/vt_dsk.cpp index 6758b5a27b2..8792ba86525 100644 --- a/src/lib/formats/vt_dsk.cpp +++ b/src/lib/formats/vt_dsk.cpp @@ -11,113 +11,119 @@ #include "formats/vt_dsk.h" #include "ioprocs.h" +#include "multibyte.h" +#include "osdcomm.h" // Zero = | 9187 | // One = | 2237 | 6950 | // 0.5us ~= 143 -void vtech_common_format::wbit(std::vector<uint32_t> &buffer, uint32_t &pos, uint32_t &mg, bool bit) +void vtech_common_format::wbit(std::vector<uint32_t> &buffer, uint32_t &pos, bool bit) { - buffer.push_back(pos | mg); - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; if(bit) { pos += 2237; - buffer.push_back(pos | mg); - mg = mg == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; + buffer.push_back(pos | floppy_image::MG_F); pos += 6950; } else pos += 9187; } -void vtech_common_format::wbyte(std::vector<uint32_t> &buffer, uint32_t &pos, uint32_t &mg, uint8_t byte) +void vtech_common_format::wbyte(std::vector<uint32_t> &buffer, uint32_t &pos, uint8_t byte) { for(int i = 7; i >= 0; i--) - wbit(buffer, pos, mg, (byte >> i) & 1); + wbit(buffer, pos, (byte >> i) & 1); } -void vtech_common_format::image_to_flux(const std::vector<uint8_t> &bdata, floppy_image *image) +void vtech_common_format::image_to_flux(const uint8_t *bdata, size_t size, floppy_image &image) { static const uint8_t sector_map[16] = { 0x0, 0xb, 0x6, 0x1, 0xc, 0x7, 0x2, 0xd, 0x8, 0x3, 0xe, 0x9, 0x4, 0xf, 0xa, 0x5 }; - for(int track = 0; track != 40; track ++) { + for(int track = 0; track != 40; track++) { uint32_t pos = 0; - uint32_t mg = floppy_image::MG_A; - std::vector<uint32_t> &buffer = image->get_buffer(track, 0); + std::vector<uint32_t> &buffer = image.get_buffer(track, 0); buffer.clear(); - image->set_write_splice_position(track, 0, 0); + image.set_write_splice_position(track, 0, 0); // One window of pad at the start to avoid problems with the write splice - wbit(buffer, pos, mg, 0); + wbit(buffer, pos, 0); - for(int sector = 0; sector != 16; sector ++) { + for(int sector = 0; sector != 16; sector++) { uint8_t sid = sector_map[sector]; for(int i=0; i != 7; i++) - wbyte(buffer, pos, mg, 0x80); - wbyte(buffer, pos, mg, 0x00); - wbyte(buffer, pos, mg, 0xfe); - wbyte(buffer, pos, mg, 0xe7); - wbyte(buffer, pos, mg, 0x18); - wbyte(buffer, pos, mg, 0xc3); - wbyte(buffer, pos, mg, track); - wbyte(buffer, pos, mg, sid); - wbyte(buffer, pos, mg, track+sid); + wbyte(buffer, pos, 0x80); + wbyte(buffer, pos, 0x00); + wbyte(buffer, pos, 0xfe); + wbyte(buffer, pos, 0xe7); + wbyte(buffer, pos, 0x18); + wbyte(buffer, pos, 0xc3); + wbyte(buffer, pos, track); + wbyte(buffer, pos, sid); + wbyte(buffer, pos, track+sid); for(int i=0; i != 5; i++) - wbyte(buffer, pos, mg, 0x80); - wbyte(buffer, pos, mg, 0x00); - wbyte(buffer, pos, mg, 0xc3); - wbyte(buffer, pos, mg, 0x18); - wbyte(buffer, pos, mg, 0xe7); - wbyte(buffer, pos, mg, 0xfe); + wbyte(buffer, pos, 0x80); + wbyte(buffer, pos, 0x00); + wbyte(buffer, pos, 0xc3); + wbyte(buffer, pos, 0x18); + wbyte(buffer, pos, 0xe7); + wbyte(buffer, pos, 0xfe); uint16_t chk = 0; - const uint8_t *src = bdata.data() + 16*128*track + 128*sid; + const uint8_t *src = &bdata[16*128*track + 128*sid]; for(int i=0; i != 128; i++) { chk += src[i]; - wbyte(buffer, pos, mg, src[i]); + wbyte(buffer, pos, src[i]); } - wbyte(buffer, pos, mg, chk); - wbyte(buffer, pos, mg, chk >> 8); + wbyte(buffer, pos, chk); + wbyte(buffer, pos, chk >> 8); } // Rest is just not formatted buffer.push_back(pos | floppy_image::MG_N); } } -std::vector<uint8_t> vtech_common_format::flux_to_image(floppy_image *image) +std::vector<uint8_t> vtech_common_format::flux_to_image(const floppy_image &image) { std::vector<uint8_t> bdata(16*256*40, 0); for(int track = 0; track != 40; track++) { - auto buffer = image->get_buffer(track, 0); + const auto &buffer = image.get_buffer(track, 0); int sz = buffer.size(); if(sz < 128) continue; std::vector<bool> bitstream; - int lpos = -1; - bool looped = !((buffer[sz-1] ^ buffer[0]) & floppy_image::MG_MASK); - int cpos = looped ? sz-1 : 0; - while(cpos != lpos) { - int dt = looped && cpos == sz-1 ? (200000000 - (buffer[cpos] & floppy_image::TIME_MASK)) + (buffer[1] & floppy_image::TIME_MASK) : - cpos == sz-1 ? 200000000 - (buffer[cpos] & floppy_image::TIME_MASK) : - (buffer[cpos+1] & floppy_image::TIME_MASK) - (buffer[cpos] & floppy_image::TIME_MASK); - int t = dt >= 9187 - 143 ? 0 : - dt >= 2237 - 143 && dt <= 2237 + 143 ? 1 : - 2; - if(t <= 1) { - if(lpos == -1) - lpos = cpos; - bitstream.push_back(t); + int cpos = 0; + while((buffer[cpos] & floppy_image::MG_MASK) != floppy_image::MG_F) { + cpos++; + if(cpos == sz) { + cpos = -1; + break; } - cpos += 1; - if(cpos == sz) - cpos = looped ? 1 : 0; + } + if(cpos == -1) + continue; + for(;;) { + int npos = cpos; + for(;;) { + npos++; + if(npos == sz) + npos = 0; + if((buffer[npos] & floppy_image::MG_MASK) == floppy_image::MG_F) + break; + } + int dt = (buffer[npos] & floppy_image::TIME_MASK) - (buffer[cpos] & floppy_image::TIME_MASK); + if(dt < 0) + cpos += 200000000; + bitstream.push_back(dt < 9187 - 143); + if(npos <= cpos) + break; + cpos = npos; } int mode = 0; - looped = false; int pos = 0; int count = 0; + bool looped = false; uint8_t *dest = nullptr; [[maybe_unused]] uint16_t checksum = 0; uint64_t buf = 0; @@ -129,7 +135,7 @@ std::vector<uint8_t> vtech_common_format::flux_to_image(floppy_image *image) buf = (buf << 1) | bitstream[sz-64+i]; for(;;) { buf = (buf << 1) | bitstream[pos]; - count ++; + count++; switch(mode) { case 0: // idle if(buf == 0x80808000fee718c3) @@ -186,49 +192,49 @@ std::vector<uint8_t> vtech_common_format::flux_to_image(floppy_image *image) } -const char *vtech_bin_format::name() const +const char *vtech_bin_format::name() const noexcept { return "vtech_bin"; } -const char *vtech_bin_format::description() const +const char *vtech_bin_format::description() const noexcept { return "VTech sector disk image"; } -const char *vtech_bin_format::extensions() const +const char *vtech_bin_format::extensions() const noexcept { return "bin"; } -const char *vtech_dsk_format::name() const +const char *vtech_dsk_format::name() const noexcept { return "vtech_dsk"; } -const char *vtech_dsk_format::description() const +const char *vtech_dsk_format::description() const noexcept { return "VTech dsk image"; } -const char *vtech_dsk_format::extensions() const +const char *vtech_dsk_format::extensions() const noexcept { return "dsk"; } -int vtech_bin_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int vtech_bin_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint64_t size; if(io.length(size)) return 0; if(size == 40*16*256) - return 50; + return FIFID_SIZE; return 0; } -int vtech_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) +int vtech_dsk_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint64_t size; if(io.length(size)) @@ -237,47 +243,47 @@ int vtech_dsk_format::identify(util::random_read &io, uint32_t form_factor, cons if(size < 256) return 0; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return 0; // Structurally validate the presence of sector headers and data int count_sh = 0, count_sd = 0; uint64_t buf = 0; - for(uint8_t b : bdata) { - buf = (buf << 8) | b; + for(size_t i = 0; size > i; ++i) { + buf = (buf << 8) | bdata[i]; if(buf == 0x80808000fee718c3) count_sh++; else if(buf == 0x80808000c318e7fe) count_sd++; } - return count_sh >= 30*16 && count_sd >= 30*16 ? 100 : 0; + return count_sh >= 30*16 && count_sd >= 30*16 ? FIFID_STRUCT : 0; } -bool vtech_bin_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool vtech_bin_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { uint64_t size; if(io.length(size) || (size != 40*16*256)) return false; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; - image_to_flux(bdata, image); - image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD); + image_to_flux(bdata.get(), size, image); + image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); return true; } -bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { uint64_t size; if(io.length(size)) return false; - std::vector<uint8_t> bdata(size); - size_t actual; - io.read_at(0, bdata.data(), size, actual); + auto const [err, bdata, actual] = read_at(io, 0, size); + if(err || (actual != size)) + return false; std::vector<uint8_t> bdatax(128*16*40, 0); @@ -287,9 +293,9 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s uint64_t buf = 0; uint8_t *dest = nullptr; - for(uint8_t b : bdata) { - buf = (buf << 8) | b; - count ++; + for(size_t i = 0; size > i; ++i) { + buf = (buf << 8) | bdata[i]; + count++; switch(mode) { case 0: // idle if(buf == 0x80808000fee718c3) @@ -299,14 +305,14 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s case 1: // sector header if(count == 3) { - uint8_t trk = buf >> 16; - uint8_t sector = buf >> 8; - uint8_t chk = buf; + const uint8_t trk = buf >> 16; + const uint8_t sector = buf >> 8; + const uint8_t chk = buf; if(chk != sector + trk) { mode = 0; break; } - dest = bdatax.data() + 128*16*trk + sector*128; + dest = &bdatax[128*16*trk + sector*128]; checksum = 0; mode = 2; } @@ -322,41 +328,40 @@ bool vtech_dsk_format::load(util::random_read &io, uint32_t form_factor, const s case 3: // sector data if(count <= 128) { - uint8_t byte = buf; + const uint8_t byte = buf; checksum += byte; *dest++ = byte; } else if(count == 128+2) { uint16_t disk_checksum = buf; - disk_checksum = (disk_checksum << 8) | (disk_checksum >> 8); + disk_checksum = swapendian_int16(disk_checksum); mode = 0; } break; } } - image_to_flux(bdatax, image); - image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD); + image_to_flux(bdatax.data(), bdatax.size(), image); + image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); return true; } -bool vtech_bin_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) +bool vtech_bin_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { int tracks, heads; - image->get_maximal_geometry(tracks, heads); + image.get_maximal_geometry(tracks, heads); if(tracks < 40) return false; auto bdata = flux_to_image(image); - size_t actual; - io.write_at(0, bdata.data(), bdata.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, bdata.data(), bdata.size()); // FIXME: check for errors return true; } -bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) +bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { int tracks, heads; - image->get_maximal_geometry(tracks, heads); + image.get_maximal_geometry(tracks, heads); if(tracks < 40) return false; @@ -370,8 +375,8 @@ bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint3 }; int pos = 0; - for(int track = 0; track != 40; track ++) { - for(int sector = 0; sector != 16; sector ++) { + for(int track = 0; track != 40; track++) { + for(int sector = 0; sector != 16; sector++) { uint8_t sid = sector_map[sector]; for(int i=0; i != 7; i++) bdatax[pos++] = 0x80; @@ -396,16 +401,15 @@ bool vtech_dsk_format::save(util::random_read_write &io, const std::vector<uint3 chk += src[i]; bdatax[pos++] = src[i]; } - bdatax[pos++] = chk; - bdatax[pos++] = chk >> 8; + put_u16le(&bdatax[pos], chk); + pos += 2; } } - size_t actual; - io.write_at(0, bdatax.data(), bdatax.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, bdatax.data(), bdatax.size()); // FIXME: check for errors return true; } -const floppy_format_type FLOPPY_VTECH_BIN_FORMAT = &floppy_image_format_creator<vtech_bin_format>; -const floppy_format_type FLOPPY_VTECH_DSK_FORMAT = &floppy_image_format_creator<vtech_dsk_format>; +const vtech_bin_format FLOPPY_VTECH_BIN_FORMAT; +const vtech_dsk_format FLOPPY_VTECH_DSK_FORMAT; |