From b16e3de17087f28ee9a05dcc5c7d3b98329c4f49 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 1 Dec 2023 17:23:13 -0500 Subject: [PATCH] Accept what look like raw booters. --- Analyser/Static/StaticAnalyser.cpp | 4 +- .../Clock Signal.xcodeproj/project.pbxproj | 8 ++++ Storage/Disk/DiskImage/Formats/FAT12.hpp | 6 +-- Storage/Disk/DiskImage/Formats/PCBooter.cpp | 48 +++++++++++++++++++ Storage/Disk/DiskImage/Formats/PCBooter.hpp | 37 ++++++++++++++ Storage/TargetPlatforms.hpp | 3 +- 6 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 Storage/Disk/DiskImage/Formats/PCBooter.cpp create mode 100644 Storage/Disk/DiskImage/Formats/PCBooter.hpp diff --git a/Analyser/Static/StaticAnalyser.cpp b/Analyser/Static/StaticAnalyser.cpp index c7e2578bc..d0d91bbdf 100644 --- a/Analyser/Static/StaticAnalyser.cpp +++ b/Analyser/Static/StaticAnalyser.cpp @@ -53,6 +53,7 @@ #include "../../Storage/Disk/DiskImage/Formats/MSA.hpp" #include "../../Storage/Disk/DiskImage/Formats/NIB.hpp" #include "../../Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp" +#include "../../Storage/Disk/DiskImage/Formats/PCBooter.hpp" #include "../../Storage/Disk/DiskImage/Formats/SSD.hpp" #include "../../Storage/Disk/DiskImage/Formats/STX.hpp" #include "../../Storage/Disk/DiskImage/Formats/WOZ.hpp" @@ -179,9 +180,10 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform:: TargetPlatform::Acorn | TargetPlatform::AmstradCPC | TargetPlatform::Commodore | TargetPlatform::Oric | TargetPlatform::ZXSpectrum) // HFE (TODO: switch to AllDisk once the MSX stops being so greedy) Format("ima", result.disks, Disk::DiskImageHolder, TargetPlatform::PCCompatible) // IMG (Enterprise/MS-DOS style) - 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::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::PCCompatible) // IMG (PC raw booter) Format( "ipf", result.disks, Disk::DiskImageHolder, diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 95bd725c0..b77825539 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 423820112B17CBC800964EFE /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820102B17CBC800964EFE /* StaticAnalyser.cpp */; }; 423820122B17CBC800964EFE /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820102B17CBC800964EFE /* StaticAnalyser.cpp */; }; + 423820442B1A90BE00964EFE /* PCBooter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820422B1A90BE00964EFE /* PCBooter.cpp */; }; + 423820452B1A90BE00964EFE /* PCBooter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 423820422B1A90BE00964EFE /* PCBooter.cpp */; }; 423BDC4A2AB24699008E37B6 /* 8088Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 423BDC492AB24699008E37B6 /* 8088Tests.mm */; }; 42437B332AC70833006DFED1 /* HDV.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6FD0342923061300EC4760 /* HDV.cpp */; }; 425739382B051EA800B7D1E4 /* PCCompatible.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 425739372B051EA800B7D1E4 /* PCCompatible.cpp */; }; @@ -1136,6 +1138,8 @@ 423820132B1A235200964EFE /* Memory.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Memory.hpp; sourceTree = ""; }; 423820142B1A23C200964EFE /* Registers.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Registers.hpp; sourceTree = ""; }; 423820152B1A23E100964EFE /* Segments.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Segments.hpp; sourceTree = ""; }; + 423820422B1A90BE00964EFE /* PCBooter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PCBooter.cpp; sourceTree = ""; }; + 423820432B1A90BE00964EFE /* PCBooter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PCBooter.hpp; sourceTree = ""; }; 423BDC492AB24699008E37B6 /* 8088Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 8088Tests.mm; sourceTree = ""; }; 42437B342ACF02A9006DFED1 /* Flags.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Flags.hpp; sourceTree = ""; }; 42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = ""; }; @@ -3047,6 +3051,7 @@ 4BC131782346DF2B00E4FF3D /* MSA.cpp */, 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */, 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */, + 423820422B1A90BE00964EFE /* PCBooter.cpp */, 4B4518991F75FD1B00926311 /* SSD.cpp */, 4B7BA03323C58B1E00B98D9E /* STX.cpp */, 4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */, @@ -3066,6 +3071,7 @@ 4BC131792346DF2B00E4FF3D /* MSA.hpp */, 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */, 4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */, + 423820432B1A90BE00964EFE /* PCBooter.hpp */, 4B45189A1F75FD1B00926311 /* SSD.hpp */, 4B7BA03223C58B1E00B98D9E /* STX.hpp */, 4B6ED2EF208E2F8A0047B343 /* WOZ.hpp */, @@ -5822,6 +5828,7 @@ 4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */, 4B2BF19223DCC6A800C3AD60 /* STX.cpp in Sources */, 4B0ACC2723775819008902D0 /* AtariST.cpp in Sources */, + 423820452B1A90BE00964EFE /* PCBooter.cpp in Sources */, 4B8318B922D3E56D006DB630 /* MemoryPacker.cpp in Sources */, 4B055ABA1FAE86170060FFFF /* Commodore.cpp in Sources */, 4B0ACC2F23775819008902D0 /* TIA.cpp in Sources */, @@ -6122,6 +6129,7 @@ 4B051CA826781D6500CA44E8 /* StaticAnalyser.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, 4B4518841F75E91A00926311 /* UnformattedTrack.cpp in Sources */, + 423820442B1A90BE00964EFE /* PCBooter.cpp in Sources */, 4B65086022F4CF8D009C1100 /* Keyboard.cpp in Sources */, 4B47770B268FBE4D005C2340 /* FAT.cpp in Sources */, 4B894528201967B4007DE474 /* Disk.cpp in Sources */, diff --git a/Storage/Disk/DiskImage/Formats/FAT12.hpp b/Storage/Disk/DiskImage/Formats/FAT12.hpp index b3a91ffa0..66e9692c8 100644 --- a/Storage/Disk/DiskImage/Formats/FAT12.hpp +++ b/Storage/Disk/DiskImage/Formats/FAT12.hpp @@ -6,8 +6,8 @@ // Copyright 2018 Thomas Harte. All rights reserved. // -#ifndef MSXDSK_hpp -#define MSXDSK_hpp +#ifndef FAT12_hpp +#define FAT12_hpp #include "MFMSectorDump.hpp" @@ -36,4 +36,4 @@ class FAT12: public MFMSectorDump { } -#endif /* MSXDSK_hpp */ +#endif /* FAT12_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/PCBooter.cpp b/Storage/Disk/DiskImage/Formats/PCBooter.cpp new file mode 100644 index 000000000..167755cf1 --- /dev/null +++ b/Storage/Disk/DiskImage/Formats/PCBooter.cpp @@ -0,0 +1,48 @@ +// +// FAT12.cpp +// Clock Signal +// +// Created by Thomas Harte on 07/01/2018. +// Copyright 2018 Thomas Harte. All rights reserved. +// + +#include "PCBooter.hpp" + +#include "Utility/ImplicitSectors.hpp" + +using namespace Storage::Disk; + +PCBooter::PCBooter(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. + const auto file_size = file_.stats().st_size; + + // Check that file size is one of the accepted options. + switch(file_size) { + default: throw Error::InvalidFormat; + + // Check for a single-sided, single-density 40-track image. + case 512 * 9 * 40: + head_count_ = 1; + track_count_ = 40; + set_geometry(9, 2, 1, true); + break; + } + + // TODO: check that an appropriate INT or similar is here? + // Should probably factor out the "does this look like a PC boot sector?" test, + // as it can also be used to disambiguate FAT12 disks. +} + +HeadPosition PCBooter::get_maximum_head_position() { + return HeadPosition(track_count_); +} + +int PCBooter::get_head_count() { + return head_count_; +} + +long PCBooter::get_file_offset_for_position(Track::Address address) { + return (address.position.as_int() * head_count_ + address.head) * 512 * 9; +} diff --git a/Storage/Disk/DiskImage/Formats/PCBooter.hpp b/Storage/Disk/DiskImage/Formats/PCBooter.hpp new file mode 100644 index 000000000..cefdc730c --- /dev/null +++ b/Storage/Disk/DiskImage/Formats/PCBooter.hpp @@ -0,0 +1,37 @@ +// +// PCBooter.hpp +// Clock Signal +// +// Created by Thomas Harte on 07/01/2018. +// Copyright 2018 Thomas Harte. All rights reserved. +// + +#ifndef PCBooter_hpp +#define PCBooter_hpp + +#include "MFMSectorDump.hpp" + +#include + +namespace Storage::Disk { + +/*! + Provides a @c DiskImage holding a raw IBM PC booter disk image: a sector dump of one of a few fixed sizes + with what looks like a meaningful boot sector. +*/ +class PCBooter: public MFMSectorDump { + public: + PCBooter(const std::string &file_name); + HeadPosition get_maximum_head_position() final; + int get_head_count() final; + + private: + long get_file_offset_for_position(Track::Address address) final; + + int head_count_; + int track_count_; +}; + +} + +#endif /* PCBooter_hpp */ diff --git a/Storage/TargetPlatforms.hpp b/Storage/TargetPlatforms.hpp index eeed8657b..9351d034b 100644 --- a/Storage/TargetPlatforms.hpp +++ b/Storage/TargetPlatforms.hpp @@ -39,11 +39,12 @@ enum Type: IntType { ZX81 = 1 << 20, ZXSpectrum = 1 << 21, PCCompatible = 1 << 22, + FAT12 = 1 << 23, Acorn = AcornAtom | AcornElectron | BBCMaster | BBCModelA | BBCModelB, ZX8081 = ZX80 | ZX81, AllCartridge = Atari2600 | AcornElectron | Coleco | MSX, - AllDisk = Acorn | AmstradCPC | Commodore | Oric | MSX | ZXSpectrum | Macintosh | AtariST | DiskII | Amiga | PCCompatible, + AllDisk = Acorn | AmstradCPC | Commodore | Oric | MSX | ZXSpectrum | Macintosh | AtariST | DiskII | Amiga | PCCompatible | FAT12, AllTape = Acorn | AmstradCPC | Commodore | Oric | ZX8081 | MSX | ZXSpectrum, };