From 9a819d6ca0a3a8a54a2fb1f1c7f1903ba0d64c8c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 23 Nov 2020 22:02:32 -0500 Subject: [PATCH] Transcribes interesting 2MG fields, albeit without acting on them. --- Storage/Disk/DiskImage/Formats/2MG.cpp | 60 +++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Storage/Disk/DiskImage/Formats/2MG.cpp b/Storage/Disk/DiskImage/Formats/2MG.cpp index b54130721..7b85c9e95 100644 --- a/Storage/Disk/DiskImage/Formats/2MG.cpp +++ b/Storage/Disk/DiskImage/Formats/2MG.cpp @@ -11,7 +11,65 @@ using namespace Storage::Disk; DiskImageHolderBase *Disk2MG::open(const std::string &file_name) { - (void)file_name; + FileHolder file(file_name); + + // Check the signature. + if(!file.check_signature("2IMG")) throw Error::InvalidFormat; + + // Skip the creator. + file.seek(4, SEEK_CUR); + + // Grab the header size, version number and image format. + const uint16_t header_size = file.get16le(); + const uint16_t version = file.get16le(); + const uint32_t format = file.get32le(); + const uint32_t flags = file.get32le(); + + // Skip the number of ProDOS blocks; this is surely implicit from the data size? + file.seek(4, SEEK_CUR); + + // Get the offset and size of the disk image data. + const uint32_t data_start = file.get32le(); + const uint32_t data_size = file.get32le(); + + // Skipped: + // + // four bytes, offset to comment + // four bytes, length of comment + // four bytes, offset to creator-specific data + // four bytes, length of creator-specific data + // + // (all of which relate to optional appendages). + + // Validate. + if(header_size < 0x40 || header_size >= file.stats().st_size) { + throw Error::InvalidFormat; + } + if(version > 1) { + throw Error::InvalidFormat; + } + + // TODO: based on format, instantiate a suitable disk image. + switch(format) { + default: throw Error::InvalidFormat; + case 0: + // TODO: DOS 3.3 sector order. + break; + case 1: + // TODO: ProDOS sector order. + break; + case 2: + // TODO: NIB data (yuck!). + break; + } + + // So: maybe extend FileHolder to handle hiding the header before instantiating + // a proper holder? Probably more valid than having each actual disk class do + // its own range logic? + (void)flags; + (void)data_start; + (void)data_size; + throw Error::InvalidFormat; return nullptr; }