From a6b326da4831ef6fac5e279e0cee497a3022ebfc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 25 Dec 2021 18:17:13 -0500 Subject: [PATCH] Parse the INFO record. --- Storage/Disk/DiskImage/Formats/IPF.cpp | 50 ++++++++++++++++++++++++-- Storage/Disk/DiskImage/Formats/IPF.hpp | 4 +-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/Storage/Disk/DiskImage/Formats/IPF.cpp b/Storage/Disk/DiskImage/Formats/IPF.cpp index 45220eb8e..5720b44ab 100644 --- a/Storage/Disk/DiskImage/Formats/IPF.cpp +++ b/Storage/Disk/DiskImage/Formats/IPF.cpp @@ -39,6 +39,52 @@ IPF::IPF(const std::string &file_name) : file_(file_name) { } break; + case BLOCK('I', 'N', 'F', 'O'): { + // There are a lot of useful archival fields in the info chunk, which for emulation + // aren't that interesting. + + // Make sure this is a floppy disk. + const uint32_t media_type = file_.get32be(); + if(media_type != 1) { + throw Error::InvalidFormat; + } + + // Skip: encoder type, revision, file key and revision, CRC of the original .ctr, and minimum track. + file_.seek(24, SEEK_CUR); + track_count_ = int(1 + file_.get32be()); + + // Skip: min side. + file_.seek(4, SEEK_CUR); + head_count_ = int(1 + file_.get32be()); + + // Skip: creation date, time. + file_.seek(8, SEEK_CUR); + + platform_type_ = 0; + for(int c = 0; c < 4; c++) { + const uint8_t platform = file_.get8(); + switch(platform) { + default: break; + case 1: platform_type_ |= TargetPlatform::Amiga; break; + case 2: platform_type_ |= TargetPlatform::AtariST; break; + /* Omitted: 3 -> IBM PC */ + case 4: platform_type_ |= TargetPlatform::AmstradCPC; break; + case 5: platform_type_ |= TargetPlatform::ZXSpectrum; break; + /* Omitted: 6 -> Sam Coupé */ + /* Omitted: 7 -> Archimedes */ + /* Omitted: 8 -> C64 */ + /* Omitted: 9 -> Atari 8-bit */ + } + } + + // If the file didn't declare anything, default to supporting everything. + if(!platform_type_) { + platform_type_ = ~0; + } + + // Ignore: disk number, creator ID, reserved area. + } break; + case BLOCK('D', 'A', 'T', 'A'): { length += file_.get32be(); printf("Handling DATA block at %ld of length %d\n", start_of_block, length); @@ -51,11 +97,11 @@ IPF::IPF(const std::string &file_name) : file_(file_name) { } HeadPosition IPF::get_maximum_head_position() { - return HeadPosition(80); // TODO; + return HeadPosition(track_count_); } int IPF::get_head_count() { - return 2; // TODO; + return head_count_; } std::shared_ptr IPF::get_track_at_position([[maybe_unused]] Track::Address address) { diff --git a/Storage/Disk/DiskImage/Formats/IPF.hpp b/Storage/Disk/DiskImage/Formats/IPF.hpp index b7f08a52b..ad016f29a 100644 --- a/Storage/Disk/DiskImage/Formats/IPF.hpp +++ b/Storage/Disk/DiskImage/Formats/IPF.hpp @@ -45,9 +45,9 @@ class IPF: public DiskImage, public TargetPlatform::TypeDistinguisher { int track_count_; TargetPlatform::Type target_platform_type() final { - return platform_type_; + return TargetPlatform::Type(platform_type_); } - TargetPlatform::Type platform_type_ = TargetPlatform::Amiga; + TargetPlatform::IntType platform_type_ = TargetPlatform::Amiga; }; }