From d1abfc040c9df49efbc9966f282b93e84bda00ba Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 29 Aug 2016 08:48:49 -0400 Subject: [PATCH] Addressed my dithering here: the file format containers themselves should do nothing but inspect the data to find out whether it is of the correct format. The machine steps are there for machine-specific validation. So it's probably easier to treat a binary ROM image just as a binary ROM image. Therefore, the Acorn-specific .rom detection is now in an Acorn-specific area. --- .../Clock Signal.xcodeproj/project.pbxproj | 32 +++++---- .../Machine/Wrappers/CSElectron.h | 2 +- StaticAnalyser/Acorn/AcornAnalyser.cpp | 67 +++++++++++++++++++ StaticAnalyser/Acorn/AcornAnalyser.hpp | 27 ++++++++ StaticAnalyser/StaticAnalyser.cpp | 23 +++++-- Storage/Cartridge/Cartridge.cpp | 2 + Storage/Cartridge/Formats/A26.cpp | 15 ----- Storage/Cartridge/Formats/A26.hpp | 30 --------- Storage/Cartridge/Formats/AcornROM.cpp | 59 ---------------- Storage/Cartridge/Formats/BinaryDump.cpp | 35 ++++++++++ .../Formats/{AcornROM.hpp => BinaryDump.hpp} | 12 ++-- 11 files changed, 174 insertions(+), 130 deletions(-) create mode 100644 StaticAnalyser/Acorn/AcornAnalyser.cpp create mode 100644 StaticAnalyser/Acorn/AcornAnalyser.hpp delete mode 100644 Storage/Cartridge/Formats/A26.cpp delete mode 100644 Storage/Cartridge/Formats/A26.hpp delete mode 100644 Storage/Cartridge/Formats/AcornROM.cpp create mode 100644 Storage/Cartridge/Formats/BinaryDump.cpp rename Storage/Cartridge/Formats/{AcornROM.hpp => BinaryDump.hpp} (56%) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index e33b3cec4..3b4cf2a74 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -26,8 +26,7 @@ 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; - 4B37EE7F1D734596006A09A4 /* A26.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE7D1D734596006A09A4 /* A26.cpp */; }; - 4B37EE821D7345A6006A09A4 /* AcornROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* AcornROM.cpp */; }; + 4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */; }; 4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; }; 4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; }; 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */; }; @@ -341,6 +340,7 @@ 4BC9DF451D044FCA00F44158 /* ROMImages in Resources */ = {isa = PBXBuildFile; fileRef = 4BC9DF441D044FCA00F44158 /* ROMImages */; }; 4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9DF4D1D04691600F44158 /* 6560.cpp */; }; 4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */; }; + 4BD14B111D74627C0088EAD6 /* AcornAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD14B0F1D74627C0088EAD6 /* AcornAnalyser.cpp */; }; 4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */; }; 4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */; }; 4BEE0A701D72496600532C7B /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; }; @@ -408,10 +408,8 @@ 4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = ""; }; 4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = ""; }; 4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = ""; }; - 4B37EE7D1D734596006A09A4 /* A26.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = A26.cpp; sourceTree = ""; }; - 4B37EE7E1D734596006A09A4 /* A26.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = A26.hpp; sourceTree = ""; }; - 4B37EE801D7345A6006A09A4 /* AcornROM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AcornROM.cpp; sourceTree = ""; }; - 4B37EE811D7345A6006A09A4 /* AcornROM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AcornROM.hpp; sourceTree = ""; }; + 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BinaryDump.cpp; sourceTree = ""; }; + 4B37EE811D7345A6006A09A4 /* BinaryDump.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = BinaryDump.hpp; sourceTree = ""; }; 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = ""; }; 4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = ""; }; 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = ""; }; @@ -767,6 +765,8 @@ 4BC9DF4E1D04691600F44158 /* 6560.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6560.hpp; sourceTree = ""; }; 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6502InterruptTests.swift; sourceTree = ""; }; 4BCA98C21D065CA20062F44C /* 6522.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6522.hpp; sourceTree = ""; }; + 4BD14B0F1D74627C0088EAD6 /* AcornAnalyser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AcornAnalyser.cpp; path = ../../StaticAnalyser/Acorn/AcornAnalyser.cpp; sourceTree = ""; }; + 4BD14B101D74627C0088EAD6 /* AcornAnalyser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AcornAnalyser.hpp; path = ../../StaticAnalyser/Acorn/AcornAnalyser.hpp; sourceTree = ""; }; 4BD5F1931D13528900631CD1 /* CSBestEffortUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CSBestEffortUpdater.h; path = Updater/CSBestEffortUpdater.h; sourceTree = ""; }; 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSBestEffortUpdater.m; path = Updater/CSBestEffortUpdater.m; sourceTree = ""; }; 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = ""; }; @@ -1519,6 +1519,15 @@ path = 6560; sourceTree = ""; }; + 4BD14B121D7462810088EAD6 /* Acorn */ = { + isa = PBXGroup; + children = ( + 4BD14B0F1D74627C0088EAD6 /* AcornAnalyser.cpp */, + 4BD14B101D74627C0088EAD6 /* AcornAnalyser.hpp */, + ); + name = Acorn; + sourceTree = ""; + }; 4BD5F1961D1352A000631CD1 /* Updater */ = { isa = PBXGroup; children = ( @@ -1551,10 +1560,8 @@ children = ( 4BEE0A6D1D72496600532C7B /* PRG.cpp */, 4BEE0A6E1D72496600532C7B /* PRG.hpp */, - 4B37EE7D1D734596006A09A4 /* A26.cpp */, - 4B37EE7E1D734596006A09A4 /* A26.hpp */, - 4B37EE801D7345A6006A09A4 /* AcornROM.cpp */, - 4B37EE811D7345A6006A09A4 /* AcornROM.hpp */, + 4B37EE801D7345A6006A09A4 /* BinaryDump.cpp */, + 4B37EE811D7345A6006A09A4 /* BinaryDump.hpp */, ); path = Formats; sourceTree = ""; @@ -1565,6 +1572,7 @@ 4BF1354A1D6D2C300054B2EA /* StaticAnalyser.cpp */, 4BF1354B1D6D2C300054B2EA /* StaticAnalyser.hpp */, 4BC830D21D6E7C6D0000A26F /* Commodore */, + 4BD14B121D7462810088EAD6 /* Acorn */, ); name = StaticAnalyser; sourceTree = ""; @@ -1979,10 +1987,10 @@ 4BAB62AD1D3272D200DF5BA0 /* Disk.cpp in Sources */, 4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */, 4BB697CE1D4BA44400248BDF /* CommodoreGCR.cpp in Sources */, + 4BD14B111D74627C0088EAD6 /* AcornAnalyser.cpp in Sources */, 4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */, 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */, 4BB697C71D4B558F00248BDF /* Factors.cpp in Sources */, - 4B37EE7F1D734596006A09A4 /* A26.cpp in Sources */, 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */, 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, @@ -2021,7 +2029,7 @@ 4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */, 4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */, 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */, - 4B37EE821D7345A6006A09A4 /* AcornROM.cpp in Sources */, + 4B37EE821D7345A6006A09A4 /* BinaryDump.cpp in Sources */, 4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h index 61e3754d8..03444749a 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSElectron.h @@ -17,7 +17,7 @@ - (void)setROM:(nonnull NSData *)rom slot:(int)slot; - (BOOL)openUEFAtURL:(nonnull NSURL *)URL; -- (void)analyse:(NSURL *)url; +- (void)analyse:(nonnull NSURL *)url; @property (nonatomic, assign) BOOL useFastLoadingHack; @property (nonatomic, assign) BOOL useTelevisionOutput; diff --git a/StaticAnalyser/Acorn/AcornAnalyser.cpp b/StaticAnalyser/Acorn/AcornAnalyser.cpp new file mode 100644 index 000000000..d064aa8b1 --- /dev/null +++ b/StaticAnalyser/Acorn/AcornAnalyser.cpp @@ -0,0 +1,67 @@ +// +// AcornAnalyser.cpp +// Clock Signal +// +// Created by Thomas Harte on 29/08/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "AcornAnalyser.hpp" + +using namespace StaticAnalyser::Acorn; + +static std::list> + AcornCartridgesFrom(const std::list> &cartridges) +{ + std::list> acorn_cartridges; + + for(std::shared_ptr cartridge : cartridges) + { + const std::list &segments = cartridge->get_segments(); + + // only one mapped item is allowed + if(segments.size() != 1) continue; + + // which must be 16 kb in size + Storage::Cartridge::Cartridge::Segment segment = segments.front(); + if(segment.data.size() != 0x4000) continue; + + // is a copyright string present? + uint8_t copyright_offset = segment.data[7]; + if( + segment.data[copyright_offset] != 0x00 || + segment.data[copyright_offset+1] != 0x28 || + segment.data[copyright_offset+2] != 0x43 || + segment.data[copyright_offset+3] != 0x29 + ) continue; + + // is the language entry point valid? + if(!( + (segment.data[0] == 0x00 && segment.data[1] == 0x00 && segment.data[2] == 0x00) || + (segment.data[0] != 0x00 && segment.data[2] >= 0x80 && segment.data[2] < 0xc0) + )) continue; + + // is the service entry point valid? + if(!(segment.data[5] >= 0x80 && segment.data[5] < 0xc0)) continue; + + // probability of a random binary blob that isn't an Acorn ROM proceeding to here: + // 1/(2^32) * + // ( ((2^24)-1)/(2^24)*(1/4) + 1/(2^24) ) * + // 1/4 + // = something very improbable — around 1/16th of 1 in 2^32, but not exactly. + acorn_cartridges.push_back(cartridge); + } + + return acorn_cartridges; +} + +void StaticAnalyser::Acorn::AddTargets( + const std::list> &disks, + const std::list> &tapes, + const std::list> &cartridges, + std::list &destination) +{ + // strip out inappropriate cartridges + std::list> acornCartridges = AcornCartridgesFrom(cartridges); +} + diff --git a/StaticAnalyser/Acorn/AcornAnalyser.hpp b/StaticAnalyser/Acorn/AcornAnalyser.hpp new file mode 100644 index 000000000..ccfaa75f3 --- /dev/null +++ b/StaticAnalyser/Acorn/AcornAnalyser.hpp @@ -0,0 +1,27 @@ +// +// AcornAnalyser.hpp +// Clock Signal +// +// Created by Thomas Harte on 29/08/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef AcornAnalyser_hpp +#define AcornAnalyser_hpp + +#include "../StaticAnalyser.hpp" + +namespace StaticAnalyser { +namespace Acorn { + +void AddTargets( + const std::list> &disks, + const std::list> &tapes, + const std::list> &cartridges, + std::list &destination +); + +} +} + +#endif /* AcornAnalyser_hpp */ diff --git a/StaticAnalyser/StaticAnalyser.cpp b/StaticAnalyser/StaticAnalyser.cpp index 9c0f39ea6..404da6e8c 100644 --- a/StaticAnalyser/StaticAnalyser.cpp +++ b/StaticAnalyser/StaticAnalyser.cpp @@ -10,13 +10,18 @@ #include -#include "../Storage/Cartridge/Formats/A26.hpp" -#include "../Storage/Cartridge/Formats/AcornROM.hpp" +// Analysers +#include "Acorn/AcornAnalyser.hpp" + +// Cartridges +#include "../Storage/Cartridge/Formats/BinaryDump.hpp" #include "../Storage/Cartridge/Formats/PRG.hpp" +// Disks #include "../Storage/Disk/Formats/D64.hpp" #include "../Storage/Disk/Formats/G64.hpp" +// Tapes #include "../Storage/Tape/Formats/CommodoreTAP.hpp" #include "../Storage/Tape/Formats/TapePRG.hpp" #include "../Storage/Tape/Formats/TapeUEF.hpp" @@ -71,10 +76,10 @@ std::list StaticAnalyser::GetTargets(const char *file_name) TryInsert(list, class, platforms) \ } - Format("a26", cartridges, Cartridge::A26, TargetPlatform::Atari2600) // A26 - Format("bin", cartridges, Cartridge::A26, TargetPlatform::Atari2600) // BIN - Format("d64", disks, Disk::D64, TargetPlatform::Commodore) // D64 - Format("g64", disks, Disk::G64, TargetPlatform::Commodore) // G64 + Format("a26", cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // A26 + Format("bin", cartridges, Cartridge::BinaryDump, TargetPlatform::Atari2600) // BIN + Format("d64", disks, Disk::D64, TargetPlatform::Commodore) // D64 + Format("g64", disks, Disk::G64, TargetPlatform::Commodore) // G64 // PRG if(!strcmp(lowercase_extension, "prg")) @@ -92,7 +97,7 @@ std::list StaticAnalyser::GetTargets(const char *file_name) } // ROM - Format("rom", cartridges, Cartridge::AcornROM, TargetPlatform::Acorn) // ROM + Format("rom", cartridges, Cartridge::BinaryDump, TargetPlatform::Acorn) // ROM Format("tap", tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP Format("uef", tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape) @@ -101,6 +106,10 @@ std::list StaticAnalyser::GetTargets(const char *file_name) // Hand off to platform-specific determination of whether these things are actually compatible and, // if so, how to load them. (TODO) + if(potential_platforms & (TargetPlatformType)TargetPlatform::Acorn) + { + Acorn::AddTargets(disks, tapes, cartridges, targets); + } free(lowercase_extension); return targets; diff --git a/Storage/Cartridge/Cartridge.cpp b/Storage/Cartridge/Cartridge.cpp index eef001e7b..d197548e1 100644 --- a/Storage/Cartridge/Cartridge.cpp +++ b/Storage/Cartridge/Cartridge.cpp @@ -7,3 +7,5 @@ // #include "Cartridge.hpp" + +const int Storage::Cartridge::Cartridge::Segment::UnknownAddress = -1; diff --git a/Storage/Cartridge/Formats/A26.cpp b/Storage/Cartridge/Formats/A26.cpp deleted file mode 100644 index 9bed6998e..000000000 --- a/Storage/Cartridge/Formats/A26.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// A26.cpp -// Clock Signal -// -// Created by Thomas Harte on 28/08/2016. -// Copyright © 2016 Thomas Harte. All rights reserved. -// - -#include "A26.hpp" - -using namespace Storage::Cartridge; - -A26::A26(const char *file_name) -{ -} diff --git a/Storage/Cartridge/Formats/A26.hpp b/Storage/Cartridge/Formats/A26.hpp deleted file mode 100644 index 6aa024568..000000000 --- a/Storage/Cartridge/Formats/A26.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// A26.hpp -// Clock Signal -// -// Created by Thomas Harte on 28/08/2016. -// Copyright © 2016 Thomas Harte. All rights reserved. -// - -#ifndef Storage_Cartridge_A26_hpp -#define Storage_Cartridge_A26_hpp - -#include "../Cartridge.hpp" - -namespace Storage { -namespace Cartridge { - -class A26 : public Cartridge { - public: - A26(const char *file_name); - - enum { - ErrorNotAcornROM - }; -}; - -} -} - - -#endif /* A26_hpp */ diff --git a/Storage/Cartridge/Formats/AcornROM.cpp b/Storage/Cartridge/Formats/AcornROM.cpp deleted file mode 100644 index afa397353..000000000 --- a/Storage/Cartridge/Formats/AcornROM.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// AcornROM.cpp -// Clock Signal -// -// Created by Thomas Harte on 28/08/2016. -// Copyright © 2016 Thomas Harte. All rights reserved. -// - -#include "AcornROM.hpp" - -#include -#include - -using namespace Storage::Cartridge; - -AcornROM::AcornROM(const char *file_name) -{ - // the file should be exactly 16 kb - struct stat file_stats; - stat(file_name, &file_stats); - if(file_stats.st_size != 0x4000) throw ErrorNotAcornROM; - - // grab contents - FILE *file = fopen(file_name, "rb"); - if(!file) throw ErrorNotAcornROM; - size_t data_length = (size_t)file_stats.st_size; - std::vector contents(data_length); - fread(&contents[0], 1, (size_t)(data_length), file); - fclose(file); - - // perform sanity checks... - - // is a copyright string present? - uint8_t copyright_offset = contents[7]; - if( - contents[copyright_offset] != 0x00 || - contents[copyright_offset+1] != 0x28 || - contents[copyright_offset+2] != 0x43 || - contents[copyright_offset+3] != 0x29 - ) throw ErrorNotAcornROM; - - // is the language entry point valid? - if(!( - (contents[0] == 0x00 && contents[1] == 0x00 && contents[2] == 0x00) || - (contents[0] != 0x00 && contents[2] >= 0x80 && contents[2] < 0xc0) - )) throw ErrorNotAcornROM; - - // is the service entry point valid? - if(!(contents[5] >= 0x80 && contents[5] < 0xc0)) throw ErrorNotAcornROM; - - // probability of a random binary blob that isn't an Acorn ROM proceeding to here: - // 1/(2^32) * - // ( ((2^24)-1)/(2^24)*(1/4) + 1/(2^24) ) * - // 1/4 - // = something very improbable — around 1/16th of 1 in 2^32, but not exactly. - - // enshrine - _segments.emplace_back(0x8000, 0xc000, std::move(contents)); -} diff --git a/Storage/Cartridge/Formats/BinaryDump.cpp b/Storage/Cartridge/Formats/BinaryDump.cpp new file mode 100644 index 000000000..37e2a8ea7 --- /dev/null +++ b/Storage/Cartridge/Formats/BinaryDump.cpp @@ -0,0 +1,35 @@ +// +// BinaryDump.cpp +// Clock Signal +// +// Created by Thomas Harte on 28/08/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "BinaryDump.hpp" + +#include +#include + +using namespace Storage::Cartridge; + +BinaryDump::BinaryDump(const char *file_name) +{ + // the file should be exactly 16 kb + struct stat file_stats; + stat(file_name, &file_stats); + + // grab contents + FILE *file = fopen(file_name, "rb"); + if(!file) throw ErrorNotAccessible; + size_t data_length = (size_t)file_stats.st_size; + std::vector contents(data_length); + fread(&contents[0], 1, (size_t)(data_length), file); + fclose(file); + + // enshrine + _segments.emplace_back( + ::Storage::Cartridge::Cartridge::Segment::UnknownAddress, + ::Storage::Cartridge::Cartridge::Segment::UnknownAddress, + std::move(contents)); +} diff --git a/Storage/Cartridge/Formats/AcornROM.hpp b/Storage/Cartridge/Formats/BinaryDump.hpp similarity index 56% rename from Storage/Cartridge/Formats/AcornROM.hpp rename to Storage/Cartridge/Formats/BinaryDump.hpp index f5f923ce7..b9d65a390 100644 --- a/Storage/Cartridge/Formats/AcornROM.hpp +++ b/Storage/Cartridge/Formats/BinaryDump.hpp @@ -1,25 +1,25 @@ // -// AcornROM.hpp +// BinaryDump.hpp // Clock Signal // // Created by Thomas Harte on 28/08/2016. // Copyright © 2016 Thomas Harte. All rights reserved. // -#ifndef Storage_Cartridge_AcornROM_hpp -#define Storage_Cartridge_AcornROM_hpp +#ifndef Storage_Cartridge_BinaryDump_hpp +#define Storage_Cartridge_BinaryDump_hpp #include "../Cartridge.hpp" namespace Storage { namespace Cartridge { -class AcornROM : public Cartridge { +class BinaryDump : public Cartridge { public: - AcornROM(const char *file_name); + BinaryDump(const char *file_name); enum { - ErrorNotAcornROM + ErrorNotAccessible }; };