1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-24 12:30:17 +00:00

Adds provisional support for WOZ files.

This commit is contained in:
Thomas Harte 2018-04-23 19:57:45 -07:00
parent 6592745e53
commit d447e81abd
6 changed files with 158 additions and 1 deletions

View File

@ -39,6 +39,7 @@
#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"
#include "../../Storage/Disk/DiskImage/Formats/WOZ.hpp"
// Tapes // Tapes
#include "../../Storage/Tape/Formats/CAS.hpp" #include "../../Storage/Tape/Formats/CAS.hpp"
@ -129,6 +130,7 @@ static Media GetMediaAndPlatforms(const std::string &file_name, TargetPlatform::
Format("tsx", result.tapes, Tape::TZX, TargetPlatform::MSX) // TSX Format("tsx", result.tapes, Tape::TZX, TargetPlatform::MSX) // TSX
Format("tzx", result.tapes, Tape::TZX, TargetPlatform::ZX8081) // TZX Format("tzx", result.tapes, Tape::TZX, TargetPlatform::ZX8081) // TZX
Format("uef", result.tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape) Format("uef", result.tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape)
Format("woz", result.disks, Disk::DiskImageHolder<Storage::Disk::WOZ>, TargetPlatform::AppleII) // WOZ
#undef Format #undef Format
#undef Insert #undef Insert

View File

@ -222,6 +222,8 @@
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; }; 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B69FB421C4D941400B5F0AA /* TapeUEF.cpp */; };
4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; }; 4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; };
4B6A4C991F58F09E00E3F787 /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; }; 4B6A4C991F58F09E00E3F787 /* 6502Base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */; };
4B6ED2F0208E2F8A0047B343 /* WOZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */; };
4B6ED2F1208E2F8A0047B343 /* WOZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */; };
4B7136861F78724F008B8ED9 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136841F78724F008B8ED9 /* Encoder.cpp */; }; 4B7136861F78724F008B8ED9 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136841F78724F008B8ED9 /* Encoder.cpp */; };
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136871F78725F008B8ED9 /* Shifter.cpp */; }; 4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B7136871F78725F008B8ED9 /* Shifter.cpp */; };
4B71368E1F788112008B8ED9 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B71368C1F788112008B8ED9 /* Parser.cpp */; }; 4B71368E1F788112008B8ED9 /* Parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B71368C1F788112008B8ED9 /* Parser.cpp */; };
@ -889,6 +891,8 @@
4B6A4C911F58F09E00E3F787 /* 6502AllRAM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502AllRAM.cpp; sourceTree = "<group>"; }; 4B6A4C911F58F09E00E3F787 /* 6502AllRAM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502AllRAM.cpp; sourceTree = "<group>"; };
4B6A4C921F58F09E00E3F787 /* 6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6502AllRAM.hpp; sourceTree = "<group>"; }; 4B6A4C921F58F09E00E3F787 /* 6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6502AllRAM.hpp; sourceTree = "<group>"; };
4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502Base.cpp; sourceTree = "<group>"; }; 4B6A4C951F58F09E00E3F787 /* 6502Base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = 6502Base.cpp; sourceTree = "<group>"; };
4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WOZ.cpp; sourceTree = "<group>"; };
4B6ED2EF208E2F8A0047B343 /* WOZ.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = WOZ.hpp; sourceTree = "<group>"; };
4B7041271F92C26900735E45 /* JoystickMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JoystickMachine.hpp; sourceTree = "<group>"; }; 4B7041271F92C26900735E45 /* JoystickMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = JoystickMachine.hpp; sourceTree = "<group>"; };
4B70412A1F92C2A700735E45 /* Joystick.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Joystick.hpp; sourceTree = "<group>"; }; 4B70412A1F92C2A700735E45 /* Joystick.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Joystick.hpp; sourceTree = "<group>"; };
4B70EF6A1FFDCDF400A3494E /* ROMSlotHandler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = ROMSlotHandler.hpp; path = MSX/ROMSlotHandler.hpp; sourceTree = "<group>"; }; 4B70EF6A1FFDCDF400A3494E /* ROMSlotHandler.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = ROMSlotHandler.hpp; path = MSX/ROMSlotHandler.hpp; sourceTree = "<group>"; };
@ -1879,6 +1883,8 @@
4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */, 4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */,
4B45189A1F75FD1B00926311 /* SSD.hpp */, 4B45189A1F75FD1B00926311 /* SSD.hpp */,
4BFDD7891F7F2DB4008579B9 /* Utility */, 4BFDD7891F7F2DB4008579B9 /* Utility */,
4B6ED2EE208E2F8A0047B343 /* WOZ.cpp */,
4B6ED2EF208E2F8A0047B343 /* WOZ.hpp */,
); );
path = Formats; path = Formats;
sourceTree = "<group>"; sourceTree = "<group>";
@ -3536,6 +3542,7 @@
4BB0A65E204500A900FB3688 /* StaticAnalyser.cpp in Sources */, 4BB0A65E204500A900FB3688 /* StaticAnalyser.cpp in Sources */,
4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */, 4B055AC11FAE98DC0060FFFF /* MachineForTarget.cpp in Sources */,
4BBB70A9202014E2002FE009 /* MultiCRTMachine.cpp in Sources */, 4BBB70A9202014E2002FE009 /* MultiCRTMachine.cpp in Sources */,
4B6ED2F1208E2F8A0047B343 /* WOZ.cpp in Sources */,
4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */, 4B055AD81FAE9B180060FFFF /* Video.cpp in Sources */,
4B89452F201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B89452F201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4B894531201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B894531201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
@ -3808,6 +3815,7 @@
4B894526201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B894526201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */, 4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */,
4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */, 4B8805FB1DCFF807003085B1 /* Oric.cpp in Sources */,
4B6ED2F0208E2F8A0047B343 /* WOZ.cpp in Sources */,
4BFE7B871FC39BF100160B38 /* StandardOptions.cpp in Sources */, 4BFE7B871FC39BF100160B38 /* StandardOptions.cpp in Sources */,
4B15A9FC208249BB005E6C8D /* StaticAnalyser.cpp in Sources */, 4B15A9FC208249BB005E6C8D /* StaticAnalyser.cpp in Sources */,
4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */, 4B5FADC01DE3BF2B00AEC565 /* Microdisc.cpp in Sources */,

