mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Finally unifies disk image file exceptions, and adds a placeholder for Apple DSK.
This commit is contained in:
parent
5c74044e62
commit
b98d5b790a
@ -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<Storage::Disk::DMK>, TargetPlatform::MSX) // DMK
|
||||
Format("dsd", result.disks, Disk::DiskImageHolder<Storage::Disk::SSD>, TargetPlatform::Acorn) // DSD
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::CPCDSK>, TargetPlatform::AmstradCPC) // DSK (Amstrad CPC)
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::AppleDSK>, TargetPlatform::AppleII) // DSK (Apple)
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::MSXDSK>, TargetPlatform::MSX) // DSK (MSX)
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::OricMFMDSK>, TargetPlatform::Oric) // DSK (Oric)
|
||||
Format("g64", result.disks, Disk::DiskImageHolder<Storage::Disk::G64>, TargetPlatform::Commodore) // G64
|
||||
|
@ -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 = "<group>"; };
|
||||
4B0333AD2094081A0050B93D /* AppleDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AppleDSK.cpp; sourceTree = "<group>"; };
|
||||
4B0333AE2094081A0050B93D /* AppleDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AppleDSK.hpp; sourceTree = "<group>"; };
|
||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
|
||||
4B047075201ABC180047AB0D /* Cartridge.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
|
||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
|
||||
@ -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 = "<group>";
|
||||
@ -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 */,
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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<off_t>(128 << sector_size)) throw ErrorNotAcornADF;
|
||||
if(file_.stats().st_size < 7 * static_cast<off_t>(128 << sector_size)) throw ErrorNotAcornADF;
|
||||
if(file_.stats().st_size % static_cast<off_t>(128 << sector_size)) throw Error::InvalidFormat;
|
||||
if(file_.stats().st_size < 7 * static_cast<off_t>(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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
37
Storage/Disk/DiskImage/Formats/AppleDSK.cpp
Normal file
37
Storage/Disk/DiskImage/Formats/AppleDSK.cpp
Normal file
@ -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<int>(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<Track> 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<uint8_t> track_data = file_.read(bytes_per_sector * sectors_per_track_);
|
||||
|
||||
return nullptr;
|
||||
}
|
47
Storage/Disk/DiskImage/Formats/AppleDSK.hpp
Normal file
47
Storage/Disk/DiskImage/Formats/AppleDSK.hpp
Normal file
@ -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 <string>
|
||||
|
||||
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<Track> get_track_at_position(Track::Address address) override;
|
||||
|
||||
private:
|
||||
Storage::FileHolder file_;
|
||||
int sectors_per_track_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* AppleDSK_hpp */
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -35,9 +35,9 @@ std::unique_ptr<Storage::Encodings::MFM::Encoder> 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() {
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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<Track> get_track_at_position(Track::Address address) override;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<int>(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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -19,12 +19,13 @@ WOZ::WOZ(const std::string &file_name) :
|
||||
'W', 'O', 'Z', '1',
|
||||
static_cast<char>(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() {
|
||||
|
@ -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<Track> 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -20,8 +20,8 @@ namespace Storage {
|
||||
|
||||
class FileHolder final {
|
||||
public:
|
||||
enum {
|
||||
ErrorCantOpen = -1
|
||||
enum class Error {
|
||||
CantOpen = -1
|
||||
};
|
||||
|
||||
enum class FileMode {
|
||||
|
Loading…
Reference in New Issue
Block a user