From b03db5fdf9d84b152dd2ffbf0a2eb2ad7de43430 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 19 May 2026 16:32:43 -0400 Subject: [PATCH] Attach NMI and HALT. --- Components/1770/1770.hpp | 8 ++++---- Machines/Tandy/CoCo/CoCo.cpp | 8 +++++++- Machines/Tandy/CoCo/DiskController.cpp | 9 +++++++++ Machines/Tandy/CoCo/DiskController.hpp | 6 ++++++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Components/1770/1770.hpp b/Components/1770/1770.hpp index caad49d6c..87ea67366 100644 --- a/Components/1770/1770.hpp +++ b/Components/1770/1770.hpp @@ -63,15 +63,15 @@ public: }; /// @returns The current value of the IRQ line output. - inline bool get_interrupt_request_line() const { return status_.interrupt_request; } + inline bool get_interrupt_request_line() const { return status_.interrupt_request; } /// @returns The current value of the DRQ line output. - inline bool get_data_request_line() const { return status_.data_request; } + inline bool get_data_request_line() const { return status_.data_request; } struct Delegate { virtual void wd1770_did_change_output(WD1770 &) = 0; }; - inline void set_delegate(Delegate *delegate) { delegate_ = delegate; } + inline void set_delegate(Delegate *const delegate) { delegate_ = delegate; } ClockingHint::Preference preferred_clocking() const final; @@ -127,7 +127,7 @@ private: IndexHoleTarget = (1 << 6), // Indicates that index_hole_count_ has reached index_hole_count_target_. ForceInterrupt = (1 << 7) // Indicates a forced interrupt. }; - void posit_event(int type); + void posit_event(int); int interesting_event_mask_; Cycles::IntType delay_time_ = 0; diff --git a/Machines/Tandy/CoCo/CoCo.cpp b/Machines/Tandy/CoCo/CoCo.cpp index f1e6e30b7..46016489e 100644 --- a/Machines/Tandy/CoCo/CoCo.cpp +++ b/Machines/Tandy/CoCo/CoCo.cpp @@ -387,7 +387,8 @@ class ConcreteMachine: public MachineTypes::MediaTarget, public MachineTypes::ScanProducer, public MachineTypes::TimedMachine, - public Utility::TypeRecipient + public Utility::TypeRecipient, + public WD::WD1770::Delegate { public: ConcreteMachine(const Analyser::Static::TandyCoCo::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : @@ -453,6 +454,7 @@ public: if(has_disk_drive) { sam_.insert_cartridge(roms.find(DiskBASIC)->second); + disk_controller_.set_delegate(this); } insert_media(target.media); @@ -1109,6 +1111,10 @@ private: DiskController disk_controller_; Cycles cycles_16mhz_; + void wd1770_did_change_output(WD::WD1770 &) override { + m6809_.template set(disk_controller_.nmi()); + m6809_.template set(disk_controller_.halt()); + } }; } diff --git a/Machines/Tandy/CoCo/DiskController.cpp b/Machines/Tandy/CoCo/DiskController.cpp index f4344d044..1347cc54e 100644 --- a/Machines/Tandy/CoCo/DiskController.cpp +++ b/Machines/Tandy/CoCo/DiskController.cpp @@ -24,6 +24,7 @@ void DiskController::set_control(const uint8_t value) { // b3: drive motors, 1 = on // b0–b2: drive selects + double_density_ = value & 0x20; set_is_double_density(value & 0x20); for_all_drives([&] (Storage::Disk::Drive &drive, size_t) { drive.set_motor_on(value & 0x8); @@ -60,3 +61,11 @@ const Storage::Disk::Disk *DiskController::disk(const std::string &name) { // * not INTRQ hits a NOR gate with DDEN; NOR of that is piped to NMI; and // * DRQ informs HALT, if enabled. // + +bool DiskController::halt() const { + return get_data_request_line(); +} + +bool DiskController::nmi() const { + return get_interrupt_request_line() && double_density_; +} diff --git a/Machines/Tandy/CoCo/DiskController.hpp b/Machines/Tandy/CoCo/DiskController.hpp index 423443c8c..500da0d0c 100644 --- a/Machines/Tandy/CoCo/DiskController.hpp +++ b/Machines/Tandy/CoCo/DiskController.hpp @@ -42,6 +42,12 @@ public: void set_activity_observer(Activity::Observer *); void set_disk(std::shared_ptr, size_t drive); const Storage::Disk::Disk *disk(const std::string &); + + bool halt() const; + bool nmi() const; + +private: + bool double_density_ = false; }; }