mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-19 02:22:39 +00:00
Ensure ZX Spectrum, at least, returns correct indication.
This commit is contained in:
@@ -697,9 +697,9 @@ template<Model model> class ConcreteMachine:
|
||||
}
|
||||
|
||||
ChangeEffect effect_for_file_did_change(const std::string &file_name) override {
|
||||
fdc_->disk();
|
||||
|
||||
return ChangeEffect::None;
|
||||
const auto disk = fdc_->disk();
|
||||
return disk && disk->represents(file_name) && disk->has_written() ?
|
||||
ChangeEffect::None : ChangeEffect::RestartMachine;
|
||||
}
|
||||
|
||||
// MARK: - ClockingHint::Observer.
|
||||
|
||||
@@ -10,9 +10,4 @@ import Cocoa
|
||||
|
||||
class DocumentController: NSDocumentController {
|
||||
let joystickManager = CSJoystickManager()
|
||||
|
||||
override func document(for url: URL) -> NSDocument? {
|
||||
Swift.print("Document for?")
|
||||
return super.document(for: url)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,16 +71,24 @@ class MachineDocument:
|
||||
self.displayName = analyser.displayName
|
||||
self.configureAs(analyser)
|
||||
self.fileObserver = CSFileContentChangeObserver.init(url: url, handler: {
|
||||
switch(self.machine.effectForFile(atURLDidChange: url)) {
|
||||
case .reinsertMedia: self.insertFile(url)
|
||||
case .restartMachine:
|
||||
let target = CSStaticAnalyser(fileAt: url)
|
||||
if let target = target {
|
||||
self.configureAs(target)
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
// self.actionLock.lock()
|
||||
// self.drawLock.lock()
|
||||
|
||||
case .none: fallthrough
|
||||
@unknown default: break
|
||||
switch(self.machine.effectForFile(atURLDidChange: url)) {
|
||||
case .reinsertMedia: self.insertFile(url)
|
||||
case .restartMachine:
|
||||
let target = CSStaticAnalyser(fileAt: url)
|
||||
if let target = target {
|
||||
// self.configureAs(target)
|
||||
}
|
||||
|
||||
case .none: fallthrough
|
||||
@unknown default: break
|
||||
}
|
||||
|
||||
// self.actionLock.unlock()
|
||||
// self.drawLock.unlock()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -23,8 +23,7 @@ bool DiskImageHolder<T>::get_is_read_only() const {
|
||||
|
||||
template <typename T>
|
||||
bool DiskImageHolder<T>::represents(const std::string &file) const {
|
||||
return false; // TODO.
|
||||
// return disk_image_.represents(file);
|
||||
return disk_image_.represents(file);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -185,3 +185,7 @@ std::unique_ptr<Track> AmigaADF::track_at_position(Track::Address address) const
|
||||
long AmigaADF::get_file_offset_for_position(Track::Address address) const {
|
||||
return (address.position.as_int() * 2 + address.head) * 512 * 11;
|
||||
}
|
||||
|
||||
bool AmigaADF::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -121,3 +121,7 @@ void AppleDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>>
|
||||
file_.write(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
bool AppleDSK::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &);
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -388,3 +388,7 @@ void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::uni
|
||||
bool CPCDSK::get_is_read_only() const {
|
||||
return is_read_only_;
|
||||
}
|
||||
|
||||
bool CPCDSK::represents(const std::string &name) const {
|
||||
return name == file_name_;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &);
|
||||
std::unique_ptr<::Storage::Disk::Track> track_at_position(::Storage::Disk::Track::Address) const;
|
||||
|
||||
|
||||
@@ -137,3 +137,7 @@ std::unique_ptr<Track> D64::track_at_position(const Track::Address address) cons
|
||||
|
||||
return std::make_unique<PCMTrack>(PCMSegment(data));
|
||||
}
|
||||
|
||||
bool D64::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -181,3 +181,7 @@ std::unique_ptr<::Storage::Disk::Track> DMK::track_at_position(const ::Storage::
|
||||
|
||||
return std::make_unique<PCMTrack>(segments);
|
||||
}
|
||||
|
||||
bool DMK::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
|
||||
@@ -105,3 +105,7 @@ std::unique_ptr<Track> G64::track_at_position(const Track::Address address) cons
|
||||
// TODO: find out whether it's possible for a G64 to supply only a partial track. I don't think it is, which
|
||||
// would make the above correct but supposing I'm wrong, the above would produce some incorrectly clocked tracks.
|
||||
}
|
||||
|
||||
bool G64::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
using DiskImage::get_is_read_only;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -128,3 +128,7 @@ void HFE::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tra
|
||||
bool HFE::get_is_read_only() const {
|
||||
return file_.get_is_known_read_only();
|
||||
}
|
||||
|
||||
bool HFE::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
|
||||
@@ -98,6 +98,10 @@ int IMD::get_head_count() const {
|
||||
return heads_ + 1;
|
||||
}
|
||||
|
||||
bool IMD::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
std::unique_ptr<Track> IMD::track_at_position(const Track::Address address) const {
|
||||
auto location = track_locations_.find(address);
|
||||
if(location == track_locations_.end()) {
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
// DiskImage interface.
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool represents(const std::string &) const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -437,3 +437,7 @@ void IPF::add_raw_data(std::vector<Storage::Disk::PCMSegment> &track, Time bit_l
|
||||
assert(segment.data.size() <= num_bits_ceiling);
|
||||
segment.data.resize(num_bits);
|
||||
}
|
||||
|
||||
bool IPF::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -71,3 +71,7 @@ void MFMSectorDump::set_tracks(const std::map<Track::Address, std::unique_ptr<Tr
|
||||
bool MFMSectorDump::get_is_read_only() const {
|
||||
return file_.get_is_known_read_only();
|
||||
}
|
||||
|
||||
bool MFMSectorDump::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
MFMSectorDump(const std::string &file_name);
|
||||
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
|
||||
@@ -94,3 +94,7 @@ HeadPosition MSA::get_maximum_head_position() const {
|
||||
int MSA::get_head_count() const {
|
||||
return sides_;
|
||||
}
|
||||
|
||||
bool MSA::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
int get_head_count() const;
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
bool get_is_read_only() const { return false; }
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable FileHolder file_;
|
||||
|
||||
@@ -171,6 +171,11 @@ bool MacintoshIMG::get_is_read_only() const {
|
||||
return file_.get_is_known_read_only();
|
||||
}
|
||||
|
||||
bool MacintoshIMG::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Track> MacintoshIMG::track_at_position(Track::Address address) const {
|
||||
/*
|
||||
The format_ byte has the following meanings:
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
|
||||
@@ -50,6 +50,10 @@ bool NIB::get_is_read_only() const {
|
||||
return file_.get_is_known_read_only();
|
||||
}
|
||||
|
||||
bool NIB::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
long NIB::file_offset(const Track::Address address) const {
|
||||
return long(address.position.as_int()) * track_length;
|
||||
}
|
||||
@@ -189,3 +193,4 @@ void NIB::set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tra
|
||||
file_.write(track.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable FileHolder file_;
|
||||
|
||||
@@ -167,3 +167,7 @@ void OricMFMDSK::set_tracks(const std::map<Track::Address, std::unique_ptr<Track
|
||||
bool OricMFMDSK::get_is_read_only() const {
|
||||
return file_.get_is_known_read_only();
|
||||
}
|
||||
|
||||
bool OricMFMDSK::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool get_is_read_only() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
@@ -593,3 +593,7 @@ std::unique_ptr<Track> STX::track_at_position(const Track::Address address) cons
|
||||
TrackConstructor constructor(track_data, sectors, track_length, first_sync);
|
||||
return constructor.get_track();
|
||||
}
|
||||
|
||||
bool STX::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
|
||||
HeadPosition get_maximum_head_position() const;
|
||||
int get_head_count() const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
std::unique_ptr<Track> track_at_position(Track::Address) const;
|
||||
|
||||
|
||||
@@ -228,3 +228,7 @@ bool WOZ::get_is_read_only() const {
|
||||
return true;
|
||||
// return file_.get_is_known_read_only() || is_read_only_ || type_ == Type::WOZ2; // WOZ 2 disks are currently read only.
|
||||
}
|
||||
|
||||
bool WOZ::represents(const std::string &name) const {
|
||||
return name == file_.name();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
void set_tracks(const std::map<Track::Address, std::unique_ptr<Track>> &tracks);
|
||||
bool get_is_read_only() const;
|
||||
bool tracks_differ(Track::Address, Track::Address) const;
|
||||
bool represents(const std::string &) const;
|
||||
|
||||
private:
|
||||
mutable Storage::FileHolder file_;
|
||||
|
||||
@@ -107,6 +107,10 @@ std::string FileHolder::extension() const {
|
||||
return extension;
|
||||
}
|
||||
|
||||
const std::string &FileHolder::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
void FileHolder::ensure_is_at_least_length(long length) {
|
||||
std::fseek(file_, 0, SEEK_END);
|
||||
long bytes_to_write = length - ftell(file_);
|
||||
|
||||
@@ -161,6 +161,11 @@ public:
|
||||
*/
|
||||
std::string extension() const;
|
||||
|
||||
/*!
|
||||
Returns the underlying file name.
|
||||
*/
|
||||
const std::string &name() const;
|
||||
|
||||
/*!
|
||||
Ensures the file is at least @c length bytes long, appending 0s until it is
|
||||
if necessary.
|
||||
|
||||
Reference in New Issue
Block a user