mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +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;
|
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)
|
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);
|
std::map<int, std::shared_ptr<Track>>::iterator cached_track = cached_tracks_.find(address);
|
||||||
if(cached_track != cached_tracks_.end()) return cached_track->second;
|
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;
|
cached_tracks_[address] = track;
|
||||||
return 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 <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include "../Storage.hpp"
|
#include "../Storage.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
@ -85,6 +86,18 @@ class Disk {
|
|||||||
*/
|
*/
|
||||||
std::shared_ptr<Track> get_track_at_position(unsigned int head, unsigned int position);
|
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:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
Subclasses should implement this to return the @c Track at @c position underneath @c head. Returned tracks
|
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;
|
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:
|
private:
|
||||||
std::map<int, std::shared_ptr<Track>> cached_tracks_;
|
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;
|
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()
|
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(head_, (unsigned int)head_position_);
|
||||||
return nullptr;
|
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);
|
void set_head(unsigned int head);
|
||||||
|
|
||||||
|
bool get_is_read_only();
|
||||||
|
|
||||||
std::shared_ptr<Track> get_track();
|
std::shared_ptr<Track> get_track();
|
||||||
|
void set_track(const std::shared_ptr<Track> &track);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Disk> disk_;
|
std::shared_ptr<Disk> disk_;
|
||||||
|
Loading…
Reference in New Issue
Block a user