mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-11 14:37:37 +00:00
Introduces flush_tracks to Drive, while switching its interface to using Track::Address and adjusting associated integer types.
This commit is contained in:
parent
f623bff5c3
commit
97a2be71e3
@ -239,7 +239,7 @@ uint8_t i8272::get_register(int address) {
|
||||
active_head_ = (command_[1] >> 2)&1; \
|
||||
status_[0] = (command_[1]&7); \
|
||||
select_drive(active_drive_); \
|
||||
get_drive().set_head((unsigned int)active_head_); \
|
||||
get_drive().set_head(active_head_); \
|
||||
set_is_double_density(command_[0] & 0x40);
|
||||
|
||||
#define WAIT_FOR_BYTES(n) \
|
||||
|
@ -53,7 +53,7 @@ void Microdisc::set_control_register(uint8_t control, uint8_t changes) {
|
||||
|
||||
// b4: side select
|
||||
if(changes & 0x10) {
|
||||
unsigned int head = (control & 0x10) ? 1 : 0;
|
||||
int head = (control & 0x10) ? 1 : 0;
|
||||
for(int c = 0; c < 4; c++) {
|
||||
if(drives_[c]) drives_[c]->set_head(head);
|
||||
}
|
||||
|
@ -69,7 +69,6 @@
|
||||
4B4518851F75E91A00926311 /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187A1F75E91900926311 /* DiskController.cpp */; };
|
||||
4B4518861F75E91A00926311 /* MFMDiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187C1F75E91900926311 /* MFMDiskController.cpp */; };
|
||||
4B4518871F75E91A00926311 /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45187F1F75E91900926311 /* DigitalPhaseLockedLoop.cpp */; };
|
||||
4B45189E1F75FD1C00926311 /* DiskImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45188A1F75FD1B00926311 /* DiskImage.cpp */; };
|
||||
4B45189F1F75FD1C00926311 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45188D1F75FD1B00926311 /* AcornADF.cpp */; };
|
||||
4B4518A01F75FD1C00926311 /* CPCDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45188F1F75FD1B00926311 /* CPCDSK.cpp */; };
|
||||
4B4518A11F75FD1C00926311 /* D64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518911F75FD1B00926311 /* D64.cpp */; };
|
||||
@ -77,7 +76,6 @@
|
||||
4B4518A31F75FD1C00926311 /* HFE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518951F75FD1B00926311 /* HFE.cpp */; };
|
||||
4B4518A41F75FD1C00926311 /* OricMFMDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518971F75FD1B00926311 /* OricMFMDSK.cpp */; };
|
||||
4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518991F75FD1B00926311 /* SSD.cpp */; };
|
||||
4B4518A61F75FD1C00926311 /* SingleTrackDisk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B45189C1F75FD1C00926311 /* SingleTrackDisk.cpp */; };
|
||||
4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */; };
|
||||
4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; };
|
||||
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; };
|
||||
@ -603,7 +601,6 @@
|
||||
4B45187F1F75E91900926311 /* DigitalPhaseLockedLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DigitalPhaseLockedLoop.cpp; sourceTree = "<group>"; };
|
||||
4B4518801F75E91900926311 /* DigitalPhaseLockedLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DigitalPhaseLockedLoop.hpp; sourceTree = "<group>"; };
|
||||
4B4518881F75ECB100926311 /* Track.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Track.hpp; sourceTree = "<group>"; };
|
||||
4B45188A1F75FD1B00926311 /* DiskImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiskImage.cpp; sourceTree = "<group>"; };
|
||||
4B45188B1F75FD1B00926311 /* DiskImage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiskImage.hpp; sourceTree = "<group>"; };
|
||||
4B45188D1F75FD1B00926311 /* AcornADF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AcornADF.cpp; sourceTree = "<group>"; };
|
||||
4B45188E1F75FD1B00926311 /* AcornADF.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AcornADF.hpp; sourceTree = "<group>"; };
|
||||
@ -619,8 +616,6 @@
|
||||
4B4518981F75FD1B00926311 /* OricMFMDSK.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OricMFMDSK.hpp; sourceTree = "<group>"; };
|
||||
4B4518991F75FD1B00926311 /* SSD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SSD.cpp; sourceTree = "<group>"; };
|
||||
4B45189A1F75FD1B00926311 /* SSD.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SSD.hpp; sourceTree = "<group>"; };
|
||||
4B45189C1F75FD1C00926311 /* SingleTrackDisk.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SingleTrackDisk.cpp; sourceTree = "<group>"; };
|
||||
4B45189D1F75FD1C00926311 /* SingleTrackDisk.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SingleTrackDisk.hpp; sourceTree = "<group>"; };
|
||||
4B4518A71F76004200926311 /* TapeParser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = TapeParser.hpp; path = Parsers/TapeParser.hpp; sourceTree = "<group>"; };
|
||||
4B4518A81F76022000926311 /* DiskImageImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskImageImplementation.hpp; sourceTree = "<group>"; };
|
||||
4B4A762E1DB1A3FA007AAE2E /* AY38910.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AY38910.cpp; path = AY38910/AY38910.cpp; sourceTree = "<group>"; };
|
||||
@ -1472,7 +1467,6 @@
|
||||
4B4518891F75FD1B00926311 /* DiskImage */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B45188A1F75FD1B00926311 /* DiskImage.cpp */,
|
||||
4B45188B1F75FD1B00926311 /* DiskImage.hpp */,
|
||||
4B4518A81F76022000926311 /* DiskImageImplementation.hpp */,
|
||||
4B45188C1F75FD1B00926311 /* Formats */,
|
||||
@ -1504,15 +1498,6 @@
|
||||
path = Formats;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B45189B1F75FD1C00926311 /* SingleTrackDisk */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4B45189C1F75FD1C00926311 /* SingleTrackDisk.cpp */,
|
||||
4B45189D1F75FD1C00926311 /* SingleTrackDisk.hpp */,
|
||||
);
|
||||
path = SingleTrackDisk;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
4B4A762D1DB1A35C007AAE2E /* AY38910 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1779,7 +1764,6 @@
|
||||
4B45187E1F75E91900926311 /* DPLL */,
|
||||
4BB697CF1D4BA44900248BDF /* Encodings */,
|
||||
4B3FE75F1F3CF6BA00448EE4 /* Parsers */,
|
||||
4B45189B1F75FD1C00926311 /* SingleTrackDisk */,
|
||||
4B4518701F75E91800926311 /* Track */,
|
||||
);
|
||||
path = Disk;
|
||||
@ -2923,7 +2907,6 @@
|
||||
4B8378DC1F336631005CA9E4 /* CharacterMapper.cpp in Sources */,
|
||||
4B8378E51F3378C4005CA9E4 /* CharacterMapper.cpp in Sources */,
|
||||
4B322E041F5A2E3C004EB04C /* Z80Base.cpp in Sources */,
|
||||
4B45189E1F75FD1C00926311 /* DiskImage.cpp in Sources */,
|
||||
4B4518A31F75FD1C00926311 /* HFE.cpp in Sources */,
|
||||
4B8378E21F336920005CA9E4 /* CharacterMapper.cpp in Sources */,
|
||||
4B4518A11F75FD1C00926311 /* D64.cpp in Sources */,
|
||||
@ -2996,7 +2979,6 @@
|
||||
4B8FE2291DA1EDDF0090D3CE /* ElectronOptionsPanel.swift in Sources */,
|
||||
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
|
||||
4BB697CB1D4B6D3E00248BDF /* TimedEventLoop.cpp in Sources */,
|
||||
4B4518A61F75FD1C00926311 /* SingleTrackDisk.cpp in Sources */,
|
||||
4BBC951E1F368D83008F4C34 /* i8272.cpp in Sources */,
|
||||
4BF1354C1D6D2C300054B2EA /* StaticAnalyser.cpp in Sources */,
|
||||
4B4A76301DB1A3FA007AAE2E /* AY38910.cpp in Sources */,
|
||||
|
@ -31,25 +31,28 @@ class Disk {
|
||||
This is not necessarily a track count. There is no implicit guarantee that every position will
|
||||
return a distinct track, or — e.g. if the media is holeless — will return any track at all.
|
||||
*/
|
||||
virtual unsigned int get_head_position_count() = 0;
|
||||
virtual int get_head_position_count() = 0;
|
||||
|
||||
/*!
|
||||
@returns the number of heads (and, therefore, impliedly surfaces) available on this disk.
|
||||
*/
|
||||
virtual unsigned int get_head_count() = 0;
|
||||
virtual int get_head_count() = 0;
|
||||
|
||||
/*!
|
||||
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
|
||||
returns @c nullptr otherwise.
|
||||
*/
|
||||
virtual std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position) = 0;
|
||||
virtual std::shared_ptr<Track> get_track_at_position(Track::Address address) = 0;
|
||||
|
||||
/*!
|
||||
Replaces the Track at position @c position underneath @c head with @c track. Ignored if this disk is read-only.
|
||||
Subclasses that are not read-only should use the protected methods @c get_is_modified and, optionally,
|
||||
@c get_modified_track_at_position to query for changes when closing.
|
||||
*/
|
||||
virtual void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) = 0;
|
||||
virtual void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) = 0;
|
||||
|
||||
/*!
|
||||
Provides a hint that no further tracks are likely to be written for a while.
|
||||
*/
|
||||
virtual void flush_tracks() = 0;
|
||||
|
||||
/*!
|
||||
@returns whether the disk image is read only. Defaults to @c true if not overridden.
|
||||
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// DiskImage.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 21/09/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "DiskImage.hpp"
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
int DiskImageHolderBase::get_id_for_track_at_position(unsigned int head, unsigned int position) {
|
||||
return (int)(position * get_head_count() + head);
|
||||
}
|
@ -35,25 +35,28 @@ class DiskImage {
|
||||
This is not necessarily a track count. There is no implicit guarantee that every position will
|
||||
return a distinct track, or — e.g. if the media is holeless — will return any track at all.
|
||||
*/
|
||||
virtual unsigned int get_head_position_count() = 0;
|
||||
virtual int get_head_position_count() = 0;
|
||||
|
||||
/*!
|
||||
@returns the number of heads (and, therefore, impliedly surfaces) available on this disk.
|
||||
*/
|
||||
virtual unsigned int get_head_count() { return 1; }
|
||||
virtual int get_head_count() { return 1; }
|
||||
|
||||
/*!
|
||||
@returns the @c Track at @c position underneath @c head if there are any detectable events there;
|
||||
returns @c nullptr otherwise.
|
||||
*/
|
||||
virtual std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position) = 0;
|
||||
virtual std::shared_ptr<Track> get_track_at_position(Track::Address address) = 0;
|
||||
|
||||
/*!
|
||||
Replaces the Track at position @c position underneath @c head with @c track. Ignored if this disk is read-only.
|
||||
Subclasses that are not read-only should use the protected methods @c get_is_modified and, optionally,
|
||||
@c get_modified_track_at_position to query for changes when closing.
|
||||
*/
|
||||
virtual void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {}
|
||||
virtual void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {}
|
||||
|
||||
/*!
|
||||
Communicates that it is likely to be a while before any more tracks are written.
|
||||
*/
|
||||
virtual void flush_tracks() {}
|
||||
|
||||
/*!
|
||||
@returns whether the disk image is read only. Defaults to @c true if not overridden.
|
||||
@ -63,8 +66,7 @@ class DiskImage {
|
||||
|
||||
class DiskImageHolderBase: public Disk {
|
||||
protected:
|
||||
int get_id_for_track_at_position(unsigned int head, unsigned int position);
|
||||
std::map<int, std::shared_ptr<Track>> cached_tracks_;
|
||||
std::map<Track::Address, std::shared_ptr<Track>> cached_tracks_;
|
||||
std::unique_ptr<Concurrency::AsyncTaskQueue> update_queue_;
|
||||
};
|
||||
|
||||
@ -79,10 +81,11 @@ template <typename T> class DiskImageHolder: public DiskImageHolderBase {
|
||||
disk_image_(args...) {}
|
||||
~DiskImageHolder();
|
||||
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track);
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track);
|
||||
void flush_tracks();
|
||||
bool get_is_read_only();
|
||||
|
||||
private:
|
||||
|
@ -6,11 +6,11 @@
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
template <typename T> unsigned int DiskImageHolder<T>::get_head_position_count() {
|
||||
template <typename T> int DiskImageHolder<T>::get_head_position_count() {
|
||||
return disk_image_.get_head_position_count();
|
||||
}
|
||||
|
||||
template <typename T> unsigned int DiskImageHolder<T>::get_head_count() {
|
||||
template <typename T> int DiskImageHolder<T>::get_head_count() {
|
||||
return disk_image_.get_head_count();
|
||||
}
|
||||
|
||||
@ -18,28 +18,29 @@ template <typename T> bool DiskImageHolder<T>::get_is_read_only() {
|
||||
return disk_image_.get_is_read_only();
|
||||
}
|
||||
|
||||
template <typename T> void DiskImageHolder<T>::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
|
||||
template <typename T> void DiskImageHolder<T>::flush_tracks() {
|
||||
}
|
||||
|
||||
template <typename T> void DiskImageHolder<T>::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
||||
if(disk_image_.get_is_read_only()) return;
|
||||
|
||||
int address = get_id_for_track_at_position(head, position);
|
||||
cached_tracks_[address] = track;
|
||||
|
||||
if(!update_queue_) update_queue_.reset(new Concurrency::AsyncTaskQueue);
|
||||
std::shared_ptr<Track> track_copy(track->clone());
|
||||
update_queue_->enqueue([this, head, position, track_copy] {
|
||||
disk_image_.set_track_at_position(head, position, track_copy);
|
||||
update_queue_->enqueue([this, address, track_copy] {
|
||||
disk_image_.set_track_at_position(address, track_copy);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
if(head >= get_head_count()) return nullptr;
|
||||
if(position >= get_head_position_count()) return nullptr;
|
||||
template <typename T> std::shared_ptr<Track> DiskImageHolder<T>::get_track_at_position(Track::Address address) {
|
||||
if(address.head >= get_head_count()) return nullptr;
|
||||
if(address.position >= get_head_position_count()) return nullptr;
|
||||
|
||||
int address = get_id_for_track_at_position(head, position);
|
||||
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
|
||||
auto cached_track = cached_tracks_.find(address);
|
||||
if(cached_track != cached_tracks_.end()) return cached_track->second;
|
||||
|
||||
std::shared_ptr<Track> track = disk_image_.get_track_at_position(head, position);
|
||||
std::shared_ptr<Track> track = disk_image_.get_track_at_position(address);
|
||||
if(!track) return nullptr;
|
||||
cached_tracks_[address] = track;
|
||||
return track;
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "Utility/ImplicitSectors.hpp"
|
||||
|
||||
namespace {
|
||||
static const unsigned int sectors_per_track = 16;
|
||||
static const unsigned int sector_size = 1;
|
||||
static const int sectors_per_track = 16;
|
||||
static const int sector_size = 1;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
@ -36,14 +36,14 @@ AcornADF::AcornADF(const char *file_name) : MFMSectorDump(file_name) {
|
||||
set_geometry(sectors_per_track, sector_size, true);
|
||||
}
|
||||
|
||||
unsigned int AcornADF::get_head_position_count() {
|
||||
int AcornADF::get_head_position_count() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
unsigned int AcornADF::get_head_count() {
|
||||
int AcornADF::get_head_count() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
long AcornADF::get_file_offset_for_position(unsigned int head, unsigned int position) {
|
||||
return (position * 1 + head) * (128 << sector_size) * sectors_per_track;
|
||||
long AcornADF::get_file_offset_for_position(Track::Address address) {
|
||||
return (address.position * 1 + address.head) * (128 << sector_size) * sectors_per_track;
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ class AcornADF: public MFMSectorDump {
|
||||
ErrorNotAcornADF,
|
||||
};
|
||||
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
|
||||
private:
|
||||
long get_file_offset_for_position(unsigned int head, unsigned int position);
|
||||
long get_file_offset_for_position(Track::Address address);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
|
||||
// Don't really care about about the creator; skip.
|
||||
fseek(file_, 0x30, SEEK_SET);
|
||||
head_position_count_ = (unsigned int)fgetc(file_);
|
||||
head_count_ = (unsigned int)fgetc(file_);
|
||||
head_position_count_ = fgetc(file_);
|
||||
head_count_ = fgetc(file_);
|
||||
|
||||
if(is_extended_) {
|
||||
// Skip two unused bytes and grab the track size table.
|
||||
fseek(file_, 2, SEEK_CUR);
|
||||
for(unsigned int c = 0; c < head_position_count_ * head_count_; c++) {
|
||||
for(int c = 0; c < head_position_count_ * head_count_; c++) {
|
||||
track_sizes_.push_back((size_t)(fgetc(file_) << 8));
|
||||
}
|
||||
} else {
|
||||
@ -37,17 +37,17 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CPCDSK::get_head_position_count() {
|
||||
int CPCDSK::get_head_position_count() {
|
||||
return head_position_count_;
|
||||
}
|
||||
|
||||
unsigned int CPCDSK::get_head_count() {
|
||||
int CPCDSK::get_head_count() {
|
||||
return head_count_;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> CPCDSK::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> CPCDSK::get_track_at_position(Track::Address address) {
|
||||
// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
|
||||
unsigned int chronological_track = (position * head_count_) + head;
|
||||
size_t chronological_track = static_cast<size_t>((address.position * head_count_) + address.head);
|
||||
|
||||
// All DSK images reserve 0x100 bytes for their headers.
|
||||
long file_offset = 0x100;
|
||||
@ -60,14 +60,14 @@ std::shared_ptr<Track> CPCDSK::get_track_at_position(unsigned int head, unsigned
|
||||
}
|
||||
|
||||
// Sum the lengths of all tracks prior to the interesting one to get a file offset.
|
||||
unsigned int t = 0;
|
||||
size_t t = 0;
|
||||
while(t < chronological_track && t < track_sizes_.size()) {
|
||||
file_offset += track_sizes_[t];
|
||||
t++;
|
||||
}
|
||||
} else {
|
||||
// Tracks are a fixed size in the original DSK file format.
|
||||
file_offset += size_of_a_track_ * chronological_track;
|
||||
file_offset += size_of_a_track_ * static_cast<long>(chronological_track);
|
||||
}
|
||||
|
||||
// Find the track, and skip the unused part of track information.
|
||||
|
@ -35,15 +35,14 @@ class CPCDSK: public DiskImage, public Storage::FileHolder {
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
using DiskImage::get_is_read_only;
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
|
||||
private:
|
||||
|
||||
unsigned int head_count_;
|
||||
unsigned int head_position_count_;
|
||||
int head_count_;
|
||||
int head_position_count_;
|
||||
bool is_extended_;
|
||||
|
||||
// Used only for non-extended disks.
|
||||
|
@ -35,18 +35,18 @@ D64::D64(const char *file_name) :
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int D64::get_head_position_count() {
|
||||
int D64::get_head_position_count() {
|
||||
return number_of_tracks_*2;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> D64::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> D64::get_track_at_position(Track::Address address) {
|
||||
// every other track is missing, as is any head above 0
|
||||
if(position&1 || head)
|
||||
if(address.position&1 || address.head)
|
||||
return std::shared_ptr<Track>();
|
||||
|
||||
// figure out where this track starts on the disk
|
||||
int offset_to_track = 0;
|
||||
int tracks_to_traverse = position >> 1;
|
||||
int tracks_to_traverse = address.position >> 1;
|
||||
|
||||
int zone_sizes[] = {17, 7, 6, 10};
|
||||
int sectors_by_zone[] = {21, 19, 18, 17};
|
||||
@ -96,7 +96,7 @@ std::shared_ptr<Track> D64::get_track_at_position(unsigned int head, unsigned in
|
||||
sector_data[0] = sector_data[1] = sector_data[2] = 0xff;
|
||||
|
||||
uint8_t sector_number = (uint8_t)(sector); // sectors count from 0
|
||||
uint8_t track_number = (uint8_t)((position >> 1) + 1); // tracks count from 1
|
||||
uint8_t track_number = (uint8_t)((address.position >> 1) + 1); // tracks count from 1
|
||||
uint8_t checksum = (uint8_t)(sector_number ^ track_number ^ disk_id_ ^ (disk_id_ >> 8));
|
||||
uint8_t header_start[4] = {
|
||||
0x08, checksum, sector_number, track_number
|
||||
|
@ -33,12 +33,12 @@ class D64: public DiskImage, public Storage::FileHolder {
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
unsigned int get_head_position_count();
|
||||
int get_head_position_count();
|
||||
using DiskImage::get_is_read_only;
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
|
||||
private:
|
||||
unsigned int number_of_tracks_;
|
||||
int number_of_tracks_;
|
||||
uint16_t disk_id_;
|
||||
};
|
||||
|
||||
|
@ -28,22 +28,22 @@ G64::G64(const char *file_name) :
|
||||
maximum_track_size_ = fgetc16le();
|
||||
}
|
||||
|
||||
unsigned int G64::get_head_position_count() {
|
||||
int G64::get_head_position_count() {
|
||||
// give at least 84 tracks, to yield the normal geometry but,
|
||||
// if there are more, shove them in
|
||||
return number_of_tracks_ > 84 ? number_of_tracks_ : 84;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> G64::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> G64::get_track_at_position(Track::Address address) {
|
||||
std::shared_ptr<Track> resulting_track;
|
||||
|
||||
// if there's definitely no track here, return the empty track
|
||||
// (TODO: should be supplying one with an index hole?)
|
||||
if(position >= number_of_tracks_) return resulting_track;
|
||||
if(head >= 1) return resulting_track;
|
||||
if(address.position >= number_of_tracks_) return resulting_track;
|
||||
if(address.head >= 1) return resulting_track;
|
||||
|
||||
// seek to this track's entry in the track table
|
||||
fseek(file_, (long)((position * 4) + 0xc), SEEK_SET);
|
||||
fseek(file_, (long)((address.position * 4) + 0xc), SEEK_SET);
|
||||
|
||||
// read the track offset
|
||||
uint32_t track_offset;
|
||||
@ -64,7 +64,7 @@ std::shared_ptr<Track> G64::get_track_at_position(unsigned int head, unsigned in
|
||||
fread(&track_contents[0], 1, track_length, file_);
|
||||
|
||||
// seek to this track's entry in the speed zone table
|
||||
fseek(file_, (long)((position * 4) + 0x15c), SEEK_SET);
|
||||
fseek(file_, (long)((address.position * 4) + 0x15c), SEEK_SET);
|
||||
|
||||
// read the speed zone offsrt
|
||||
uint32_t speed_zone_offset;
|
||||
|
@ -36,8 +36,8 @@ class G64: public DiskImage, public Storage::FileHolder {
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
unsigned int get_head_position_count();
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
int get_head_position_count();
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
using DiskImage::get_is_read_only;
|
||||
|
||||
private:
|
||||
|
@ -19,8 +19,8 @@ HFE::HFE(const char *file_name) :
|
||||
if(!check_signature("HXCPICFE", 8)) throw ErrorNotHFE;
|
||||
|
||||
if(fgetc(file_)) throw ErrorNotHFE;
|
||||
track_count_ = (unsigned int)fgetc(file_);
|
||||
head_count_ = (unsigned int)fgetc(file_);
|
||||
track_count_ = fgetc(file_);
|
||||
head_count_ = fgetc(file_);
|
||||
|
||||
fseek(file_, 7, SEEK_CUR);
|
||||
track_list_offset_ = (long)fgetc16le() << 9;
|
||||
@ -29,11 +29,11 @@ HFE::HFE(const char *file_name) :
|
||||
HFE::~HFE() {
|
||||
}
|
||||
|
||||
unsigned int HFE::get_head_position_count() {
|
||||
int HFE::get_head_position_count() {
|
||||
return track_count_;
|
||||
}
|
||||
|
||||
unsigned int HFE::get_head_count() {
|
||||
int HFE::get_head_count() {
|
||||
return head_count_;
|
||||
}
|
||||
|
||||
@ -44,25 +44,25 @@ unsigned int HFE::get_head_count() {
|
||||
To read the track, start from the current file position, read 256 bytes,
|
||||
skip 256 bytes, read 256 bytes, skip 256 bytes, etc.
|
||||
*/
|
||||
uint16_t HFE::seek_track(unsigned int head, unsigned int position) {
|
||||
uint16_t HFE::seek_track(Track::Address address) {
|
||||
// Get track position and length from the lookup table; data is then always interleaved
|
||||
// based on an assumption of two heads.
|
||||
fseek(file_, track_list_offset_ + position * 4, SEEK_SET);
|
||||
fseek(file_, track_list_offset_ + address.position * 4, SEEK_SET);
|
||||
|
||||
long track_offset = (long)fgetc16le() << 9;
|
||||
uint16_t track_length = fgetc16le();
|
||||
|
||||
fseek(file_, track_offset, SEEK_SET);
|
||||
if(head) fseek(file_, 256, SEEK_CUR);
|
||||
if(address.head) fseek(file_, 256, SEEK_CUR);
|
||||
|
||||
return track_length / 2;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> HFE::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> HFE::get_track_at_position(Track::Address address) {
|
||||
PCMSegment segment;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
uint16_t track_length = seek_track(head, position);
|
||||
uint16_t track_length = seek_track(address);
|
||||
|
||||
segment.data.resize(track_length);
|
||||
segment.number_of_bits = track_length * 8;
|
||||
@ -84,9 +84,9 @@ std::shared_ptr<Track> HFE::get_track_at_position(unsigned int head, unsigned in
|
||||
return track;
|
||||
}
|
||||
|
||||
void HFE::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
|
||||
void HFE::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
||||
std::unique_lock<std::mutex> lock_guard(file_access_mutex_);
|
||||
uint16_t track_length = seek_track(head, position);
|
||||
uint16_t track_length = seek_track(address);
|
||||
lock_guard.unlock();
|
||||
|
||||
PCMSegment segment = Storage::Disk::track_serialisation(*track, Storage::Time(1, track_length * 8));
|
||||
@ -94,7 +94,7 @@ void HFE::set_track_at_position(unsigned int head, unsigned int position, const
|
||||
uint16_t data_length = std::min(static_cast<uint16_t>(segment.data.size()), track_length);
|
||||
|
||||
lock_guard.lock();
|
||||
seek_track(head, position);
|
||||
seek_track(address);
|
||||
|
||||
uint16_t c = 0;
|
||||
while(c < data_length) {
|
||||
|
@ -34,17 +34,17 @@ class HFE: public DiskImage, public Storage::FileHolder {
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
using Storage::FileHolder::get_is_read_only;
|
||||
void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
|
||||
private:
|
||||
uint16_t seek_track(unsigned int head, unsigned int position);
|
||||
uint16_t seek_track(Track::Address address);
|
||||
|
||||
unsigned int head_count_;
|
||||
unsigned int track_count_;
|
||||
int head_count_;
|
||||
int track_count_;
|
||||
long track_list_offset_;
|
||||
};
|
||||
|
||||
|
@ -20,11 +20,11 @@ void MFMSectorDump::set_geometry(int sectors_per_track, uint8_t sector_size, boo
|
||||
is_double_density_ = is_double_density;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> MFMSectorDump::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> MFMSectorDump::get_track_at_position(Track::Address address) {
|
||||
uint8_t sectors[(128 << sector_size_)*sectors_per_track_];
|
||||
|
||||
if(head > 1) return nullptr;
|
||||
long file_offset = get_file_offset_for_position(head, position);
|
||||
if(address.head > 1) return nullptr;
|
||||
long file_offset = get_file_offset_for_position(address);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
@ -32,15 +32,15 @@ std::shared_ptr<Track> MFMSectorDump::get_track_at_position(unsigned int head, u
|
||||
fread(sectors, 1, sizeof(sectors), file_);
|
||||
}
|
||||
|
||||
return track_for_sectors(sectors, static_cast<uint8_t>(position), static_cast<uint8_t>(head), 0, sector_size_, is_double_density_);
|
||||
return track_for_sectors(sectors, static_cast<uint8_t>(address.position), static_cast<uint8_t>(address.head), 0, sector_size_, is_double_density_);
|
||||
}
|
||||
|
||||
void MFMSectorDump::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
|
||||
void MFMSectorDump::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
||||
uint8_t parsed_track[(128 << sector_size_)*sectors_per_track_];
|
||||
// Assumption here: sector IDs will run from 0.
|
||||
decode_sectors(*track, parsed_track, 0, static_cast<uint8_t>(sectors_per_track_-1), sector_size_, is_double_density_);
|
||||
|
||||
long file_offset = get_file_offset_for_position(head, position);
|
||||
long file_offset = get_file_offset_for_position(address);
|
||||
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
ensure_file_is_at_least_length(file_offset);
|
||||
|
@ -24,12 +24,12 @@ class MFMSectorDump: public DiskImage, public Storage::FileHolder {
|
||||
void set_geometry(int sectors_per_track, uint8_t sector_size, bool is_double_density);
|
||||
|
||||
using Storage::FileHolder::get_is_read_only;
|
||||
void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
|
||||
private:
|
||||
std::mutex file_access_mutex_;
|
||||
virtual long get_file_offset_for_position(unsigned int head, unsigned int position) = 0;
|
||||
virtual long get_file_offset_for_position(Track::Address address) = 0;
|
||||
|
||||
int sectors_per_track_ = 0;
|
||||
uint8_t sector_size_ = 0;
|
||||
|
@ -29,32 +29,32 @@ OricMFMDSK::OricMFMDSK(const char *file_name) :
|
||||
throw ErrorNotOricMFMDSK;
|
||||
}
|
||||
|
||||
unsigned int OricMFMDSK::get_head_position_count() {
|
||||
return track_count_;
|
||||
int OricMFMDSK::get_head_position_count() {
|
||||
return static_cast<int>(track_count_);
|
||||
}
|
||||
|
||||
unsigned int OricMFMDSK::get_head_count() {
|
||||
return head_count_;
|
||||
int OricMFMDSK::get_head_count() {
|
||||
return static_cast<int>(head_count_);
|
||||
}
|
||||
|
||||
long OricMFMDSK::get_file_offset_for_position(unsigned int head, unsigned int position) {
|
||||
long seek_offset = 0;
|
||||
long OricMFMDSK::get_file_offset_for_position(Track::Address address) {
|
||||
int seek_offset = 0;
|
||||
switch(geometry_type_) {
|
||||
case 1:
|
||||
seek_offset = (head * track_count_) + position;
|
||||
seek_offset = address.head * static_cast<int>(track_count_) + address.position;
|
||||
break;
|
||||
case 2:
|
||||
seek_offset = (position * track_count_ * head_count_) + head;
|
||||
seek_offset = address.position * static_cast<int>(track_count_ * head_count_) + address.head;
|
||||
break;
|
||||
}
|
||||
return (seek_offset * 6400) + 256;
|
||||
return static_cast<long>(seek_offset) * 6400 + 256;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> OricMFMDSK::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
std::shared_ptr<Track> OricMFMDSK::get_track_at_position(Track::Address address) {
|
||||
PCMSegment segment;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
fseek(file_, get_file_offset_for_position(head, position), SEEK_SET);
|
||||
fseek(file_, get_file_offset_for_position(address), SEEK_SET);
|
||||
|
||||
// The file format omits clock bits. So it's not a genuine MFM capture.
|
||||
// A consumer must contextually guess when an FB, FC, etc is meant to be a control mark.
|
||||
@ -114,7 +114,7 @@ std::shared_ptr<Track> OricMFMDSK::get_track_at_position(unsigned int head, unsi
|
||||
return track;
|
||||
}
|
||||
|
||||
void OricMFMDSK::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track) {
|
||||
void OricMFMDSK::set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track) {
|
||||
PCMSegment segment = Storage::Disk::track_serialisation(*track, Storage::Encodings::MFM::MFMBitLength);
|
||||
Storage::Encodings::MFM::Shifter shifter;
|
||||
shifter.set_is_double_density(true);
|
||||
@ -153,7 +153,7 @@ void OricMFMDSK::set_track_at_position(unsigned int head, unsigned int position,
|
||||
}
|
||||
}
|
||||
|
||||
long file_offset = get_file_offset_for_position(head, position);
|
||||
long file_offset = get_file_offset_for_position(address);
|
||||
|
||||
std::lock_guard<std::mutex> lock_guard(file_access_mutex_);
|
||||
fseek(file_, file_offset, SEEK_SET);
|
||||
|
@ -32,15 +32,15 @@ class OricMFMDSK: public DiskImage, public Storage::FileHolder {
|
||||
};
|
||||
|
||||
// implemented to satisfy @c Disk
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
using Storage::FileHolder::get_is_read_only;
|
||||
void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
void set_track_at_position(Track::Address address, const std::shared_ptr<Track> &track);
|
||||
std::shared_ptr<Track> get_track_at_position(Track::Address address);
|
||||
|
||||
private:
|
||||
std::mutex file_access_mutex_;
|
||||
long get_file_offset_for_position(unsigned int head, unsigned int position);
|
||||
long get_file_offset_for_position(Track::Address address);
|
||||
|
||||
uint32_t head_count_;
|
||||
uint32_t track_count_;
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "Utility/ImplicitSectors.hpp"
|
||||
|
||||
namespace {
|
||||
static const unsigned int sectors_per_track = 10;
|
||||
static const unsigned int sector_size = 1;
|
||||
static const int sectors_per_track = 10;
|
||||
static const int sector_size = 1;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
@ -27,21 +27,21 @@ SSD::SSD(const char *file_name) : MFMSectorDump(file_name) {
|
||||
|
||||
// this has two heads if the suffix is .dsd, one if it's .ssd
|
||||
head_count_ = (tolower(file_name[strlen(file_name) - 3]) == 'd') ? 2 : 1;
|
||||
track_count_ = (unsigned int)(file_stats_.st_size / (256 * 10));
|
||||
track_count_ = static_cast<int>(file_stats_.st_size / (256 * 10));
|
||||
if(track_count_ < 40) track_count_ = 40;
|
||||
else if(track_count_ < 80) track_count_ = 80;
|
||||
|
||||
set_geometry(sectors_per_track, sector_size, false);
|
||||
}
|
||||
|
||||
unsigned int SSD::get_head_position_count() {
|
||||
int SSD::get_head_position_count() {
|
||||
return track_count_;
|
||||
}
|
||||
|
||||
unsigned int SSD::get_head_count() {
|
||||
int SSD::get_head_count() {
|
||||
return head_count_;
|
||||
}
|
||||
|
||||
long SSD::get_file_offset_for_position(unsigned int head, unsigned int position) {
|
||||
return (position * head_count_ + head) * 256 * 10;
|
||||
long SSD::get_file_offset_for_position(Track::Address address) {
|
||||
return (address.position * head_count_ + address.head) * 256 * 10;
|
||||
}
|
||||
|
@ -31,14 +31,14 @@ class SSD: public MFMSectorDump {
|
||||
ErrorNotSSD,
|
||||
};
|
||||
|
||||
unsigned int get_head_position_count();
|
||||
unsigned int get_head_count();
|
||||
int get_head_position_count();
|
||||
int get_head_count();
|
||||
|
||||
private:
|
||||
long get_file_offset_for_position(unsigned int head, unsigned int position);
|
||||
long get_file_offset_for_position(Track::Address address);
|
||||
|
||||
unsigned int head_count_;
|
||||
unsigned int track_count_;
|
||||
int head_count_;
|
||||
int track_count_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Drive::Drive(unsigned int input_clock_rate, int revolutions_per_minute, unsigned int number_of_heads):
|
||||
Drive::Drive(unsigned int input_clock_rate, int revolutions_per_minute, int number_of_heads):
|
||||
Storage::TimedEventLoop(input_clock_rate),
|
||||
rotational_multiplier_(60, revolutions_per_minute),
|
||||
available_heads_(number_of_heads) {
|
||||
@ -51,7 +51,7 @@ void Drive::step(int direction) {
|
||||
}
|
||||
}
|
||||
|
||||
void Drive::set_head(unsigned int head) {
|
||||
void Drive::set_head(int head) {
|
||||
head = std::min(head, available_heads_ - 1);
|
||||
if(head != head_) {
|
||||
head_ = head;
|
||||
@ -83,6 +83,7 @@ void Drive::set_motor_on(bool motor_is_on) {
|
||||
motor_is_on_ = motor_is_on;
|
||||
if(!motor_is_on) {
|
||||
ready_index_count_ = 0;
|
||||
if(disk_) disk_->flush_tracks();
|
||||
}
|
||||
update_sleep_observer();
|
||||
}
|
||||
@ -178,12 +179,12 @@ void Drive::process_next_event() {
|
||||
#pragma mark - Track management
|
||||
|
||||
std::shared_ptr<Track> Drive::get_track() {
|
||||
if(disk_) return disk_->get_track_at_position(head_, (unsigned int)head_position_);
|
||||
if(disk_) return disk_->get_track_at_position(Track::Address(head_, head_position_));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Drive::set_track(const std::shared_ptr<Track> &track) {
|
||||
if(disk_) disk_->set_track_at_position(head_, (unsigned int)head_position_, track);
|
||||
if(disk_) disk_->set_track_at_position(Track::Address(head_, head_position_), track);
|
||||
}
|
||||
|
||||
void Drive::setup_track() {
|
||||
|
@ -23,7 +23,7 @@ namespace Disk {
|
||||
|
||||
class Drive: public Sleeper, public TimedEventLoop {
|
||||
public:
|
||||
Drive(unsigned int input_clock_rate, int revolutions_per_minute, unsigned int number_of_heads);
|
||||
Drive(unsigned int input_clock_rate, int revolutions_per_minute, int number_of_heads);
|
||||
|
||||
/*!
|
||||
Replaces whatever is in the drive with @c disk.
|
||||
@ -49,7 +49,7 @@ class Drive: public Sleeper, public TimedEventLoop {
|
||||
/*!
|
||||
Sets the current read head.
|
||||
*/
|
||||
void set_head(unsigned int head);
|
||||
void set_head(int head);
|
||||
|
||||
/*!
|
||||
@returns @c true if the inserted disk is read-only or no disk is inserted; @c false otherwise.
|
||||
@ -139,8 +139,8 @@ class Drive: public Sleeper, public TimedEventLoop {
|
||||
|
||||
// A record of head position and active head.
|
||||
int head_position_ = 0;
|
||||
unsigned int head_ = 0;
|
||||
unsigned int available_heads_ = 0;
|
||||
int head_ = 0;
|
||||
int available_heads_ = 0;
|
||||
|
||||
// Motor control state.
|
||||
bool motor_is_on_ = false;
|
||||
|
@ -22,7 +22,7 @@ void Parser::install_sectors_from_track(const Storage::Disk::Track::Address &add
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Storage::Disk::Track> track = disk_->get_track_at_position((unsigned int)address.head, (unsigned int)address.position);
|
||||
std::shared_ptr<Storage::Disk::Track> track = disk_->get_track_at_position(address);
|
||||
if(!track) {
|
||||
return;
|
||||
}
|
||||
@ -39,9 +39,7 @@ void Parser::install_sectors_from_track(const Storage::Disk::Track::Address &add
|
||||
}
|
||||
|
||||
Sector *Parser::get_sector(int head, int track, uint8_t sector) {
|
||||
Disk::Track::Address address;
|
||||
address.position = track;
|
||||
address.head = head;
|
||||
Disk::Track::Address address(head, track);
|
||||
install_sectors_from_track(address);
|
||||
|
||||
auto sectors = sectors_by_address_by_track_.find(address);
|
||||
|
@ -1,22 +0,0 @@
|
||||
//
|
||||
// SingleTrackDisk.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/09/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "SingleTrackDisk.hpp"
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
SingleTrackDiskImage::SingleTrackDiskImage(const std::shared_ptr<Track> &track) :
|
||||
track_(track) {}
|
||||
|
||||
unsigned int SingleTrackDiskImage::get_head_position_count() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> SingleTrackDiskImage::get_track_at_position(unsigned int head, unsigned int position) {
|
||||
return track_;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//
|
||||
// SingleTrackDisk.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 10/09/2017.
|
||||
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef SingleTrackDisk_hpp
|
||||
#define SingleTrackDisk_hpp
|
||||
|
||||
#include "DiskImage.hpp"
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
|
||||
/*!
|
||||
Provides a disk that has houses a single track.
|
||||
*/
|
||||
class SingleTrackDiskImage: public DiskImage {
|
||||
public:
|
||||
/// Constructs a single-track disk with the track @c track.
|
||||
SingleTrackDiskImage(const std::shared_ptr<Track> &track);
|
||||
unsigned int get_head_position_count();
|
||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
||||
|
||||
private:
|
||||
std::shared_ptr<Track> track_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SingleTrackDisk_hpp */
|
@ -10,6 +10,7 @@
|
||||
#define Track_h
|
||||
|
||||
#include "../../Storage.hpp"
|
||||
#include <tuple>
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
@ -29,14 +30,9 @@ class Track {
|
||||
int head, position;
|
||||
|
||||
bool operator < (const Address &rhs) const {
|
||||
return (head < rhs.head) || (position < rhs.position);
|
||||
return std::tie(head, position) < std::tie(rhs.head, rhs.position);
|
||||
}
|
||||
// Address(const Address &rhs) noexcept : head(rhs.head), position(rhs.position) {}
|
||||
// const Address &operator =(const Address &rhs) {
|
||||
// head = rhs.head;
|
||||
// position = rhs.position;
|
||||
// return *this;
|
||||
// }
|
||||
Address(int head, int position) : head(head), position(position) {}
|
||||
};
|
||||
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user