From 6fa4e379d22a8959d4361615aa8797c09c678f23 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 30 Aug 2022 16:07:44 -0400 Subject: [PATCH] Make a hacky and blunt offer of drive data. --- Storage/Disk/DiskImage/Formats/2MG.cpp | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Storage/Disk/DiskImage/Formats/2MG.cpp b/Storage/Disk/DiskImage/Formats/2MG.cpp index b48590b60..f68c3c090 100644 --- a/Storage/Disk/DiskImage/Formats/2MG.cpp +++ b/Storage/Disk/DiskImage/Formats/2MG.cpp @@ -9,11 +9,67 @@ #include "2MG.hpp" #include "MacintoshIMG.hpp" +#include "../../../MassStorage/Encodings/AppleIIVolume.hpp" + #include using namespace Storage::Disk; +namespace { + +// TODO: I've boxed myself into a corner on this stuff by not using factories more generally; +// volume to device mappers are not themselves mass storage devices because then their use +// can't currently be private to file types and relevant knowledge would need to be pushed up into +// the static analyser. +// +// So, I guess: go factory, pervasively. And probably stop the strict disk/mass storage/tape +// distinction, given that clearly some platforms just capture volumes abstractly from media. +class MassStorage2MG: public Storage::MassStorage::MassStorageDevice { + public: + MassStorage2MG(const std::string &file_name, long start, long size): + file_(file_name), + file_start_(start), + image_size_(size) + { + mapper_.set_drive_type( + Storage::MassStorage::Encodings::Apple::DriveType::SCSI, + size_t(size / 512) + ); + } + + private: + Storage::FileHolder file_; + long file_start_, image_size_; + Storage::MassStorage::Encodings::AppleII::Mapper mapper_; + + /* MassStorageDevices overrides. */ + size_t get_block_size() final { + return 512; + } + size_t get_number_of_blocks() final { + return mapper_.get_number_of_blocks(); + } + std::vector get_block(size_t address) final { + const auto source_address = mapper_.to_source_address(address); + + if(source_address >= 0 && long(source_address*512) < image_size_) { + const long file_offset = 512 * source_address; + file_.seek(file_offset, SEEK_SET); + return mapper_.convert_source_block(source_address, file_.read(get_block_size())); + } else { + return mapper_.convert_source_block(source_address); + } + } + void set_block(size_t address, const std::vector &data) final { + // TODO. +// file_.seek(file_start_ + address * 512, SEEK_SET); +// file_.write(data); + } +}; + +} + Disk2MG::DiskOrMassStorageDevice Disk2MG::open(const std::string &file_name) { FileHolder file(file_name); @@ -74,6 +130,7 @@ Disk2MG::DiskOrMassStorageDevice Disk2MG::open(const std::string &file_name) { // TODO: Apple II-style. // TODO: hard-disk image. + return new MassStorage2MG(file_name, data_start, data_size); break; case 2: // TODO: NIB data (yuck!).