View File

@ -68,7 +68,7 @@
</AdditionalOptions> </AdditionalOptions>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES" enableASanStackUseAfterReturn = "YES"

View File

@ -397,6 +397,7 @@
<key>CFBundleTypeExtensions</key> <key>CFBundleTypeExtensions</key>
<array> <array>
<string>nib</string> <string>nib</string>
<string>woz</string>
</array> </array>
<key>CFBundleTypeIconFile</key> <key>CFBundleTypeIconFile</key>
<string>floppy525</string> <string>floppy525</string>

View File

@ -0,0 +1,100 @@
//
// WOZ.cpp
// Clock Signal
//
// Created by Thomas Harte on 23/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#include "WOZ.hpp"
#include "../../Track/PCMTrack.hpp"
using namespace Storage::Disk;
WOZ::WOZ(const std::string &file_name) :
file_(file_name) {
const char signature[8] = {
'W', 'O', 'Z', '1',
static_cast<char>(0xff), 0x0a, 0x0d, 0x0a
};
if(!file_.check_signature(signature, 8)) throw ErrorNotWOZ;
// TODO: check CRC32, instead of skipping it.
file_.seek(4, SEEK_CUR);
// Parse all chunks up front.
while(true) {
const uint32_t chunk_id = file_.get32le();
const uint32_t chunk_size = file_.get32le();
if(file_.eof()) break;
long end_of_chunk = file_.tell() + static_cast<long>(chunk_size);
#define CK(str) (str[0] | (str[1] << 8) | (str[2] << 16) | (str[3] << 24))
switch(chunk_id) {
case CK("INFO"): {
const uint8_t version = file_.get8();
if(version != 1) break;
is_3_5_disk_ = file_.get8() == 2;
is_read_only_ = file_.get8() == 1;
/* Ignored:
1 byte: Synchronized; 1 = Cross track sync was used during imaging.
1 byte: Cleaned; 1 = MC3470 fake bits have been removed.
32 bytes: Cretor; a UTF-8 string.
*/
} break;
case CK("TMAP"): {
file_.read(track_map_, 160);
} break;
case CK("TRKS"): {
tracks_offset_ = file_.tell();
} break;
// TODO: parse META chunks.
default:
break;
}
#undef CK
file_.seek(end_of_chunk, SEEK_SET);
}
}
int WOZ::get_head_position_count() {
// TODO: deal with the elephant in the room of non-integral track coordinates.
return is_3_5_disk_ ? 80 : 160;
}
int WOZ::get_head_count() {
return is_3_5_disk_ ? 2 : 1;
}
std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
// Out-of-bounds => no track.
if(address.head >= get_head_count()) return nullptr;
if(address.position >= get_head_position_count()) return nullptr;
// Calculate table position; if this track is defined to be unformatted, return no track.
const int table_position = address.head * get_head_position_count() + address.position;
if(track_map_[table_position] == 0xff) return nullptr;
// Seek to the real track.
file_.seek(tracks_offset_ + track_map_[table_position] * 6656, SEEK_SET);
PCMSegment track_contents;
track_contents.data = file_.read(6646);
track_contents.data.resize(file_.get16le());
track_contents.number_of_bits = file_.get16le();
const uint16_t splice_point = file_.get16le();
if(splice_point != 0xffff) {
// TODO: expand track from splice_point?
}
return std::shared_ptr<PCMTrack>(new PCMTrack(track_contents));
}

View File

@ -0,0 +1,46 @@
//
// WOZ.hpp
// Clock Signal
//
// Created by Thomas Harte on 23/04/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef WOZ_hpp
#define WOZ_hpp
#include "../DiskImage.hpp"
#include "../../../FileHolder.hpp"
#include <string>
namespace Storage {
namespace Disk {
/*!
Provides a @c DiskImage containing a WOZ a bit stream representation of a floppy.
*/
class WOZ: public DiskImage {
public:
WOZ(const std::string &file_name);
enum {
ErrorNotWOZ
};
int get_head_position_count() override;
int get_head_count() override;
std::shared_ptr<Track> get_track_at_position(Track::Address address) override;
private:
Storage::FileHolder file_;
bool is_read_only_ = false;
bool is_3_5_disk_ = false;
uint8_t track_map_[160];
long tracks_offset_ = 0;
};
}
}
#endif /* WOZ_hpp */