1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-26 10:29:31 +00:00

Extended Storage::Disk::Disk to permit write-back of modified tracks, exposed some interface via Storage::Disk::Drive.

This commit is contained in:
Thomas Harte 2016-12-24 22:11:31 -05:00
parent 7f303cfceb
commit 6e94d0c19f
4 changed files with 68 additions and 1 deletions

View File

@ -10,9 +10,23 @@
using namespace Storage::Disk;
int Disk::get_id_for_track_at_position(unsigned int head, unsigned int position)
{
return (int)(position * get_head_count() + head);
}
void Disk::set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track)
{
if(!get_is_read_only()) return;
int address = get_id_for_track_at_position(head, position);
cached_tracks_[address] = track;
modified_tracks_.insert(address);
}
std::shared_ptr<Track> Disk::get_track_at_position(unsigned int head, unsigned int position)
{
int address = (int)(position * get_head_count() + head);
int address = get_id_for_track_at_position(head, position);
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
if(cached_track != cached_tracks_.end()) return cached_track->second;
@ -20,3 +34,17 @@ std::shared_ptr<Track> Disk::get_track_at_position(unsigned int head, unsigned i
cached_tracks_[address] = track;
return track;
}
std::shared_ptr<Track> Disk::get_modified_track_at_position(unsigned int head, unsigned int position)
{
int address = get_id_for_track_at_position(head, position);
if(modified_tracks_.find(address) == modified_tracks_.end()) return nullptr;
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
if(cached_track == cached_tracks_.end()) return nullptr;
return cached_track->second;
}
bool Disk::get_is_modified()
{
return !modified_tracks_.empty();
}

View File

@ -11,6 +11,7 @@
#include <memory>
#include <map>
#include <set>
#include "../Storage.hpp"
namespace Storage {
@ -85,6 +86,18 @@ class Disk {
*/
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
/*!
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.
*/
void set_track_at_position(unsigned int head, unsigned int position, const std::shared_ptr<Track> &track);
/*!
@returns whether the disk image is read only. Defaults to @c true if not overridden.
*/
virtual bool get_is_read_only() { return true; }
protected:
/*!
Subclasses should implement this to return the @c Track at @c position underneath @c head. Returned tracks
@ -93,8 +106,20 @@ class Disk {
*/
virtual std::shared_ptr<Track> get_uncached_track_at_position(unsigned int head, unsigned int position) = 0;
/*!
@returns @c true if any calls to set_track_at_position occurred; @c false otherwise.
*/
bool get_is_modified();
/*!
@returns the @c Track at @c position underneath @c head if a modification was written there.
*/
std::shared_ptr<Track> get_modified_track_at_position(unsigned int head, unsigned int position);
private:
std::map<int, std::shared_ptr<Track>> cached_tracks_;
std::set<int> modified_tracks_;
int get_id_for_track_at_position(unsigned int head, unsigned int position);
};
}

View File

@ -39,8 +39,19 @@ void Drive::set_head(unsigned int head)
head_ = head;
}
bool Drive::get_is_read_only()
{
if(disk_) return disk_->get_is_read_only();
return false;
}
std::shared_ptr<Track> Drive::get_track()
{
if(disk_) return disk_->get_track_at_position(head_, (unsigned int)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);
}

View File

@ -44,7 +44,10 @@ class Drive {
*/
void set_head(unsigned int head);
bool get_is_read_only();
std::shared_ptr<Track> get_track();
void set_track(const std::shared_ptr<Track> &track);
private:
std::shared_ptr<Disk> disk_;