diff options
Diffstat (limited to 'src/lib/formats/as_dsk.cpp')
-rw-r--r-- | src/lib/formats/as_dsk.cpp | 250 |
1 files changed, 115 insertions, 135 deletions
diff --git a/src/lib/formats/as_dsk.cpp b/src/lib/formats/as_dsk.cpp index 5c8a0545870..0fad7217585 100644 --- a/src/lib/formats/as_dsk.cpp +++ b/src/lib/formats/as_dsk.cpp @@ -4,55 +4,17 @@ // Applesauce solved output formats #include "as_dsk.h" + #include "ioprocs.h" +#include "multibyte.h" #include <string.h> -as_format::as_format() : floppy_image_format_t() -{ -} -uint32_t as_format::find_tag(const std::vector<uint8_t> &data, uint32_t tag) -{ - uint32_t offset = 12; - do { - if(r32(data, offset) == tag) - return offset + 8; - offset += r32(data, offset+4) + 8; - } while(offset < data.size() - 8); - return 0; -} +namespace { -uint32_t as_format::r32(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset] | (data[offset+1] << 8) | (data[offset+2] << 16) | (data[offset+3] << 24); -} - -uint16_t as_format::r16(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset] | (data[offset+1] << 8); -} - -void as_format::w32(std::vector<uint8_t> &data, int offset, uint32_t value) -{ - data[offset] = value; - data[offset+1] = value >> 8; - data[offset+2] = value >> 16; - data[offset+3] = value >> 24; -} - -void as_format::w16(std::vector<uint8_t> &data, int offset, uint16_t value) -{ - data[offset] = value; - data[offset+1] = value >> 8; -} - -uint8_t as_format::r8(const std::vector<uint8_t> &data, uint32_t offset) -{ - return data[offset]; -} - -uint32_t as_format::crc32r(const uint8_t *data, uint32_t size) +template <typename T> +uint32_t crc32r(T &&data, uint32_t size) { // Reversed crc32 uint32_t crc = 0xffffffff; @@ -67,15 +29,35 @@ uint32_t as_format::crc32r(const uint8_t *data, uint32_t size) return ~crc; } -bool as_format::load_bitstream_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant) +template <typename T> +uint32_t find_tag(T &&data, size_t size, uint32_t tag) +{ + uint32_t offset = 12; + do { + if(get_u32le(&data[offset]) == tag) + return offset + 8; + offset += get_u32le(&data[offset+4]) + 8; + } while(offset < (size - 8)); + return 0; +} + +} // anonymous namespace + + +as_format::as_format() : floppy_image_format_t() +{ +} + + +bool as_format::load_bitstream_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t idx, uint32_t off_trks, bool may_be_short, bool set_variant) { uint32_t trks_off = off_trks + (idx * 8); - uint32_t track_size = r32(img, trks_off + 4); + uint32_t track_size = get_u32le(&img[trks_off + 4]); if (track_size == 0) return false; - uint32_t boff = (uint32_t)r16(img, trks_off + 0) * 512; + uint32_t boff = (uint32_t)get_u16le(&img[trks_off + 0]) * 512; // With 5.25 floppies the end-of-track may be missing // if unformatted. Accept track length down to 95% of @@ -92,15 +74,15 @@ bool as_format::load_bitstream_track(const std::vector<uint8_t> &img, floppy_ima generate_track_from_bitstream(track, head, &img[boff], track_size, image, subtrack, 0xffff); if(set_variant) - image.set_variant(r32(img, trks_off + 4) >= 90000 ? floppy_image::DSHD : floppy_image::DSDD); + image.set_variant(get_u32le(&img[trks_off + 4]) >= 90000 ? floppy_image::DSHD : floppy_image::DSDD); return true; } -void as_format::load_flux_track(const std::vector<uint8_t> &img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks) +void as_format::load_flux_track(const uint8_t *img, floppy_image &image, int head, int track, int subtrack, uint8_t fidx, uint32_t off_trks) { uint32_t trks_off = off_trks + (fidx * 8); - uint32_t boff = (uint32_t)r16(img, trks_off + 0) * 512; - uint32_t track_size = r32(img, trks_off + 4); + uint32_t boff = (uint32_t)get_u16le(&img[trks_off + 0]) * 512; + uint32_t track_size = get_u32le(&img[trks_off + 4]); uint32_t total_ticks = 0; for(uint32_t i=0; i != track_size; i++) @@ -239,13 +221,13 @@ bool as_format::test_flux(const std::vector<tdata> &tracks) void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> &tracks, uint32_t total_blocks, bool has_flux) { - w32(data, 80, 0x50414D54); // TMAP - w32(data, 84, 160); // size + put_u32le(&data[80], 0x50414d54); // TMAP + put_u32le(&data[84], 160); // size uint32_t fstart = 1536 + total_blocks*512; if(has_flux) { - w32(data, fstart, 0x58554c46); - w32(data, fstart+4, 160); + put_u32le(&data[fstart], 0x58554c46); + put_u32le(&data[fstart+4], 160); fstart += 8; } @@ -264,8 +246,8 @@ void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> } } - w32(data, 248, 0x534B5254); // TRKS - w32(data, 252, 1280 + total_blocks*512); // size + put_u32le(&data[248], 0x534b5254); // TRKS + put_u32le(&data[252], 1280 + total_blocks*512); // size uint8_t tid = 0; uint16_t tb = 3; @@ -274,14 +256,14 @@ void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata> int size = tracks[i].data.size(); int blocks = (size + 511) / 512; memcpy(data.data() + tb*512, tracks[i].data.data(), size); - w16(data, 256 + tid*8, tb); - w16(data, 256 + tid*8 + 2, blocks); - w32(data, 256 + tid*8 + 4, tracks[i].track_size); + put_u16le(&data[256 + tid*8], tb); + put_u16le(&data[256 + tid*8 + 2], blocks); + put_u32le(&data[256 + tid*8 + 4], tracks[i].track_size); tb += blocks; tid ++; } - w32(data, 8, crc32r(&data[12], data.size() - 12)); + put_u32le(&data[8], crc32r(&data[12], data.size() - 12)); } @@ -316,10 +298,10 @@ const uint8_t woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, int woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[8]; - size_t actual; - io.read_at(0, header, 8, actual); - if (!memcmp(header, signature, 8)) return FIFID_SIGN; - if (!memcmp(header, signature2, 8)) return FIFID_SIGN; + auto const [err, actual] = read_at(io, 0, header, 8); + if(err || (8 != actual)) return 0; + if(!memcmp(header, signature, 8)) return FIFID_SIGN; + if(!memcmp(header, signature2, 8)) return FIFID_SIGN; return 0; } @@ -328,9 +310,9 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve uint64_t image_size; if(io.length(image_size)) return false; - std::vector<uint8_t> img(image_size); - size_t actual; - io.read_at(0, &img[0], img.size(), actual); + auto const [err, img, actual] = read_at(io, 0, image_size); + if(err || (actual != image_size)) + return false; // Check signature if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8))) @@ -340,29 +322,29 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve if(!memcmp(&img[0], signature2, 8)) woz_vers = 2; // Check integrity - uint32_t crc = crc32r(&img[12], img.size() - 12); - if(crc != r32(img, 8)) + uint32_t crc = crc32r(&img[12], image_size - 12); + if(crc != get_u32le(&img[8])) return false; - uint32_t off_info = find_tag(img, 0x4f464e49); - uint32_t off_tmap = find_tag(img, 0x50414d54); - uint32_t off_trks = find_tag(img, 0x534b5254); -// uint32_t off_writ = find_tag(img, 0x54495257); + uint32_t off_info = find_tag(img, image_size, 0x4f464e49); + uint32_t off_tmap = find_tag(img, image_size, 0x50414d54); + uint32_t off_trks = find_tag(img, image_size, 0x534b5254); +// uint32_t off_writ = find_tag(img, image_size, 0x54495257); if(!off_info || !off_tmap || !off_trks) return false; - uint32_t info_vers = r8(img, off_info + 0); + uint32_t info_vers = img[off_info + 0]; if(info_vers < 1 || info_vers > 3) return false; - uint16_t off_flux = info_vers < 3 ? 0 : r16(img, off_info + 46); - uint16_t flux_size = info_vers < 3 ? 0 : r16(img, off_info + 48); + uint16_t off_flux = (info_vers < 3) ? 0 : get_u16le(&img[off_info + 46]); + uint16_t flux_size = (info_vers < 3) ? 0 : get_u16le(&img[off_info + 48]); if(!flux_size) off_flux = 0; - bool is_35 = r8(img, off_info + 1) == 2; + bool is_35 = img[off_info + 1] == 2; if((form_factor == floppy_image::FF_35 && !is_35) || (form_factor == floppy_image::FF_525 && is_35)) return false; @@ -374,36 +356,36 @@ bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::ve else image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); - if (woz_vers == 1) { + if(woz_vers == 1) { for (unsigned int trkid = 0; trkid != limit; trkid++) { int head = is_35 && trkid >= 80 ? 1 : 0; int track = is_35 ? trkid % 80 : trkid / 4; int subtrack = is_35 ? 0 : trkid & 3; - uint8_t idx = r8(img, off_tmap + trkid); + uint8_t idx = img[off_tmap + trkid]; if(idx != 0xff) { uint32_t boff = off_trks + 6656*idx; - if (r16(img, boff + 6648) == 0) + if (get_u16le(&img[boff + 6648]) == 0) return false; - generate_track_from_bitstream(track, head, &img[boff], r16(img, boff + 6648), image, subtrack, r16(img, boff + 6650)); + generate_track_from_bitstream(track, head, &img[boff], get_u16le(&img[boff + 6648]), image, subtrack, get_u16le(&img[boff + 6650])); if(is_35 && !track && head) image.set_variant(floppy_image::DSDD); } } - } else if (woz_vers == 2) { + } else if(woz_vers == 2) { for (unsigned int trkid = 0; trkid != limit; trkid++) { int head = is_35 && trkid & 1 ? 1 : 0; int track = is_35 ? trkid >> 1 : trkid / 4; int subtrack = is_35 ? 0 : trkid & 3; - uint8_t idx = r8(img, off_tmap + trkid); - uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff; + uint8_t idx = img[off_tmap + trkid]; + uint8_t fidx = off_flux ? img[off_flux*512 + 8 + trkid] : 0xff; - if(fidx != 0xff) - load_flux_track(img, image, head, track, subtrack, fidx, off_trks); + if(fidx != 0xff) { + load_flux_track(&img[0], image, head, track, subtrack, fidx, off_trks); - else if(idx != 0xff) { - if(!load_bitstream_track(img, image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head)) + } else if(idx != 0xff) { + if(!load_bitstream_track(&img[0], image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head)) return false; } } @@ -445,31 +427,30 @@ bool woz_format::save(util::random_read_write &io, const std::vector<uint32_t> & memcpy(&data[0], signature2, 8); - w32(data, 12, 0x4F464E49); // INFO - w32(data, 16, 60); // size - data[20] = 3; // chunk version + put_u32le(&data[12], 0x4f464e49); // INFO + put_u32le(&data[16], 60); // size + data[20] = 3; // chunk version data[21] = image.get_form_factor() == floppy_image::FF_525 ? 1 : 2; - data[22] = 0; // not write protected - data[23] = 1; // synchronized, since our internal format is - data[24] = 1; // weak bits are generated, not stored + data[22] = 0; // not write protected + data[23] = 1; // synchronized, since our internal format is + data[24] = 1; // weak bits are generated, not stored data[25] = 'M'; data[26] = 'A'; data[27] = 'M'; data[28] = 'E'; memset(&data[29], ' ', 32-4); data[57] = twosided ? 2 : 1; - data[58] = 0; // boot sector unknown + data[58] = 0; // boot sector unknown data[59] = image.get_form_factor() == floppy_image::FF_525 ? 32 : image.get_variant() == floppy_image::DSHD ? 8 : 16; - w16(data, 60, 0); // compatibility unknown - w16(data, 62, 0); // needed ram unknown - w16(data, 64, max_blocks); - w16(data, 66, has_flux ? total_blocks+3 : 0); - w16(data, 68, max_blocks); + put_u16le(&data[60], 0); // compatibility unknown + put_u16le(&data[62], 0); // needed RAM unknown + put_u16le(&data[64], max_blocks); + put_u16le(&data[66], has_flux ? total_blocks+3 : 0); + put_u16le(&data[68], max_blocks); save_tracks(data, tracks, total_blocks, has_flux); - size_t actual; - io.write_at(0, data.data(), data.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, data.data(), data.size()); // FIXME: check for errors return true; } @@ -505,9 +486,9 @@ const uint8_t moof_format::signature[8] = { 0x4d, 0x4f, 0x4f, 0x46, 0xff, 0x0a, int moof_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { uint8_t header[8]; - size_t actual; - io.read_at(0, header, 8, actual); - if (!memcmp(header, signature, 8)) return FIFID_SIGN; + auto const [err, actual] = read_at(io, 0, header, 8); + if(err || (8 != actual)) return 0; + if(!memcmp(header, signature, 8)) return FIFID_SIGN; return 0; } @@ -516,37 +497,37 @@ bool moof_format::load(util::random_read &io, uint32_t form_factor, const std::v uint64_t image_size; if(io.length(image_size)) return false; - std::vector<uint8_t> img(image_size); - size_t actual; - io.read_at(0, &img[0], img.size(), actual); + auto const [err, img, actual] = read_at(io, 0, image_size); + if(err || (actual != image_size)) + return false; // Check signature if(memcmp(&img[0], signature, 8)) return false; // Check integrity - uint32_t crc = crc32r(&img[12], img.size() - 12); - if(crc != r32(img, 8)) + uint32_t crc = crc32r(&img[12], image_size - 12); + if(crc != get_u32le(&img[8])) return false; - uint32_t off_info = find_tag(img, 0x4f464e49); - uint32_t off_tmap = find_tag(img, 0x50414d54); - uint32_t off_trks = find_tag(img, 0x534b5254); + uint32_t off_info = find_tag(img, image_size, 0x4f464e49); + uint32_t off_tmap = find_tag(img, image_size, 0x50414d54); + uint32_t off_trks = find_tag(img, image_size, 0x534b5254); if(!off_info || !off_tmap || !off_trks) return false; - uint32_t info_vers = r8(img, off_info + 0); + uint32_t info_vers = img[off_info + 0]; if(info_vers != 1) return false; - uint16_t off_flux = r16(img, off_info + 40); - uint16_t flux_size = r16(img, off_info + 42); + uint16_t off_flux = get_u16le(&img[off_info + 40]); + uint16_t flux_size = get_u16le(&img[off_info + 42]); if(!flux_size) off_flux = 0; - switch(r8(img, off_info + 1)) { + switch(img[off_info + 1]) { case 1: image.set_form_variant(floppy_image::FF_35, floppy_image::SSDD); break; @@ -564,14 +545,14 @@ bool moof_format::load(util::random_read &io, uint32_t form_factor, const std::v int head = trkid & 1; int track = trkid >> 1; - uint8_t idx = r8(img, off_tmap + trkid); - uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff; + uint8_t idx = img[off_tmap + trkid]; + uint8_t fidx = off_flux ? img[off_flux*512 + 8 + trkid] : 0xff; - if(fidx != 0xff) - load_flux_track(img, image, head, track, 0, fidx, off_trks); + if(fidx != 0xff) { + load_flux_track(&img[0], image, head, track, 0, fidx, off_trks); - else if(idx != 0xff) { - if(!load_bitstream_track(img, image, head, track, 0, idx, off_trks, false, false)) + } else if(idx != 0xff) { + if(!load_bitstream_track(&img[0], image, head, track, 0, idx, off_trks, false, false)) return false; } } @@ -606,27 +587,26 @@ bool moof_format::save(util::random_read_write &io, const std::vector<uint32_t> memcpy(&data[0], signature, 8); - w32(data, 12, 0x4F464E49); // INFO - w32(data, 16, 60); // size - data[20] = 1; // chunk version + put_u32le(&data[12], 0x4f464e49); // INFO + put_u32le(&data[16], 60); // size + data[20] = 1; // chunk version data[21] = is_hd ? 3 : twosided ? 2 : 1; // variant - data[22] = 0; // not write protected - data[23] = 1; // synchronized, since our internal format is - data[24] = is_hd ? 8 : 16; // optimal timing + data[22] = 0; // not write protected + data[23] = 1; // synchronized, since our internal format is + data[24] = is_hd ? 8 : 16; // optimal timing data[25] = 'M'; data[26] = 'A'; data[27] = 'M'; data[28] = 'E'; memset(&data[29], ' ', 32-4); - data[57] = 0; // pad - w16(data, 58, max_blocks); - w16(data, 60, has_flux ? total_blocks+3 : 0); - w16(data, 62, max_blocks); + data[57] = 0; // pad + put_u16le(&data[58], max_blocks); + put_u16le(&data[60], has_flux ? total_blocks+3 : 0); + put_u16le(&data[62], max_blocks); save_tracks(data, tracks, total_blocks, has_flux); - size_t actual; - io.write_at(0, data.data(), data.size(), actual); + /*auto const [err, actual] =*/ write_at(io, 0, data.data(), data.size()); // FIXME: check for errors return true; } |