1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-26 10:29:31 +00:00

Finally unifies disk image file exceptions, and adds a placeholder for Apple DSK.

This commit is contained in:
Thomas Harte 2018-04-27 23:18:45 -04:00
parent 5c74044e62
commit b98d5b790a
29 changed files with 150 additions and 92 deletions

View File

@ -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

View File

@ -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 */,

View File

@ -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.

View File

@ -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);
}

View File

@ -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;

View 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;
}

View 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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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?

View File

@ -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;

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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() {

View File

@ -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;
};
}

View File

@ -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() {

View File

@ -20,8 +20,8 @@ namespace Storage {
class FileHolder final {
public:
enum {
ErrorCantOpen = -1
enum class Error {
CantOpen = -1
};
enum class FileMode {