1
0
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:
Thomas Harte
2025-02-24 22:34:15 -05:00
parent 8dcccf11bf
commit 93ddf4f0ba
38 changed files with 112 additions and 19 deletions
+3 -3
View File
@@ -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;
+4
View File
@@ -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();
}
+1
View File
@@ -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_;
+4
View 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();
}
+1
View File
@@ -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;
+4
View File
@@ -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();
}
+1
View File
@@ -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_;
+4
View 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();
}
+1
View File
@@ -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;
+4
View File
@@ -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()) {
+1
View File
@@ -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:
+4
View File
@@ -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();
}
+1
View File
@@ -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;
+4
View File
@@ -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();
}
+1
View File
@@ -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);
+5
View File
@@ -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);
}
}
+1
View File
@@ -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;
+4
View File
@@ -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();
}
+1
View File
@@ -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;
+4
View File
@@ -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();
}
+1
View File
@@ -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_;
+4
View 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_);
+5
View 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.