mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +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:
parent
7f303cfceb
commit
6e94d0c19f
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user