From b98d5b790a5cb82a51344281c6fa1c70a3cebd40 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 27 Apr 2018 23:18:45 -0400 Subject: [PATCH] Finally unifies disk image file exceptions, and adds a placeholder for Apple DSK. --- Analyser/Static/StaticAnalyser.cpp | 2 + .../Clock Signal.xcodeproj/project.pbxproj | 12 ++++- Storage/Disk/DiskImage/DiskImage.hpp | 5 ++ Storage/Disk/DiskImage/Formats/AcornADF.cpp | 8 ++-- Storage/Disk/DiskImage/Formats/AcornADF.hpp | 8 +--- Storage/Disk/DiskImage/Formats/AppleDSK.cpp | 37 +++++++++++++++ Storage/Disk/DiskImage/Formats/AppleDSK.hpp | 47 +++++++++++++++++++ Storage/Disk/DiskImage/Formats/CPCDSK.cpp | 4 +- Storage/Disk/DiskImage/Formats/CPCDSK.hpp | 8 +--- Storage/Disk/DiskImage/Formats/D64.cpp | 2 +- Storage/Disk/DiskImage/Formats/D64.hpp | 8 +--- Storage/Disk/DiskImage/Formats/DMK.cpp | 8 ++-- Storage/Disk/DiskImage/Formats/DMK.hpp | 6 +-- Storage/Disk/DiskImage/Formats/G64.cpp | 4 +- Storage/Disk/DiskImage/Formats/G64.hpp | 12 ++--- Storage/Disk/DiskImage/Formats/HFE.cpp | 4 +- Storage/Disk/DiskImage/Formats/HFE.hpp | 8 ++-- Storage/Disk/DiskImage/Formats/MSXDSK.cpp | 8 ++-- Storage/Disk/DiskImage/Formats/MSXDSK.hpp | 5 -- Storage/Disk/DiskImage/Formats/NIB.cpp | 2 +- Storage/Disk/DiskImage/Formats/NIB.hpp | 4 -- Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp | 4 +- Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp | 4 -- Storage/Disk/DiskImage/Formats/SSD.cpp | 6 +-- Storage/Disk/DiskImage/Formats/SSD.hpp | 8 +--- Storage/Disk/DiskImage/Formats/WOZ.cpp | 6 ++- Storage/Disk/DiskImage/Formats/WOZ.hpp | 6 +-- Storage/FileHolder.cpp | 2 +- Storage/FileHolder.hpp | 4 +- 29 files changed, 150 insertions(+), 92 deletions(-) create mode 100644 Storage/Disk/DiskImage/Formats/AppleDSK.cpp create mode 100644 Storage/Disk/DiskImage/Formats/AppleDSK.hpp diff --git a/Analyser/Static/StaticAnalyser.cpp b/Analyser/Static/StaticAnalyser.cpp index c929125c0..7d85ac366 100644 --- a/Analyser/Static/StaticAnalyser.cpp +++ b/Analyser/Static/StaticAnalyser.cpp @@ -30,6 +30,7 @@ // Disks #include "../../Storage/Disk/DiskImage/Formats/AcornADF.hpp" +#include "../../Storage/Disk/DiskImage/Formats/AppleDSK.hpp" #include "../../Storage/Disk/DiskImage/Formats/CPCDSK.hpp" #include "../../Storage/Disk/DiskImage/Formats/D64.hpp" #include "../../Storage/Disk/DiskImage/Formats/G64.hpp" @@ -95,6 +96,7 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: Format("dmk", result.disks, Disk::DiskImageHolder, TargetPlatform::MSX) // DMK Format("dsd", result.disks, Disk::DiskImageHolder, TargetPlatform::Acorn) // DSD Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::AmstradCPC) // DSK (Amstrad CPC) + Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::AppleII) // DSK (Apple) Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::MSX) // DSK (MSX) Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::Oric) // DSK (Oric) Format("g64", result.disks, Disk::DiskImageHolder, TargetPlatform::Commodore) // G64 diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 6c3663dea..467ff17f5 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; }; + 4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; + 4B0333B02094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; 4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; }; 4B055A7A1FAE78A00060FFFF /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B055A771FAE78210060FFFF /* SDL2.framework */; }; 4B055A7E1FAE84AA0060FFFF /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B055A7C1FAE84A50060FFFF /* main.cpp */; }; @@ -680,6 +682,8 @@ /* Begin PBXFileReference section */ 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = ""; }; + 4B0333AD2094081A0050B93D /* AppleDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AppleDSK.cpp; sourceTree = ""; }; + 4B0333AE2094081A0050B93D /* AppleDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AppleDSK.hpp; sourceTree = ""; }; 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = ""; }; 4B047075201ABC180047AB0D /* Cartridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = ""; }; 4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = ""; }; @@ -1869,6 +1873,7 @@ isa = PBXGroup; children = ( 4B45188D1F75FD1B00926311 /* AcornADF.cpp */, + 4B0333AD2094081A0050B93D /* AppleDSK.cpp */, 4B45188F1F75FD1B00926311 /* CPCDSK.cpp */, 4B4518911F75FD1B00926311 /* D64.cpp */, 4BAF2B4C2004580C00480230 /* DMK.cpp */, @@ -1879,7 +1884,9 @@ 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */, 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */, 4B4518991F75FD1B00926311 /* SSD.cpp */, + 4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */, 4B45188E1F75FD1B00926311 /* AcornADF.hpp */, + 4B0333AE2094081A0050B93D /* AppleDSK.hpp */, 4B4518901F75FD1B00926311 /* CPCDSK.hpp */, 4B4518921F75FD1B00926311 /* D64.hpp */, 4BAF2B4D2004580C00480230 /* DMK.hpp */, @@ -1890,9 +1897,8 @@ 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */, 4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */, 4B45189A1F75FD1B00926311 /* SSD.hpp */, - 4BFDD7891F7F2DB4008579B9 /* Utility */, - 4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */, 4B6ED2EF208E2F8A0047B343 /* WOZ.hpp */, + 4BFDD7891F7F2DB4008579B9 /* Utility */, ); path = Formats; sourceTree = ""; @@ -3650,6 +3656,7 @@ 4BAF2B4F2004580C00480230 /* DMK.cpp in Sources */, 4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */, 4B055A961FAE85BB0060FFFF /* Commodore.cpp in Sources */, + 4B0333B02094081A0050B93D /* AppleDSK.cpp in Sources */, 4B055ADE1FAE9B4C0060FFFF /* 6522Base.cpp in Sources */, 4B894535201967B4007DE474 /* AddressMapper.cpp in Sources */, 4B055AD41FAE9B0B0060FFFF /* Oric.cpp in Sources */, @@ -3727,6 +3734,7 @@ 4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */, 4BAE49582032881E004BE78E /* CSZX8081.mm in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, + 4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */, 4B894518201967B4007DE474 /* ConfidenceCounter.cpp in Sources */, 4B89452E201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B38F3481F2EC11D00D9235D /* AmstradCPC.cpp in Sources */, diff --git a/Storage/Disk/DiskImage/DiskImage.hpp b/Storage/Disk/DiskImage/DiskImage.hpp index 7237c8b53..86dbcb657 100644 --- a/Storage/Disk/DiskImage/DiskImage.hpp +++ b/Storage/Disk/DiskImage/DiskImage.hpp @@ -18,6 +18,11 @@ namespace Storage { namespace Disk { +enum class Error { + InvalidFormat = -2, + UnknownVersion = -3 +}; + /*! Models a disk image as a collection of tracks, plus a range of possible track positions. diff --git a/Storage/Disk/DiskImage/Formats/AcornADF.cpp b/Storage/Disk/DiskImage/Formats/AcornADF.cpp index 653b10bd2..df5864453 100644 --- a/Storage/Disk/DiskImage/Formats/AcornADF.cpp +++ b/Storage/Disk/DiskImage/Formats/AcornADF.cpp @@ -20,18 +20,18 @@ using namespace Storage::Disk; AcornADF::AcornADF(const std::string &file_name) : MFMSectorDump(file_name) { // very loose validation: the file needs to be a multiple of 256 bytes // and not ungainly large - if(file_.stats().st_size % static_cast(128 << sector_size)) throw ErrorNotAcornADF; - if(file_.stats().st_size < 7 * static_cast(128 << sector_size)) throw ErrorNotAcornADF; + if(file_.stats().st_size % static_cast(128 << sector_size)) throw Error::InvalidFormat; + if(file_.stats().st_size < 7 * static_cast(128 << sector_size)) throw Error::InvalidFormat; // check that the initial directory's 'Hugo's are present file_.seek(513, SEEK_SET); uint8_t bytes[4]; file_.read(bytes, 4); - if(bytes[0] != 'H' || bytes[1] != 'u' || bytes[2] != 'g' || bytes[3] != 'o') throw ErrorNotAcornADF; + if(bytes[0] != 'H' || bytes[1] != 'u' || bytes[2] != 'g' || bytes[3] != 'o') throw Error::InvalidFormat; file_.seek(0x6fb, SEEK_SET); file_.read(bytes, 4); - if(bytes[0] != 'H' || bytes[1] != 'u' || bytes[2] != 'g' || bytes[3] != 'o') throw ErrorNotAcornADF; + if(bytes[0] != 'H' || bytes[1] != 'u' || bytes[2] != 'g' || bytes[3] != 'o') throw Error::InvalidFormat; set_geometry(sectors_per_track, sector_size, 0, true); } diff --git a/Storage/Disk/DiskImage/Formats/AcornADF.hpp b/Storage/Disk/DiskImage/Formats/AcornADF.hpp index 7cd115308..11e24a95c 100644 --- a/Storage/Disk/DiskImage/Formats/AcornADF.hpp +++ b/Storage/Disk/DiskImage/Formats/AcornADF.hpp @@ -24,15 +24,11 @@ class AcornADF: public MFMSectorDump { /*! Construct an @c AcornADF containing content from the file with name @c file_name. - @throws ErrorCantOpen if this file can't be opened. - @throws ErrorNotAcornADF if the file doesn't appear to contain an Acorn .ADF format image. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain an Acorn .ADF format image. */ AcornADF(const std::string &file_name); - enum { - ErrorNotAcornADF, - }; - int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/AppleDSK.cpp b/Storage/Disk/DiskImage/Formats/AppleDSK.cpp new file mode 100644 index 000000000..cf1c68568 --- /dev/null +++ b/Storage/Disk/DiskImage/Formats/AppleDSK.cpp @@ -0,0 +1,37 @@ +// +// AppleDSK.cpp +// Clock Signal +// +// Created by Thomas Harte on 27/04/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#include "AppleDSK.hpp" + +using namespace Storage::Disk; + +namespace { + const int number_of_tracks = 35; + const int bytes_per_sector = 256; +} + +AppleDSK::AppleDSK(const std::string &file_name) : + file_(file_name) { + if(file_.stats().st_size % number_of_tracks*bytes_per_sector) throw Error::InvalidFormat; + + sectors_per_track_ = static_cast(file_.stats().st_size / (number_of_tracks*bytes_per_sector)); + if(sectors_per_track_ != 13 && sectors_per_track_ != 16) throw Error::InvalidFormat; +} + +int AppleDSK::get_head_position_count() { + return number_of_tracks * 4; +} + +std::shared_ptr AppleDSK::get_track_at_position(Track::Address address) { + const long file_offset = (address.position >> 2) * bytes_per_sector * sectors_per_track_; + file_.seek(file_offset, SEEK_SET); + +// std::vector track_data = file_.read(bytes_per_sector * sectors_per_track_); + + return nullptr; +} diff --git a/Storage/Disk/DiskImage/Formats/AppleDSK.hpp b/Storage/Disk/DiskImage/Formats/AppleDSK.hpp new file mode 100644 index 000000000..465c73e87 --- /dev/null +++ b/Storage/Disk/DiskImage/Formats/AppleDSK.hpp @@ -0,0 +1,47 @@ +// +// AppleDSK.hpp +// Clock Signal +// +// Created by Thomas Harte on 27/04/2018. +// Copyright © 2018 Thomas Harte. All rights reserved. +// + +#ifndef AppleDSK_hpp +#define AppleDSK_hpp + +#include "../DiskImage.hpp" +#include "../../../FileHolder.hpp" + +#include + +namespace Storage { +namespace Disk { + +/*! + Provides a @c DiskImage containing an Apple DSK disk image — a representation of sector contents, + implicitly numbered and located. +*/ +class AppleDSK: public DiskImage { + public: + /*! + Construct an @c AppleDSK containing content from the file with name @c file_name. + + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain a .G64 format image. + */ + AppleDSK(const std::string &file_name); + + // implemented to satisfy @c Disk + int get_head_position_count() override; + std::shared_ptr get_track_at_position(Track::Address address) override; + + private: + Storage::FileHolder file_; + int sectors_per_track_; +}; + +} +} + + +#endif /* AppleDSK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/CPCDSK.cpp b/Storage/Disk/DiskImage/Formats/CPCDSK.cpp index 2fa9f5751..db5090b97 100644 --- a/Storage/Disk/DiskImage/Formats/CPCDSK.cpp +++ b/Storage/Disk/DiskImage/Formats/CPCDSK.cpp @@ -27,7 +27,7 @@ CPCDSK::CPCDSK(const std::string &file_name) : is_extended_ = true; file.seek(0, SEEK_SET); if(!file.check_signature("EXTENDED")) - throw ErrorNotCPCDSK; + throw Error::InvalidFormat; } // Don't really care about about the creator; skip. @@ -145,7 +145,7 @@ CPCDSK::CPCDSK(const std::string &file_name) : if(declared_data_size > data_size) { number_of_samplings = declared_data_size / data_size; if(declared_data_size % data_size) - throw ErrorNotCPCDSK; + throw Error::InvalidFormat; } else { stored_data_size = declared_data_size; } diff --git a/Storage/Disk/DiskImage/Formats/CPCDSK.hpp b/Storage/Disk/DiskImage/Formats/CPCDSK.hpp index 5d19db4dc..d946ea3f8 100644 --- a/Storage/Disk/DiskImage/Formats/CPCDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/CPCDSK.hpp @@ -27,15 +27,11 @@ class CPCDSK: public DiskImage { /*! Construct an @c AcornADF containing content from the file with name @c file_name. - @throws ErrorCantOpen if this file can't be opened. - @throws ErrorNotAcornADF if the file doesn't appear to contain an Acorn .ADF format image. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain an Acorn .ADF format image. */ CPCDSK(const std::string &file_name); - enum { - ErrorNotCPCDSK, - }; - // implemented to satisfy @c Disk int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/D64.cpp b/Storage/Disk/DiskImage/Formats/D64.cpp index 8522b7319..d82826b1c 100644 --- a/Storage/Disk/DiskImage/Formats/D64.cpp +++ b/Storage/Disk/DiskImage/Formats/D64.cpp @@ -22,7 +22,7 @@ D64::D64(const std::string &file_name) : // in D64, this is it for validation without imposing potential false-negative tests — check that // the file size appears to be correct. Stone-age stuff. if(file_.stats().st_size != 174848 && file_.stats().st_size != 196608) - throw ErrorNotD64; + throw Error::InvalidFormat; number_of_tracks_ = (file_.stats().st_size == 174848) ? 35 : 40; diff --git a/Storage/Disk/DiskImage/Formats/D64.hpp b/Storage/Disk/DiskImage/Formats/D64.hpp index d395ecd15..a412607ac 100644 --- a/Storage/Disk/DiskImage/Formats/D64.hpp +++ b/Storage/Disk/DiskImage/Formats/D64.hpp @@ -23,15 +23,11 @@ class D64: public DiskImage { /*! Construct a @c D64 containing content from the file with name @c file_name. - @throws ErrorCantOpen if this file can't be opened. - @throws ErrorNotD64 if the file doesn't appear to contain a .D64 format image. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain a .D64 format image. */ D64(const std::string &file_name); - enum { - ErrorNotD64, - }; - // implemented to satisfy @c Disk int get_head_position_count() override; using DiskImage::get_is_read_only; diff --git a/Storage/Disk/DiskImage/Formats/DMK.cpp b/Storage/Disk/DiskImage/Formats/DMK.cpp index 13a1af8c6..92fe728a7 100644 --- a/Storage/Disk/DiskImage/Formats/DMK.cpp +++ b/Storage/Disk/DiskImage/Formats/DMK.cpp @@ -35,9 +35,9 @@ std::unique_ptr new_encoder(Storage::Disk::PCM DMK::DMK(const std::string &file_name) : file_(file_name) { // Determine whether this DMK represents a read-only disk (whether intentionally, - // or by virtue of placement). + // or by virtue of filesystem placement). uint8_t read_only_byte = file_.get8(); - if(read_only_byte != 0x00 && read_only_byte != 0xff) throw ErrorNotDMK; + if(read_only_byte != 0x00 && read_only_byte != 0xff) throw Error::InvalidFormat; is_read_only_ = (read_only_byte == 0xff) || file_.get_is_known_read_only(); // Read track count and size. @@ -46,7 +46,7 @@ DMK::DMK(const std::string &file_name) : // Track length must be at least 0x80, as that's the size of the IDAM // table before track contents. - if(track_length_ < 0x80) throw ErrorNotDMK; + if(track_length_ < 0x80) throw Error::InvalidFormat; // Read the file flags and apply them. uint8_t flags = file_.get8(); @@ -58,7 +58,7 @@ DMK::DMK(const std::string &file_name) : // "in the emulator's native format". file_.seek(0xc, SEEK_SET); uint32_t format = file_.get32le(); - if(format) throw ErrorNotDMK; + if(format) throw Error::InvalidFormat; } int DMK::get_head_position_count() { diff --git a/Storage/Disk/DiskImage/Formats/DMK.hpp b/Storage/Disk/DiskImage/Formats/DMK.hpp index 6be4eaed4..af772530e 100644 --- a/Storage/Disk/DiskImage/Formats/DMK.hpp +++ b/Storage/Disk/DiskImage/Formats/DMK.hpp @@ -26,14 +26,10 @@ class DMK: public DiskImage { /*! Construct a @c DMK containing content from the file with name @c file_name. - @throws ErrorNotDMK if this file doesn't appear to be a DMK. + @throws Error::InvalidFormat if this file doesn't appear to be a DMK. */ DMK(const std::string &file_name); - enum { - ErrorNotDMK - }; - // implemented to satisfy @c Disk int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/G64.cpp b/Storage/Disk/DiskImage/Formats/G64.cpp index c80460c88..87ee86763 100644 --- a/Storage/Disk/DiskImage/Formats/G64.cpp +++ b/Storage/Disk/DiskImage/Formats/G64.cpp @@ -19,11 +19,11 @@ using namespace Storage::Disk; G64::G64(const std::string &file_name) : file_(file_name) { // read and check the file signature - if(!file_.check_signature("GCR-1541")) throw ErrorNotG64; + if(!file_.check_signature("GCR-1541")) throw Error::InvalidFormat; // check the version number int version = file_.get8(); - if(version != 0) throw ErrorUnknownVersion; + if(version != 0) throw Error::UnknownVersion; // get the number of tracks and track size number_of_tracks_ = file_.get8(); diff --git a/Storage/Disk/DiskImage/Formats/G64.hpp b/Storage/Disk/DiskImage/Formats/G64.hpp index c10ef7e04..2b27fca73 100644 --- a/Storage/Disk/DiskImage/Formats/G64.hpp +++ b/Storage/Disk/DiskImage/Formats/G64.hpp @@ -25,18 +25,12 @@ class G64: public DiskImage { /*! Construct a @c G64 containing content from the file with name @c file_name. - @throws ErrorCantOpen if this file can't be opened. - @throws ErrorNotG64 if the file doesn't appear to contain a .G64 format image. - @throws ErrorUnknownVersion if this file appears to be a .G64 but has an unrecognised version number. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain a .G64 format image. + @throws Error::UnknownVersion if this file appears to be a .G64 but has an unrecognised version number. */ G64(const std::string &file_name); - enum { - ErrorCantOpen, - ErrorNotG64, - ErrorUnknownVersion - }; - // implemented to satisfy @c Disk int get_head_position_count() override; std::shared_ptr get_track_at_position(Track::Address address) override; diff --git a/Storage/Disk/DiskImage/Formats/HFE.cpp b/Storage/Disk/DiskImage/Formats/HFE.cpp index 14e0c0004..05549a2cb 100644 --- a/Storage/Disk/DiskImage/Formats/HFE.cpp +++ b/Storage/Disk/DiskImage/Formats/HFE.cpp @@ -16,9 +16,9 @@ using namespace Storage::Disk; HFE::HFE(const std::string &file_name) : file_(file_name) { - if(!file_.check_signature("HXCPICFE")) throw ErrorNotHFE; + if(!file_.check_signature("HXCPICFE")) throw Error::InvalidFormat; - if(file_.get8()) throw ErrorNotHFE; + if(file_.get8()) throw Error::UnknownVersion; track_count_ = file_.get8(); head_count_ = file_.get8(); diff --git a/Storage/Disk/DiskImage/Formats/HFE.hpp b/Storage/Disk/DiskImage/Formats/HFE.hpp index 8283a0f6a..bf66af727 100644 --- a/Storage/Disk/DiskImage/Formats/HFE.hpp +++ b/Storage/Disk/DiskImage/Formats/HFE.hpp @@ -25,15 +25,13 @@ class HFE: public DiskImage { /*! Construct an @c HFE containing content from the file with name @c file_name. - @throws ErrorNotHFE if the file doesn't appear to contain a .SSD format image. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain an .HFE format image. + @throws Error::UnknownVersion if the file looks correct but is an unsupported version. */ HFE(const std::string &file_name); ~HFE(); - enum { - ErrorNotHFE - }; - // implemented to satisfy @c Disk int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/MSXDSK.cpp b/Storage/Disk/DiskImage/Formats/MSXDSK.cpp index 7cd8b6bd1..9b03de6d6 100644 --- a/Storage/Disk/DiskImage/Formats/MSXDSK.cpp +++ b/Storage/Disk/DiskImage/Formats/MSXDSK.cpp @@ -25,16 +25,16 @@ MSXDSK::MSXDSK(const std::string &file_name) : off_t file_size = file_.stats().st_size; // Throw if there would seemingly be an incomplete track. - if(file_size % track_size) throw ErrorNotMSXDSK; + if(file_size % track_size) throw Error::InvalidFormat; track_count_ = static_cast(file_size / track_size); head_count_ = 1; // Throw if too large or too small or too large for single sided and // clearly not double sided. - if(track_count_ < 40) throw ErrorNotMSXDSK; - if(track_count_ > 82*2) throw ErrorNotMSXDSK; - if(track_count_ > 82 && track_count_&1) throw ErrorNotMSXDSK; + if(track_count_ < 40) throw Error::InvalidFormat; + if(track_count_ > 82*2) throw Error::InvalidFormat; + if(track_count_ > 82 && track_count_&1) throw Error::InvalidFormat; // The below effectively prefers the idea of a single-sided 80-track disk // to a double-sided 40-track disk. Emulators have to guess. diff --git a/Storage/Disk/DiskImage/Formats/MSXDSK.hpp b/Storage/Disk/DiskImage/Formats/MSXDSK.hpp index 8bf8936c1..74d7f9247 100644 --- a/Storage/Disk/DiskImage/Formats/MSXDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/MSXDSK.hpp @@ -23,11 +23,6 @@ namespace Disk { class MSXDSK: public MFMSectorDump { public: MSXDSK(const std::string &file_name); - - enum { - ErrorNotMSXDSK, - }; - int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/NIB.cpp b/Storage/Disk/DiskImage/Formats/NIB.cpp index 41cab6631..afc5870f3 100644 --- a/Storage/Disk/DiskImage/Formats/NIB.cpp +++ b/Storage/Disk/DiskImage/Formats/NIB.cpp @@ -26,7 +26,7 @@ NIB::NIB(const std::string &file_name) : file_(file_name) { // A NIB should be 35 tracks, each 6656 bytes long. if(file_.stats().st_size != track_length*number_of_tracks) { - throw ErrorNotNIB; + throw Error::InvalidFormat; } // TODO: all other validation. I.e. does this look like a GCR disk? diff --git a/Storage/Disk/DiskImage/Formats/NIB.hpp b/Storage/Disk/DiskImage/Formats/NIB.hpp index fff52ca95..bde1f4322 100644 --- a/Storage/Disk/DiskImage/Formats/NIB.hpp +++ b/Storage/Disk/DiskImage/Formats/NIB.hpp @@ -24,10 +24,6 @@ class NIB: public DiskImage { public: NIB(const std::string &file_name); - enum { - ErrorNotNIB, - }; - int get_head_position_count() override; std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) override; diff --git a/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp b/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp index d43700067..8c0f754e4 100644 --- a/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp +++ b/Storage/Disk/DiskImage/Formats/OricMFMDSK.cpp @@ -19,14 +19,14 @@ using namespace Storage::Disk; OricMFMDSK::OricMFMDSK(const std::string &file_name) : file_(file_name) { if(!file_.check_signature("MFM_DISK")) - throw ErrorNotOricMFMDSK; + throw Error::InvalidFormat; head_count_ = file_.get32le(); track_count_ = file_.get32le(); geometry_type_ = file_.get32le(); if(geometry_type_ < 1 || geometry_type_ > 2) - throw ErrorNotOricMFMDSK; + throw Error::InvalidFormat; } int OricMFMDSK::get_head_position_count() { diff --git a/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp b/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp index c6b6d60be..14fa16ecd 100644 --- a/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp @@ -29,10 +29,6 @@ class OricMFMDSK: public DiskImage { */ OricMFMDSK(const std::string &file_name); - enum { - ErrorNotOricMFMDSK, - }; - // implemented to satisfy @c DiskImage int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/SSD.cpp b/Storage/Disk/DiskImage/Formats/SSD.cpp index 280521d7d..7d8647023 100644 --- a/Storage/Disk/DiskImage/Formats/SSD.cpp +++ b/Storage/Disk/DiskImage/Formats/SSD.cpp @@ -23,9 +23,9 @@ SSD::SSD(const std::string &file_name) : MFMSectorDump(file_name) { // very loose validation: the file needs to be a multiple of 256 bytes // and not ungainly large - if(file_.stats().st_size & 255) throw ErrorNotSSD; - if(file_.stats().st_size < 512) throw ErrorNotSSD; - if(file_.stats().st_size > 800*256) throw ErrorNotSSD; + if(file_.stats().st_size & 255) throw Error::InvalidFormat; + if(file_.stats().st_size < 512) throw Error::InvalidFormat; + if(file_.stats().st_size > 800*256) throw Error::InvalidFormat; // this has two heads if the suffix is .dsd, one if it's .ssd head_count_ = (tolower(file_name[file_name.size() - 3]) == 'd') ? 2 : 1; diff --git a/Storage/Disk/DiskImage/Formats/SSD.hpp b/Storage/Disk/DiskImage/Formats/SSD.hpp index 58f67027c..7eeba9173 100644 --- a/Storage/Disk/DiskImage/Formats/SSD.hpp +++ b/Storage/Disk/DiskImage/Formats/SSD.hpp @@ -22,15 +22,11 @@ class SSD: public MFMSectorDump { /*! Construct an @c SSD containing content from the file with name @c file_name. - @throws ErrorCantOpen if this file can't be opened. - @throws ErrorNotSSD if the file doesn't appear to contain a .SSD format image. + @throws Storage::FileHolder::Error::CantOpen if this file can't be opened. + @throws Error::InvalidFormat if the file doesn't appear to contain a .SSD format image. */ SSD(const std::string &file_name); - enum { - ErrorNotSSD, - }; - int get_head_position_count() override; int get_head_count() override; diff --git a/Storage/Disk/DiskImage/Formats/WOZ.cpp b/Storage/Disk/DiskImage/Formats/WOZ.cpp index 1d76b5f6c..da6395a4e 100644 --- a/Storage/Disk/DiskImage/Formats/WOZ.cpp +++ b/Storage/Disk/DiskImage/Formats/WOZ.cpp @@ -19,12 +19,13 @@ WOZ::WOZ(const std::string &file_name) : 'W', 'O', 'Z', '1', static_cast(0xff), 0x0a, 0x0d, 0x0a }; - if(!file_.check_signature(signature, 8)) throw ErrorNotWOZ; + if(!file_.check_signature(signature, 8)) throw Error::InvalidFormat; // TODO: check CRC32, instead of skipping it. file_.seek(4, SEEK_CUR); // Parse all chunks up front. + bool has_tmap = false; while(true) { const uint32_t chunk_id = file_.get32le(); const uint32_t chunk_size = file_.get32le(); @@ -48,6 +49,7 @@ WOZ::WOZ(const std::string &file_name) : case CK("TMAP"): { file_.read(track_map_, 160); + has_tmap = true; } break; case CK("TRKS"): { @@ -63,6 +65,8 @@ WOZ::WOZ(const std::string &file_name) : file_.seek(end_of_chunk, SEEK_SET); } + + if(tracks_offset_ == -1 || !has_tmap) throw Error::InvalidFormat; } int WOZ::get_head_position_count() { diff --git a/Storage/Disk/DiskImage/Formats/WOZ.hpp b/Storage/Disk/DiskImage/Formats/WOZ.hpp index 16abba35c..afae68e5e 100644 --- a/Storage/Disk/DiskImage/Formats/WOZ.hpp +++ b/Storage/Disk/DiskImage/Formats/WOZ.hpp @@ -24,10 +24,6 @@ class WOZ: public DiskImage { public: WOZ(const std::string &file_name); - enum { - ErrorNotWOZ - }; - int get_head_position_count() override; int get_head_count() override; std::shared_ptr get_track_at_position(Track::Address address) override; @@ -37,7 +33,7 @@ class WOZ: public DiskImage { bool is_read_only_ = false; bool is_3_5_disk_ = false; uint8_t track_map_[160]; - long tracks_offset_ = 0; + long tracks_offset_ = -1; }; } diff --git a/Storage/FileHolder.cpp b/Storage/FileHolder.cpp index d63d2520d..2825db34b 100644 --- a/Storage/FileHolder.cpp +++ b/Storage/FileHolder.cpp @@ -38,7 +38,7 @@ FileHolder::FileHolder(const std::string &file_name, FileMode ideal_mode) break; } - if(!file_) throw ErrorCantOpen; + if(!file_) throw Error::CantOpen; } uint32_t FileHolder::get32le() { diff --git a/Storage/FileHolder.hpp b/Storage/FileHolder.hpp index f4e14b1df..e639b03d3 100644 --- a/Storage/FileHolder.hpp +++ b/Storage/FileHolder.hpp @@ -20,8 +20,8 @@ namespace Storage { class FileHolder final { public: - enum { - ErrorCantOpen = -1 + enum class Error { + CantOpen = -1 }; enum class FileMode {