From 9e39be282b20f680178f6de1f6f848686d0cfa91 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 18 Nov 2025 13:12:41 -0500 Subject: [PATCH] Start to consolidate relationship around push. --- .../Commodore/1540/Implementation/C1540.cpp | 68 ++++++++++++------- .../1540/Implementation/C1540Base.hpp | 18 +++-- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/Machines/Commodore/1540/Implementation/C1540.cpp b/Machines/Commodore/1540/Implementation/C1540.cpp index 7fe86dd47..58cd6b11e 100644 --- a/Machines/Commodore/1540/Implementation/C1540.cpp +++ b/Machines/Commodore/1540/Implementation/C1540.cpp @@ -109,10 +109,7 @@ Cycles MachineBase::perform(const AddressT address, CPU::MOS6502Mk2::data_t(true); } + } else { + m6502_.set(false); } - else m6502_.set(false); } // the 1540 does not recognise index holes @@ -174,6 +172,21 @@ void MachineBase::drive_via_did_set_data_density(DriveVIA &, const int density) set_expected_bit_length(Storage::Encodings::CommodoreGCR::length_of_a_bit_in_time_zone(unsigned(density))); } +void MachineBase::drive_via_did_set_drive_motor(DriveVIA &, const bool enabled) { + get_drive().set_motor_on(enabled); +} + +void MachineBase::drive_via_did_set_write_mode(DriveVIA &, bool) { + // TODO. +} + +void MachineBase::drive_via_should_set_cpu_overflow(DriveVIA &, const bool overflow) { + set_cpu_overflow_ = overflow; + if(!overflow) { + m6502_.set(false); + } +} + // MARK: - SerialPortVIA template @@ -200,13 +213,17 @@ void SerialPortVIA::set_serial_line_state( const bool value, MOS::MOS6522::MOS6522 &via ) { + const auto set = [&](const uint8_t mask) { + port_b_ = (port_b_ & ~mask) | (value ? 0x00 : mask); + }; + switch(line) { default: break; - case ::Commodore::Serial::Line::Data: port_b_ = (port_b_ & ~0x01) | (value ? 0x00 : 0x01); break; - case ::Commodore::Serial::Line::Clock: port_b_ = (port_b_ & ~0x04) | (value ? 0x00 : 0x04); break; + case ::Commodore::Serial::Line::Data: set(0x01); break; + case ::Commodore::Serial::Line::Clock: set(0x04); break; case ::Commodore::Serial::Line::Attention: + set(0x80); attention_level_input_ = !value; - port_b_ = (port_b_ & ~0x80) | (value ? 0x00 : 0x80); via.set_control_line_input(!value); update_data_line(); break; @@ -249,24 +266,23 @@ void DriveVIA::set_data_input(const uint8_t value) { port_a_ = value; } -bool DriveVIA::should_set_overflow() { - return should_set_overflow_; -} - -bool DriveVIA::motor_enabled() { - return drive_motor_; -} - template void DriveVIA::set_control_line_output(const bool value) { if(port == MOS::MOS6522::Port::A && line == MOS::MOS6522::Line::Two) { - should_set_overflow_ = value; + if(set_cpu_overflow_ != value) { + set_cpu_overflow_ = value; + if(delegate_) { + delegate_->drive_via_should_set_cpu_overflow(*this, set_cpu_overflow_); + } + } } if(port == MOS::MOS6522::Port::B && line == MOS::MOS6522::Line::Two) { - // TODO: 0 = write, 1 = read. - if(!value) { - printf("NOT IMPLEMENTED: write mode\n"); + if(value != write_mode_) { + write_mode_ = !value; + if(delegate_) { + delegate_->drive_via_did_set_write_mode(*this, write_mode_); + } } } } @@ -275,7 +291,13 @@ template <> void DriveVIA::set_port_output(const uint8_t value, uint8_t) { if(previous_port_b_output_ != value) { // Record drive motor state. - drive_motor_ = value&4; + const bool new_drive_motor = value & 4; + if(new_drive_motor != drive_motor_) { + drive_motor_ = new_drive_motor; + if(delegate_) { + delegate_->drive_via_did_set_drive_motor(*this, drive_motor_); + } + } // Check for a head step. const int step_difference = ((value&3) - (previous_port_b_output_&3))&3; diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp index 0ffd2940f..f3fc8b6c5 100644 --- a/Machines/Commodore/1540/Implementation/C1540Base.hpp +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -82,6 +82,9 @@ public: struct Delegate { virtual void drive_via_did_step_head(DriveVIA &, int direction) = 0; virtual void drive_via_did_set_data_density(DriveVIA &, int density) = 0; + virtual void drive_via_did_set_drive_motor(DriveVIA &, bool enabled) = 0; + virtual void drive_via_did_set_write_mode(DriveVIA &, bool write) = 0; + virtual void drive_via_should_set_cpu_overflow(DriveVIA &, bool overflow) = 0; }; void set_delegate(Delegate *); @@ -91,8 +94,6 @@ public: void set_sync_detected(bool); void set_data_input(uint8_t); void set_is_read_only(bool); - bool should_set_overflow(); - bool motor_enabled(); template void set_control_line_output(bool value); @@ -104,8 +105,11 @@ public: private: uint8_t port_b_ = 0xff, port_a_ = 0xff; - bool should_set_overflow_ = false; + + bool set_cpu_overflow_ = false; bool drive_motor_ = false; + bool write_mode_ = false; + uint8_t previous_port_b_output_ = 0; Delegate *delegate_ = nullptr; Activity::Observer *observer_ = nullptr; @@ -144,8 +148,11 @@ protected: void mos6522_did_change_interrupt_status(void *mos6522) override; // to satisfy DriveVIA::Delegate - void drive_via_did_step_head(DriveVIA &, int direction) override; - void drive_via_did_set_data_density(DriveVIA &, int density) override; + void drive_via_did_step_head(DriveVIA &, int) override; + void drive_via_did_set_data_density(DriveVIA &, int) override; + void drive_via_did_set_drive_motor(DriveVIA &, bool) override; + void drive_via_did_set_write_mode(DriveVIA &, bool) override; + void drive_via_should_set_cpu_overflow(DriveVIA &, bool) override; struct M6502Traits { static constexpr auto uses_ready_line = false; @@ -164,6 +171,7 @@ protected: MOS::MOS6522::MOS6522 drive_VIA_; MOS::MOS6522::MOS6522 serial_port_VIA_; + bool set_cpu_overflow_ = false; int shift_register_ = 0, bit_window_offset_; void process_input_bit(int value) override; void process_index_hole() override;