1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-30 22:29:56 +00:00

Introduces enough DMK support to progress to failure to parse a track.

This commit is contained in:
Thomas Harte 2018-01-08 21:57:11 -05:00
parent 6eb56a1564
commit 4e124047c6
5 changed files with 161 additions and 5 deletions

View File

@ -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 */,

View File

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

View File

@ -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)

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

View 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 */