mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-10 16:30:07 +00:00
Introduces enough DMK support to progress to failure to parse a track.
This commit is contained in:
parent
6eb56a1564
commit
4e124047c6
@ -281,6 +281,8 @@
|
||||
4BA61EB01D91515900B3C876 /* NSData+StdVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA61EAF1D91515900B3C876 /* NSData+StdVector.mm */; };
|
||||
4BA799951D8B656E0045123D /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BA799931D8B656E0045123D /* StaticAnalyser.cpp */; };
|
||||
4BAD13441FF709C700FD114A /* MSX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0E61051FF34737002A9DBD /* MSX.cpp */; };
|
||||
4BAF2B4E2004580C00480230 /* DMK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAF2B4C2004580C00480230 /* DMK.cpp */; };
|
||||
4BAF2B4F2004580C00480230 /* DMK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BAF2B4C2004580C00480230 /* DMK.cpp */; };
|
||||
4BB17D4E1ED7909F00ABD1E1 /* tests.expected.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BB17D4C1ED7909F00ABD1E1 /* tests.expected.json */; };
|
||||
4BB17D4F1ED7909F00ABD1E1 /* tests.in.json in Resources */ = {isa = PBXBuildFile; fileRef = 4BB17D4D1ED7909F00ABD1E1 /* tests.in.json */; };
|
||||
4BB298F11B587D8400A49093 /* start in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E51B587D8300A49093 /* start */; };
|
||||
@ -938,6 +940,8 @@
|
||||
4BA9C3CF1D8164A9002DDB61 /* ConfigurationTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ConfigurationTarget.hpp; sourceTree = "<group>"; };
|
||||
4BAB62AC1D3272D200DF5BA0 /* Disk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Disk.hpp; sourceTree = "<group>"; };
|
||||
4BAB62AE1D32730D00DF5BA0 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = "<group>"; };
|
||||
4BAF2B4C2004580C00480230 /* DMK.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DMK.cpp; sourceTree = "<group>"; };
|
||||
4BAF2B4D2004580C00480230 /* DMK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMK.hpp; sourceTree = "<group>"; };
|
||||
4BB06B211F316A3F00600C7A /* ForceInline.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ForceInline.hpp; sourceTree = "<group>"; };
|
||||
4BB146C61F49D7D700253439 /* Sleeper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sleeper.hpp; sourceTree = "<group>"; };
|
||||
4BB17D4C1ED7909F00ABD1E1 /* tests.expected.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = tests.expected.json; path = FUSE/tests.expected.json; sourceTree = "<group>"; };
|
||||
@ -1786,6 +1790,7 @@
|
||||
4B45188D1F75FD1B00926311 /* AcornADF.cpp */,
|
||||
4B45188F1F75FD1B00926311 /* CPCDSK.cpp */,
|
||||
4B4518911F75FD1B00926311 /* D64.cpp */,
|
||||
4BAF2B4C2004580C00480230 /* DMK.cpp */,
|
||||
4B4518931F75FD1B00926311 /* G64.cpp */,
|
||||
4B4518951F75FD1B00926311 /* HFE.cpp */,
|
||||
4B58601C1F806AB200AEE2E3 /* MFMSectorDump.cpp */,
|
||||
@ -1795,6 +1800,7 @@
|
||||
4B45188E1F75FD1B00926311 /* AcornADF.hpp */,
|
||||
4B4518901F75FD1B00926311 /* CPCDSK.hpp */,
|
||||
4B4518921F75FD1B00926311 /* D64.hpp */,
|
||||
4BAF2B4D2004580C00480230 /* DMK.hpp */,
|
||||
4B4518941F75FD1B00926311 /* G64.hpp */,
|
||||
4B4518961F75FD1B00926311 /* HFE.hpp */,
|
||||
4B58601D1F806AB200AEE2E3 /* MFMSectorDump.hpp */,
|
||||
@ -3406,6 +3412,7 @@
|
||||
4B055ADF1FAE9B4C0060FFFF /* IRQDelegatePortHandler.cpp in Sources */,
|
||||
4B055AB51FAE860F0060FFFF /* TapePRG.cpp in Sources */,
|
||||
4B055AE01FAE9B660060FFFF /* CRT.cpp in Sources */,
|
||||
4BAF2B4F2004580C00480230 /* DMK.cpp in Sources */,
|
||||
4B0E04F21FC9EAA800F43484 /* StaticAnalyser.cpp in Sources */,
|
||||
4B055AD01FAE9B030060FFFF /* Tape.cpp in Sources */,
|
||||
4B055A961FAE85BB0060FFFF /* Commodore.cpp in Sources */,
|
||||
@ -3439,6 +3446,7 @@
|
||||
4B2BFC5F1D613E0200BA3AA9 /* TapePRG.cpp in Sources */,
|
||||
4BC9DF4F1D04691600F44158 /* 6560.cpp in Sources */,
|
||||
4B59199C1DAC6C46005BB85C /* OricTAP.cpp in Sources */,
|
||||
4BAF2B4E2004580C00480230 /* DMK.cpp in Sources */,
|
||||
4BB697CE1D4BA44400248BDF /* CommodoreGCR.cpp in Sources */,
|
||||
4B7136861F78724F008B8ED9 /* Encoder.cpp in Sources */,
|
||||
4B0E04EA1FC9E5DA00F43484 /* CAS.cpp in Sources */,
|
||||
|
@ -265,11 +265,6 @@
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.akop.cocoamsx.filetype.cassette</string>
|
||||
<string>com.clocksignal.cas</string>
|
||||
</array>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cas</string>
|
||||
@ -281,11 +276,30 @@
|
||||
<string>MSX Tape Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.akop.cocoamsx.filetype.cassette</string>
|
||||
<string>com.clocksignal.cas</string>
|
||||
</array>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
<key>NSDocumentClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).MachineDocument</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>dmk</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>floppy35</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Disk Image</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSTypeIsPackage</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../Storage/Disk/DiskImage/Formats/CPCDSK.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/D64.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/G64.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/DMK.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/HFE.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/MSXDSK.hpp"
|
||||
#include "../Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp"
|
||||
@ -90,6 +91,7 @@ static Media GetMediaAndPlatforms(const char *file_name, TargetPlatform::IntType
|
||||
Format("cdt", result.tapes, Tape::TZX, TargetPlatform::AmstradCPC) // CDT
|
||||
Format("csw", result.tapes, Tape::CSW, TargetPlatform::AllTape) // CSW
|
||||
Format("d64", result.disks, Disk::DiskImageHolder<Storage::Disk::D64>, TargetPlatform::Commodore) // D64
|
||||
Format("dmk", result.disks, Disk::DiskImageHolder<Storage::Disk::DMK>, TargetPlatform::MSX) // DMK
|
||||
Format("dsd", result.disks, Disk::DiskImageHolder<Storage::Disk::SSD>, TargetPlatform::Acorn) // DSD
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::CPCDSK>, TargetPlatform::AmstradCPC) // DSK (Amstrad CPC)
|
||||
Format("dsk", result.disks, Disk::DiskImageHolder<Storage::Disk::MSXDSK>, TargetPlatform::MSX) // DSK (MSX)
|
||||
|
75
Storage/Disk/DiskImage/Formats/DMK.cpp
Normal file
75
Storage/Disk/DiskImage/Formats/DMK.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// DMK.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 08/01/2018.
|
||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "DMK.hpp"
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
DMK::DMK(const char *file_name) :
|
||||
file_(file_name) {
|
||||
// Determine whether this DMK represents a read-only disk (whether intentionally,
|
||||
// or by virtue of placement).
|
||||
uint8_t read_only_byte = file_.get8();
|
||||
if(read_only_byte != 0x00 && read_only_byte != 0xff) throw ErrorNotDMK;
|
||||
is_read_only_ = (read_only_byte == 0xff) || file_.get_is_known_read_only();
|
||||
|
||||
// Read track count and size.
|
||||
head_position_count_ = static_cast<int>(file_.get8());
|
||||
track_length_ = static_cast<long>(file_.get16le());
|
||||
|
||||
// Track length must be at least 0x80, as that's the size of the IDAM
|
||||
// table before track contents.
|
||||
if(track_length_ < 0x80) throw ErrorNotDMK;
|
||||
|
||||
// Read the file flags and apply them.
|
||||
uint8_t flags = file_.get8();
|
||||
head_count_ = 2 - ((flags & 0x10) >> 4);
|
||||
head_position_count_ /= head_count_;
|
||||
is_purely_single_density_ = !!(flags & 0x40);
|
||||
|
||||
// Skip to the end of the header and check that this is
|
||||
// "in the emulator's native format".
|
||||
file_.seek(0xc, SEEK_SET);
|
||||
uint32_t format = file_.get32le();
|
||||
if(format) throw ErrorNotDMK;
|
||||
}
|
||||
|
||||
int DMK::get_head_position_count() {
|
||||
return head_position_count_;
|
||||
}
|
||||
|
||||
int DMK::get_head_count() {
|
||||
return head_count_;
|
||||
}
|
||||
|
||||
bool DMK::get_is_read_only() {
|
||||
return is_read_only_;
|
||||
}
|
||||
|
||||
long DMK::get_file_offset_for_position(Track::Address address) {
|
||||
return (address.head*head_count_ + address.position) * track_length_ + 16;
|
||||
}
|
||||
|
||||
std::shared_ptr<::Storage::Disk::Track> DMK::get_track_at_position(::Storage::Disk::Track::Address address) {
|
||||
file_.seek(get_file_offset_for_position(address), SEEK_SET);
|
||||
|
||||
uint16_t idam_locations[64];
|
||||
std::size_t index = 0;
|
||||
for(std::size_t c = 0; c < sizeof(idam_locations); ++c) {
|
||||
idam_locations[index] = file_.get16le();
|
||||
if((idam_locations[index] & 0x7fff) >= 128) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// `index` is now the final (sensical) entry in the IDAM location table.
|
||||
// TODO: parse track contents.
|
||||
printf("number of IDAMs: %d", index);
|
||||
|
||||
return nullptr;
|
||||
}
|
57
Storage/Disk/DiskImage/Formats/DMK.hpp
Normal file
57
Storage/Disk/DiskImage/Formats/DMK.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// DMK.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 08/01/2018.
|
||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef DMK_hpp
|
||||
#define DMK_hpp
|
||||
|
||||
#include "../DiskImage.hpp"
|
||||
#include "../../../FileHolder.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
|
||||
/*!
|
||||
Provides a @c Disk containing a DMK disk image — mostly a decoded byte stream, but with
|
||||
a record of IDAM locations.
|
||||
*/
|
||||
class DMK: public DiskImage {
|
||||
public:
|
||||
/*!
|
||||
Construct a @c DMK containing content from the file with name @c file_name.
|
||||
|
||||
@throws ErrorNotDMK if this file doesn't appear to be a DMK.
|
||||
*/
|
||||
DMK(const char *file_name);
|
||||
|
||||
enum {
|
||||
ErrorNotDMK
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
int get_head_position_count() override;
|
||||
int get_head_count() override;
|
||||
bool get_is_read_only() override;
|
||||
|
||||
std::shared_ptr<::Storage::Disk::Track> get_track_at_position(::Storage::Disk::Track::Address address) override;
|
||||
|
||||
private:
|
||||
FileHolder file_;
|
||||
long get_file_offset_for_position(Track::Address address);
|
||||
|
||||
bool is_read_only_;
|
||||
int head_position_count_;
|
||||
int head_count_;
|
||||
|
||||
long track_length_;
|
||||
bool is_purely_single_density_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DMK_hpp */
|
Loading…
x
Reference in New Issue
Block a user