From 07dacff42d47ec139710db6a8b4cfda548ab8f2d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 30 Dec 2016 18:03:30 -0500 Subject: [PATCH] Added writing for Acorn ADF disks, plus appropriate TODOs in both similar bits of boilerplate. --- Storage/Disk/Formats/AcornADF.cpp | 50 ++++++++++++++++++------------- Storage/Disk/Formats/AcornADF.hpp | 3 ++ Storage/Disk/Formats/SSD.cpp | 2 ++ Storage/Disk/Formats/SSD.hpp | 1 + 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/Storage/Disk/Formats/AcornADF.cpp b/Storage/Disk/Formats/AcornADF.cpp index 9615139f9..28b319067 100644 --- a/Storage/Disk/Formats/AcornADF.cpp +++ b/Storage/Disk/Formats/AcornADF.cpp @@ -40,25 +40,6 @@ AcornADF::AcornADF(const char *file_name) : AcornADF::~AcornADF() { flush_updates(); -// if(get_is_modified()) -// { -// for(unsigned int head = 0; head < get_head_count(); head++) -// { -// for(unsigned int track = 0; track < get_head_position_count(); track++) -// { -// std::shared_ptr modified_track = get_modified_track_at_position(head, track); -// if(modified_track) -// { -// Storage::Encodings::MFM::Parser parser(true, modified_track); -// for(unsigned int c = 0; c < sectors_per_track; c++) -// { -// std::shared_ptr sector = parser.get_sector((uint8_t)track, (uint8_t)c); -// printf("Sector %d: %p\n", c, sector.get()); -// } -// } -// } -// } -// } } unsigned int AcornADF::get_head_position_count() @@ -76,12 +57,17 @@ bool AcornADF::get_is_read_only() return is_read_only_; } +long AcornADF::get_file_offset_for_position(unsigned int head, unsigned int position) +{ + return (position * 1 + head) * bytes_per_sector * sectors_per_track; +} + std::shared_ptr AcornADF::get_uncached_track_at_position(unsigned int head, unsigned int position) { std::shared_ptr track; if(head >= 2) return track; - long file_offset = (position * 1 + head) * bytes_per_sector * sectors_per_track; + long file_offset = get_file_offset_for_position(head, position); fseek(file_, file_offset, SEEK_SET); std::vector sectors; @@ -104,3 +90,27 @@ std::shared_ptr AcornADF::get_uncached_track_at_position(unsigned int hea return track; } + +void AcornADF::store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex) +{ + std::vector parsed_track; + Storage::Encodings::MFM::Parser parser(true, track); + for(unsigned int c = 0; c < sectors_per_track; c++) + { + std::shared_ptr sector = parser.get_sector((uint8_t)position, (uint8_t)c); + if(sector) + { + parsed_track.insert(parsed_track.end(), sector->data.begin(), sector->data.end()); + } + else + { + // TODO: what's correct here? Warn the user that whatever has been written to the disk, + // it can no longer be stored as an SSD? If so, warn them by what route? + parsed_track.resize(parsed_track.size() + bytes_per_sector); + } + } + + std::lock_guard lock_guard(file_access_mutex); + fseek(file_, get_file_offset_for_position(head, position), SEEK_SET); + fwrite(parsed_track.data(), 1, parsed_track.size(), file_); +} diff --git a/Storage/Disk/Formats/AcornADF.hpp b/Storage/Disk/Formats/AcornADF.hpp index ea996303f..0100a4d2c 100644 --- a/Storage/Disk/Formats/AcornADF.hpp +++ b/Storage/Disk/Formats/AcornADF.hpp @@ -37,8 +37,11 @@ class AcornADF: public Disk, public Storage::FileHolder { unsigned int get_head_position_count(); unsigned int get_head_count(); bool get_is_read_only(); + private: + void store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex); std::shared_ptr get_uncached_track_at_position(unsigned int head, unsigned int position); + long get_file_offset_for_position(unsigned int head, unsigned int position); }; } diff --git a/Storage/Disk/Formats/SSD.cpp b/Storage/Disk/Formats/SSD.cpp index 006dfc642..b91c7dcbd 100644 --- a/Storage/Disk/Formats/SSD.cpp +++ b/Storage/Disk/Formats/SSD.cpp @@ -99,6 +99,8 @@ void SSD::store_updated_track_at_position(unsigned int head, unsigned int positi } else { + // TODO: what's correct here? Warn the user that whatever has been written to the disk, + // it can no longer be stored as an SSD? If so, warn them by what route? parsed_track.resize(parsed_track.size() + 256); } } diff --git a/Storage/Disk/Formats/SSD.hpp b/Storage/Disk/Formats/SSD.hpp index 0e806a147..a26432c10 100644 --- a/Storage/Disk/Formats/SSD.hpp +++ b/Storage/Disk/Formats/SSD.hpp @@ -42,6 +42,7 @@ class SSD: public Disk, public Storage::FileHolder { void store_updated_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr &track, std::mutex &file_access_mutex); std::shared_ptr get_uncached_track_at_position(unsigned int head, unsigned int position); long get_file_offset_for_position(unsigned int head, unsigned int position); + unsigned int head_count_; unsigned int track_count_; };