diff --git a/Analyser/Static/StaticAnalyser.cpp b/Analyser/Static/StaticAnalyser.cpp index 016869b1e..e145e8345 100644 --- a/Analyser/Static/StaticAnalyser.cpp +++ b/Analyser/Static/StaticAnalyser.cpp @@ -43,9 +43,9 @@ #include "../../Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp" #include "../../Storage/Disk/DiskImage/Formats/G64.hpp" #include "../../Storage/Disk/DiskImage/Formats/DMK.hpp" +#include "../../Storage/Disk/DiskImage/Formats/FAT12.hpp" #include "../../Storage/Disk/DiskImage/Formats/HFE.hpp" #include "../../Storage/Disk/DiskImage/Formats/MSA.hpp" -#include "../../Storage/Disk/DiskImage/Formats/MSXDSK.hpp" #include "../../Storage/Disk/DiskImage/Formats/NIB.hpp" #include "../../Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp" #include "../../Storage/Disk/DiskImage/Formats/SSD.hpp" @@ -147,7 +147,7 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::Macintosh) // DSK (Macintosh, floppy disk) Format("dsk", result.mass_storage_devices, MassStorage::HFV, TargetPlatform::Macintosh) // DSK (Macintosh, hard disk, single volume image) Format("dsk", result.mass_storage_devices, MassStorage::DSK, TargetPlatform::Macintosh) // DSK (Macintosh, hard disk, full device image) - Format("dsk", result.disks, Disk::DiskImageHolder, TargetPlatform::MSX) // DSK (MSX) + 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 Format( "hfe", @@ -157,7 +157,7 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: // HFE (TODO: switch to AllDisk once the MSX stops being so greedy) Format("img", result.disks, Disk::DiskImageHolder, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2) Format("image", result.disks, Disk::DiskImageHolder, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2) - Format("img", result.disks, Disk::DiskImageHolder, TargetPlatform::Enterprise) // IMG (Enterprise/MS-DOS style) + Format("img", result.disks, Disk::DiskImageHolder, TargetPlatform::Enterprise) // IMG (Enterprise/MS-DOS style) Format("msa", result.disks, Disk::DiskImageHolder, TargetPlatform::AtariST) // MSA Format("nib", result.disks, Disk::DiskImageHolder, TargetPlatform::DiskII) // NIB Format("o", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index c55e0ded8..ff6cbeb57 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -323,7 +323,7 @@ 4B778F0023A5EB990000D260 /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518931F75FD1B00926311 /* G64.cpp */; }; 4B778F0123A5EBA00000D260 /* MacintoshIMG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */; }; 4B778F0223A5EBA40000D260 /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */; }; - 4B778F0323A5EBB00000D260 /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; }; + 4B778F0323A5EBB00000D260 /* FAT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */; }; 4B778F0423A5EBB00000D260 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; }; 4B778F0523A5EBB00000D260 /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; }; 4B778F0623A5EC150000D260 /* CAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0E04E81FC9E5DA00F43484 /* CAS.cpp */; }; @@ -961,8 +961,8 @@ 4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */; }; 4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; }; 4BEA52631DF339D7007E74F2 /* SoundGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */; }; - 4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; }; - 4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; }; + 4BEBFB4D2002C4BF000708CC /* FAT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */; }; + 4BEBFB4E2002C4BF000708CC /* FAT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */; }; 4BEBFB512002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; }; 4BEBFB522002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; }; 4BEDA3BA25B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B425B25563000C2DBD /* Decoder.cpp */; }; @@ -2021,8 +2021,8 @@ 4BEA52601DF3343A007E74F2 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Interrupts.hpp; sourceTree = ""; }; 4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundGenerator.cpp; sourceTree = ""; }; 4BEA52621DF339D7007E74F2 /* SoundGenerator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SoundGenerator.hpp; sourceTree = ""; }; - 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MSXDSK.cpp; sourceTree = ""; }; - 4BEBFB4C2002C4BF000708CC /* MSXDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MSXDSK.hpp; sourceTree = ""; }; + 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FAT12.cpp; sourceTree = ""; }; + 4BEBFB4C2002C4BF000708CC /* FAT12.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FAT12.hpp; sourceTree = ""; }; 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiskROM.cpp; sourceTree = ""; }; 4BEBFB502002DB30000708CC /* DiskROM.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskROM.hpp; sourceTree = ""; }; 4BEDA3B425B25563000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = ""; }; @@ -2713,7 +2713,7 @@ 4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */, 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */, 4BC131782346DF2B00E4FF3D /* MSA.cpp */, - 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */, + 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */, 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */, 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */, 4B4518991F75FD1B00926311 /* SSD.cpp */, @@ -2730,7 +2730,7 @@ 4BB4BFAF22A42F290069048D /* MacintoshIMG.hpp */, 4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */, 4BC131792346DF2B00E4FF3D /* MSA.hpp */, - 4BEBFB4C2002C4BF000708CC /* MSXDSK.hpp */, + 4BEBFB4C2002C4BF000708CC /* FAT12.hpp */, 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */, 4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */, 4B45189A1F75FD1B00926311 /* SSD.hpp */, @@ -5283,7 +5283,7 @@ 4BB4BFBA22A4372F0069048D /* StaticAnalyser.cpp in Sources */, 4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */, 4B2E86E325DC95150024F1E9 /* Joystick.cpp in Sources */, - 4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */, + 4BEBFB4E2002C4BF000708CC /* FAT12.cpp in Sources */, 4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */, 4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */, 4B2BF19223DCC6A800C3AD60 /* STX.cpp in Sources */, @@ -5597,7 +5597,7 @@ 4B894536201967B4007DE474 /* Z80.cpp in Sources */, 4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */, 4BC1317A2346DF2B00E4FF3D /* MSA.cpp in Sources */, - 4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */, + 4BEBFB4D2002C4BF000708CC /* FAT12.cpp in Sources */, 4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */, 4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */, 4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */, @@ -5745,7 +5745,7 @@ 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, 4B778F6023A5F3460000D260 /* Disk.cpp in Sources */, 4B778F5C23A5F3070000D260 /* MSX.cpp in Sources */, - 4B778F0323A5EBB00000D260 /* MSXDSK.cpp in Sources */, + 4B778F0323A5EBB00000D260 /* FAT12.cpp in Sources */, 4B778F4023A5F1910000D260 /* z8530.cpp in Sources */, 4B778EFD23A5EB8E0000D260 /* AppleDSK.cpp in Sources */, 4B778EFB23A5EB7E0000D260 /* HFE.cpp in Sources */, diff --git a/Storage/Disk/DiskImage/Formats/FAT12.cpp b/Storage/Disk/DiskImage/Formats/FAT12.cpp new file mode 100644 index 000000000..ebdb1b8bf --- /dev/null +++ b/Storage/Disk/DiskImage/Formats/FAT12.cpp @@ -0,0 +1,57 @@ +// +// FAT12.cpp +// Clock Signal +// +// Created by Thomas Harte on 07/01/2018. +// Copyright 2018 Thomas Harte. All rights reserved. +// + +#include "FAT12.hpp" + +#include "Utility/ImplicitSectors.hpp" + +using namespace Storage::Disk; + +FAT12::FAT12(const std::string &file_name) : + MFMSectorDump(file_name) { + // The only sanity check here is whether a sensible + // geometry is encoded in the first sector, or can be guessed. + off_t file_size = file_.stats().st_size; + + if(file_size < 512) throw Error::InvalidFormat; + + // Inspect the FAT. + file_.seek(11, SEEK_SET); + sector_size_ = file_.get16le(); + file_.seek(19, SEEK_SET); + const uint16_t total_sectors = file_.get16le(); + file_.seek(24, SEEK_SET); + sector_count_ = file_.get16le(); + head_count_ = file_.get16le(); + + // Throw if there would seemingly be an incomplete track. + if(file_size != total_sectors*sector_size_) throw Error::InvalidFormat; + if(total_sectors % (head_count_ * sector_count_)) throw Error::InvalidFormat; + track_count_ = int(total_sectors / (head_count_ * sector_count_)); + + // Check that there is a valid power-of-two sector size. + uint8_t log_sector_size = 2; + while(log_sector_size < 5 && (1 << (7+log_sector_size)) != sector_size_) { + ++log_sector_size; + } + if(log_sector_size >= 5) throw Error::InvalidFormat; + + set_geometry(sector_count_, log_sector_size, 1, true); +} + +HeadPosition FAT12::get_maximum_head_position() { + return HeadPosition(track_count_); +} + +int FAT12::get_head_count() { + return head_count_; +} + +long FAT12::get_file_offset_for_position(Track::Address address) { + return (address.position.as_int()*head_count_ + address.head) * sector_size_ * sector_count_; +} diff --git a/Storage/Disk/DiskImage/Formats/MSXDSK.hpp b/Storage/Disk/DiskImage/Formats/FAT12.hpp similarity index 73% rename from Storage/Disk/DiskImage/Formats/MSXDSK.hpp rename to Storage/Disk/DiskImage/Formats/FAT12.hpp index f88c46754..044612466 100644 --- a/Storage/Disk/DiskImage/Formats/MSXDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/FAT12.hpp @@ -1,5 +1,5 @@ // -// MSXDSK.hpp +// FAT12.hpp // Clock Signal // // Created by Thomas Harte on 07/01/2018. @@ -17,12 +17,12 @@ namespace Storage { namespace Disk { /*! - Provides a @c DiskImage describing an MSDOS-style disk image: + Provides a @c DiskImage holding an MSDOS-style FAT12 disk image: a sector dump of appropriate proportions. */ -class MSXDSK: public MFMSectorDump { +class FAT12: public MFMSectorDump { public: - MSXDSK(const std::string &file_name); + FAT12(const std::string &file_name); HeadPosition get_maximum_head_position() final; int get_head_count() final; @@ -31,6 +31,8 @@ class MSXDSK: public MFMSectorDump { int head_count_; int track_count_; + int sector_count_; + int sector_size_; }; } diff --git a/Storage/Disk/DiskImage/Formats/MSXDSK.cpp b/Storage/Disk/DiskImage/Formats/MSXDSK.cpp deleted file mode 100644 index f811a3599..000000000 --- a/Storage/Disk/DiskImage/Formats/MSXDSK.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// MSXDSK.cpp -// Clock Signal -// -// Created by Thomas Harte on 07/01/2018. -// Copyright 2018 Thomas Harte. All rights reserved. -// - -#include "MSXDSK.hpp" - -#include "Utility/ImplicitSectors.hpp" - -namespace { - constexpr int sectors_per_track = 9; - constexpr int sector_size = 2; - constexpr off_t track_size = (128 << sector_size)*sectors_per_track; -} - -using namespace Storage::Disk; - -MSXDSK::MSXDSK(const std::string &file_name) : - MFMSectorDump(file_name) { - // The only sanity check here is whether a sensible - // geometry can be guessed. - off_t file_size = file_.stats().st_size; - - // Throw if there would seemingly be an incomplete track. - if(file_size % track_size) throw Error::InvalidFormat; - - track_count_ = 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 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. - if(track_count_ > 82) { - track_count_ /= 2; - head_count_ = 2; - } - - set_geometry(sectors_per_track, sector_size, 1, true); -} - -HeadPosition MSXDSK::get_maximum_head_position() { - return HeadPosition(track_count_); -} - -int MSXDSK::get_head_count() { - return head_count_; -} - -long MSXDSK::get_file_offset_for_position(Track::Address address) { - return (address.position.as_int()*head_count_ + address.head) * 512 * 9; -}