1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-01 11:49:58 +00:00

Use the FAT12 boot sector to determine geometry.

This commit is contained in:
Thomas Harte 2021-06-22 06:54:17 -04:00
parent e062780968
commit 83a54fd6d2
5 changed files with 76 additions and 76 deletions

View File

@ -43,9 +43,9 @@
#include "../../Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp" #include "../../Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp"
#include "../../Storage/Disk/DiskImage/Formats/G64.hpp" #include "../../Storage/Disk/DiskImage/Formats/G64.hpp"
#include "../../Storage/Disk/DiskImage/Formats/DMK.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/HFE.hpp"
#include "../../Storage/Disk/DiskImage/Formats/MSA.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/NIB.hpp"
#include "../../Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp" #include "../../Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp"
#include "../../Storage/Disk/DiskImage/Formats/SSD.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<Storage::Disk::MacintoshIMG>, TargetPlatform::Macintosh) // DSK (Macintosh, floppy disk) Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::MacintoshIMG>, 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::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.mass_storage_devices, MassStorage::DSK, TargetPlatform::Macintosh) // DSK (Macintosh, hard disk, full device image)
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::MSXDSK>, TargetPlatform::MSX) // DSK (MSX) Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::FAT12>, TargetPlatform::MSX) // DSK (MSX)
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::OricMFMDSK>, TargetPlatform::Oric) // DSK (Oric) Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::OricMFMDSK>, TargetPlatform::Oric) // DSK (Oric)
Format("g64", result.disks, Disk::DiskImageHolder<Storage::Disk::G64>, TargetPlatform::Commodore) // G64 Format("g64", result.disks, Disk::DiskImageHolder<Storage::Disk::G64>, TargetPlatform::Commodore) // G64
Format( "hfe", 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) // HFE (TODO: switch to AllDisk once the MSX stops being so greedy)
Format("img", result.disks, Disk::DiskImageHolder<Storage::Disk::MacintoshIMG>, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2) Format("img", result.disks, Disk::DiskImageHolder<Storage::Disk::MacintoshIMG>, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2)
Format("image", result.disks, Disk::DiskImageHolder<Storage::Disk::MacintoshIMG>, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2) Format("image", result.disks, Disk::DiskImageHolder<Storage::Disk::MacintoshIMG>, TargetPlatform::Macintosh) // IMG (DiskCopy 4.2)
Format("img", result.disks, Disk::DiskImageHolder<Storage::Disk::MSXDSK>, TargetPlatform::Enterprise) // IMG (Enterprise/MS-DOS style) Format("img", result.disks, Disk::DiskImageHolder<Storage::Disk::FAT12>, TargetPlatform::Enterprise) // IMG (Enterprise/MS-DOS style)
Format("msa", result.disks, Disk::DiskImageHolder<Storage::Disk::MSA>, TargetPlatform::AtariST) // MSA Format("msa", result.disks, Disk::DiskImageHolder<Storage::Disk::MSA>, TargetPlatform::AtariST) // MSA
Format("nib", result.disks, Disk::DiskImageHolder<Storage::Disk::NIB>, TargetPlatform::DiskII) // NIB Format("nib", result.disks, Disk::DiskImageHolder<Storage::Disk::NIB>, TargetPlatform::DiskII) // NIB
Format("o", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O Format("o", result.tapes, Tape::ZX80O81P, TargetPlatform::ZX8081) // O

View File

@ -323,7 +323,7 @@
4B778F0023A5EB990000D260 /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518931F75FD1B00926311 /* G64.cpp */; }; 4B778F0023A5EB990000D260 /* G64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518931F75FD1B00926311 /* G64.cpp */; };
4B778F0123A5EBA00000D260 /* MacintoshIMG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */; }; 4B778F0123A5EBA00000D260 /* MacintoshIMG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */; };
4B778F0223A5EBA40000D260 /* MFMSectorDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.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 */; }; 4B778F0423A5EBB00000D260 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; };
4B778F0523A5EBB00000D260 /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; }; 4B778F0523A5EBB00000D260 /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; };
4B778F0623A5EC150000D260 /* CAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0E04E81FC9E5DA00F43484 /* CAS.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 */; }; 4BE9A6B11EDE293000CBCB47 /* zexdoc.com in Resources */ = {isa = PBXBuildFile; fileRef = 4BE9A6B01EDE293000CBCB47 /* zexdoc.com */; };
4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; }; 4BEA525E1DF33323007E74F2 /* Tape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA525D1DF33323007E74F2 /* Tape.cpp */; };
4BEA52631DF339D7007E74F2 /* SoundGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */; }; 4BEA52631DF339D7007E74F2 /* SoundGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */; };
4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; }; 4BEBFB4D2002C4BF000708CC /* FAT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */; };
4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; }; 4BEBFB4E2002C4BF000708CC /* FAT12.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */; };
4BEBFB512002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; }; 4BEBFB512002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; };
4BEBFB522002DB30000708CC /* 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 */; }; 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 = "<group>"; }; 4BEA52601DF3343A007E74F2 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Interrupts.hpp; sourceTree = "<group>"; };
4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundGenerator.cpp; sourceTree = "<group>"; }; 4BEA52611DF339D7007E74F2 /* SoundGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SoundGenerator.cpp; sourceTree = "<group>"; };
4BEA52621DF339D7007E74F2 /* SoundGenerator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SoundGenerator.hpp; sourceTree = "<group>"; }; 4BEA52621DF339D7007E74F2 /* SoundGenerator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SoundGenerator.hpp; sourceTree = "<group>"; };
4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MSXDSK.cpp; sourceTree = "<group>"; }; 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FAT12.cpp; sourceTree = "<group>"; };
4BEBFB4C2002C4BF000708CC /* MSXDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MSXDSK.hpp; sourceTree = "<group>"; }; 4BEBFB4C2002C4BF000708CC /* FAT12.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = FAT12.hpp; sourceTree = "<group>"; };
4BEBFB4F2002DB30000708CC /* DiskROM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiskROM.cpp; sourceTree = "<group>"; }; 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiskROM.cpp; sourceTree = "<group>"; };
4BEBFB502002DB30000708CC /* DiskROM.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskROM.hpp; sourceTree = "<group>"; }; 4BEBFB502002DB30000708CC /* DiskROM.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskROM.hpp; sourceTree = "<group>"; };
4BEDA3B425B25563000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; }; 4BEDA3B425B25563000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; };
@ -2713,7 +2713,7 @@
4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */, 4BB4BFAE22A42F290069048D /* MacintoshIMG.cpp */,
4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */, 4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */,
4BC131782346DF2B00E4FF3D /* MSA.cpp */, 4BC131782346DF2B00E4FF3D /* MSA.cpp */,
4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */, 4BEBFB4B2002C4BF000708CC /* FAT12.cpp */,
4B0F94FC208C1A1600FE41D9 /* NIB.cpp */, 4B0F94FC208C1A1600FE41D9 /* NIB.cpp */,
4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */, 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */,
4B4518991F75FD1B00926311 /* SSD.cpp */, 4B4518991F75FD1B00926311 /* SSD.cpp */,
@ -2730,7 +2730,7 @@
4BB4BFAF22A42F290069048D /* MacintoshIMG.hpp */, 4BB4BFAF22A42F290069048D /* MacintoshIMG.hpp */,
4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */, 4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */,
4BC131792346DF2B00E4FF3D /* MSA.hpp */, 4BC131792346DF2B00E4FF3D /* MSA.hpp */,
4BEBFB4C2002C4BF000708CC /* MSXDSK.hpp */, 4BEBFB4C2002C4BF000708CC /* FAT12.hpp */,
4B0F94FD208C1A1600FE41D9 /* NIB.hpp */, 4B0F94FD208C1A1600FE41D9 /* NIB.hpp */,
4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */, 4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */,
4B45189A1F75FD1B00926311 /* SSD.hpp */, 4B45189A1F75FD1B00926311 /* SSD.hpp */,
@ -5283,7 +5283,7 @@
4BB4BFBA22A4372F0069048D /* StaticAnalyser.cpp in Sources */, 4BB4BFBA22A4372F0069048D /* StaticAnalyser.cpp in Sources */,
4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */, 4B055AA21FAE85DA0060FFFF /* SSD.cpp in Sources */,
4B2E86E325DC95150024F1E9 /* Joystick.cpp in Sources */, 4B2E86E325DC95150024F1E9 /* Joystick.cpp in Sources */,
4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */, 4BEBFB4E2002C4BF000708CC /* FAT12.cpp in Sources */,
4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */, 4B055ADD1FAE9B460060FFFF /* i8272.cpp in Sources */,
4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */, 4B055A9C1FAE85DA0060FFFF /* CPCDSK.cpp in Sources */,
4B2BF19223DCC6A800C3AD60 /* STX.cpp in Sources */, 4B2BF19223DCC6A800C3AD60 /* STX.cpp in Sources */,
@ -5597,7 +5597,7 @@
4B894536201967B4007DE474 /* Z80.cpp in Sources */, 4B894536201967B4007DE474 /* Z80.cpp in Sources */,
4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */, 4BCA6CC81D9DD9F000C2D7B2 /* CommodoreROM.cpp in Sources */,
4BC1317A2346DF2B00E4FF3D /* MSA.cpp in Sources */, 4BC1317A2346DF2B00E4FF3D /* MSA.cpp in Sources */,
4BEBFB4D2002C4BF000708CC /* MSXDSK.cpp in Sources */, 4BEBFB4D2002C4BF000708CC /* FAT12.cpp in Sources */,
4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */, 4BBFBB6C1EE8401E00C01E7A /* ZX8081.cpp in Sources */,
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */, 4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */, 4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */,
@ -5745,7 +5745,7 @@
4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */,
4B778F6023A5F3460000D260 /* Disk.cpp in Sources */, 4B778F6023A5F3460000D260 /* Disk.cpp in Sources */,
4B778F5C23A5F3070000D260 /* MSX.cpp in Sources */, 4B778F5C23A5F3070000D260 /* MSX.cpp in Sources */,
4B778F0323A5EBB00000D260 /* MSXDSK.cpp in Sources */, 4B778F0323A5EBB00000D260 /* FAT12.cpp in Sources */,
4B778F4023A5F1910000D260 /* z8530.cpp in Sources */, 4B778F4023A5F1910000D260 /* z8530.cpp in Sources */,
4B778EFD23A5EB8E0000D260 /* AppleDSK.cpp in Sources */, 4B778EFD23A5EB8E0000D260 /* AppleDSK.cpp in Sources */,
4B778EFB23A5EB7E0000D260 /* HFE.cpp in Sources */, 4B778EFB23A5EB7E0000D260 /* HFE.cpp in Sources */,

View File

@ -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_;
}

View File

@ -1,5 +1,5 @@
// //
// MSXDSK.hpp // FAT12.hpp
// Clock Signal // Clock Signal
// //
// Created by Thomas Harte on 07/01/2018. // Created by Thomas Harte on 07/01/2018.
@ -17,12 +17,12 @@ namespace Storage {
namespace Disk { 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. a sector dump of appropriate proportions.
*/ */
class MSXDSK: public MFMSectorDump { class FAT12: public MFMSectorDump {
public: public:
MSXDSK(const std::string &file_name); FAT12(const std::string &file_name);
HeadPosition get_maximum_head_position() final; HeadPosition get_maximum_head_position() final;
int get_head_count() final; int get_head_count() final;
@ -31,6 +31,8 @@ class MSXDSK: public MFMSectorDump {
int head_count_; int head_count_;
int track_count_; int track_count_;
int sector_count_;
int sector_size_;
}; };
} }

View File

@ -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;
}