mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-11-04 00:16:26 +00:00 
			
		
		
		
	Prefer references for delegate protocols.
This commit is contained in:
		@@ -106,5 +106,5 @@ void MultiTimedMachine::run_for(const Time::Seconds duration) {
 | 
			
		||||
		if(machine->get_confidence() >= 0.01f) machine->run_for(duration);
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	if(delegate_) delegate_->did_run_machines(this);
 | 
			
		||||
	if(delegate_) delegate_->did_run_machines(*this);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ public:
 | 
			
		||||
		been received.
 | 
			
		||||
	*/
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void did_run_machines(MultiTimedMachine *) = 0;
 | 
			
		||||
		virtual void did_run_machines(MultiTimedMachine &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	/// Sets @c delegate as the receiver of delegate messages.
 | 
			
		||||
	void set_delegate(Delegate *const delegate) {
 | 
			
		||||
 
 | 
			
		||||
@@ -60,24 +60,24 @@ void MultiSpeaker::set_output_volume(const float volume) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MultiSpeaker::speaker_did_complete_samples(Speaker *const speaker, const std::vector<int16_t> &buffer) {
 | 
			
		||||
void MultiSpeaker::speaker_did_complete_samples(Speaker &speaker, const std::vector<int16_t> &buffer) {
 | 
			
		||||
	auto delegate = delegate_.load(std::memory_order_relaxed);
 | 
			
		||||
	if(!delegate) return;
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard lock_guard(front_speaker_mutex_);
 | 
			
		||||
		if(speaker != front_speaker_) return;
 | 
			
		||||
		if(&speaker != front_speaker_) return;
 | 
			
		||||
	}
 | 
			
		||||
	did_complete_samples(this, buffer, stereo_output_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MultiSpeaker::speaker_did_change_input_clock(Speaker *const speaker) {
 | 
			
		||||
void MultiSpeaker::speaker_did_change_input_clock(Speaker &speaker) {
 | 
			
		||||
	auto delegate = delegate_.load(std::memory_order_relaxed);
 | 
			
		||||
	if(!delegate) return;
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard lock_guard(front_speaker_mutex_);
 | 
			
		||||
		if(speaker != front_speaker_) return;
 | 
			
		||||
		if(&speaker != front_speaker_) return;
 | 
			
		||||
	}
 | 
			
		||||
	delegate->speaker_did_change_input_clock(this);
 | 
			
		||||
	delegate->speaker_did_change_input_clock(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MultiSpeaker::set_new_front_machine(::Machine::DynamicMachine *const machine) {
 | 
			
		||||
@@ -87,6 +87,6 @@ void MultiSpeaker::set_new_front_machine(::Machine::DynamicMachine *const machin
 | 
			
		||||
	}
 | 
			
		||||
	auto delegate = delegate_.load(std::memory_order_relaxed);
 | 
			
		||||
	if(delegate) {
 | 
			
		||||
		delegate->speaker_did_change_input_clock(this);
 | 
			
		||||
		delegate->speaker_did_change_input_clock(*this);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,8 +42,8 @@ public:
 | 
			
		||||
	void set_output_volume(float) override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void speaker_did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer) final;
 | 
			
		||||
	void speaker_did_change_input_clock(Speaker *speaker) final;
 | 
			
		||||
	void speaker_did_complete_samples(Speaker &, const std::vector<int16_t> &buffer) final;
 | 
			
		||||
	void speaker_did_change_input_clock(Speaker &) final;
 | 
			
		||||
	MultiSpeaker(const std::vector<Outputs::Speaker::Speaker *> &speakers);
 | 
			
		||||
 | 
			
		||||
	std::vector<Outputs::Speaker::Speaker *> speakers_;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@ bool MultiMachine::would_collapse(const std::vector<std::unique_ptr<DynamicMachi
 | 
			
		||||
		(machines.front()->timed_machine()->get_confidence() >= 2.0f * machines[1]->timed_machine()->get_confidence());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MultiMachine::did_run_machines(MultiTimedMachine *) {
 | 
			
		||||
void MultiMachine::did_run_machines(MultiTimedMachine &) {
 | 
			
		||||
	std::lock_guard machines_lock(machines_mutex_);
 | 
			
		||||
 | 
			
		||||
	if constexpr (logger.enabled) {
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ public:
 | 
			
		||||
	void *raw_pointer() final;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void did_run_machines(MultiTimedMachine *) final;
 | 
			
		||||
	void did_run_machines(MultiTimedMachine &) final;
 | 
			
		||||
 | 
			
		||||
	std::vector<std::unique_ptr<DynamicMachine>> machines_;
 | 
			
		||||
	std::recursive_mutex machines_mutex_;
 | 
			
		||||
 
 | 
			
		||||
@@ -820,7 +820,7 @@ void WD1770::update_status(const std::function<void(Status &)> updater) {
 | 
			
		||||
			(status_.busy != old_status.busy) ||
 | 
			
		||||
			(status_.data_request != old_status.data_request) ||
 | 
			
		||||
			(status_.interrupt_request != old_status.interrupt_request);
 | 
			
		||||
		if(did_change) delegate_->wd1770_did_change_output(this);
 | 
			
		||||
		if(did_change) delegate_->wd1770_did_change_output(*this);
 | 
			
		||||
	} else updater(status_);
 | 
			
		||||
 | 
			
		||||
	if(status_.busy != old_status.busy) update_clocking_observer();
 | 
			
		||||
 
 | 
			
		||||
@@ -66,9 +66,8 @@ public:
 | 
			
		||||
	/// @returns The current value of the DRQ line output.
 | 
			
		||||
	inline bool get_data_request_line() const		{	return status_.data_request;		}
 | 
			
		||||
 | 
			
		||||
	class Delegate {
 | 
			
		||||
	public:
 | 
			
		||||
		virtual void wd1770_did_change_output(WD1770 *) = 0;
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void wd1770_did_change_output(WD1770 &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	inline void set_delegate(Delegate *delegate)	{	delegate_ = delegate;				}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -60,8 +60,7 @@ public:
 | 
			
		||||
*/
 | 
			
		||||
class IRQDelegatePortHandler: public PortHandler {
 | 
			
		||||
public:
 | 
			
		||||
	class Delegate {
 | 
			
		||||
	public:
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		/// Indicates that the interrupt status has changed for the IRQDelegatePortHandler provided.
 | 
			
		||||
		virtual void mos6522_did_change_interrupt_status(void *irq_delegate) = 0;
 | 
			
		||||
	};
 | 
			
		||||
 
 | 
			
		||||
@@ -425,6 +425,6 @@ void z8530::update_delegate() {
 | 
			
		||||
	const bool interrupt_line = get_interrupt_line();
 | 
			
		||||
	if(interrupt_line != previous_interrupt_line_) {
 | 
			
		||||
		previous_interrupt_line_ = interrupt_line;
 | 
			
		||||
		if(delegate_) delegate_->did_change_interrupt_status(this, interrupt_line);
 | 
			
		||||
		if(delegate_) delegate_->did_change_interrupt_status(*this, interrupt_line);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,7 @@ public:
 | 
			
		||||
		/*!
 | 
			
		||||
			Communicates that @c scc now has the interrupt line status @c new_status.
 | 
			
		||||
		*/
 | 
			
		||||
		virtual void did_change_interrupt_status(z8530 *, bool new_status) = 0;
 | 
			
		||||
		virtual void did_change_interrupt_status(z8530 &, bool new_status) = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
@@ -54,7 +54,7 @@ public:
 | 
			
		||||
	void set_delegate(Delegate *const delegate) {
 | 
			
		||||
		if(delegate_ == delegate) return;
 | 
			
		||||
		delegate_ = delegate;
 | 
			
		||||
		delegate_->did_change_interrupt_status(this, get_interrupt_line());
 | 
			
		||||
		delegate_->did_change_interrupt_status(*this, get_interrupt_line());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ bool Keyboard::set_key_pressed(const Key key, const char, const bool is_pressed,
 | 
			
		||||
	}
 | 
			
		||||
	key_states_[key_offset] = is_pressed;
 | 
			
		||||
 | 
			
		||||
	if(delegate_) return delegate_->keyboard_did_change_key(this, key, is_pressed);
 | 
			
		||||
	if(delegate_) return delegate_->keyboard_did_change_key(*this, key, is_pressed);
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -38,7 +38,7 @@ const std::set<Inputs::Keyboard::Key> &Keyboard::get_essential_modifiers() const
 | 
			
		||||
 | 
			
		||||
void Keyboard::reset_all_keys() {
 | 
			
		||||
	std::fill(key_states_.begin(), key_states_.end(), false);
 | 
			
		||||
	if(delegate_) delegate_->reset_all_keys(this);
 | 
			
		||||
	if(delegate_) delegate_->reset_all_keys(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Keyboard::set_delegate(Delegate *const delegate) {
 | 
			
		||||
 
 | 
			
		||||
@@ -73,8 +73,8 @@ public:
 | 
			
		||||
 | 
			
		||||
	// Delegate interface.
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual bool keyboard_did_change_key(Keyboard *keyboard, Key key, bool is_pressed) = 0;
 | 
			
		||||
		virtual void reset_all_keys(Keyboard *keyboard) = 0;
 | 
			
		||||
		virtual bool keyboard_did_change_key(Keyboard &, Key, bool is_pressed) = 0;
 | 
			
		||||
		virtual void reset_all_keys(Keyboard &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	void set_delegate(Delegate *);
 | 
			
		||||
	bool get_key_state(Key) const;
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ public:
 | 
			
		||||
		set_delegate(this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void wd1770_did_change_output(WD::WD1770 *) override {
 | 
			
		||||
	void wd1770_did_change_output(WD::WD1770 &) override {
 | 
			
		||||
		observer_.update_interrupts();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -561,7 +561,7 @@ public:
 | 
			
		||||
		scsi_is_clocked_ = preference != ClockingHint::Preference::None;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void tape_did_change_interrupt_status(Tape *) final {
 | 
			
		||||
	void tape_did_change_interrupt_status(Tape &) final {
 | 
			
		||||
		interrupt_status_ = (interrupt_status_ & ~(Interrupt::TransmitDataEmpty | Interrupt::ReceiveDataFull | Interrupt::HighToneDetect)) | tape_.get_interrupt_status();
 | 
			
		||||
		evaluate_interrupts();
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,7 @@ void Tape::push_tape_bit(uint16_t bit) {
 | 
			
		||||
void Tape::evaluate_interrupts() {
 | 
			
		||||
	if(last_posted_interrupt_status_ != interrupt_status_) {
 | 
			
		||||
		last_posted_interrupt_status_ = interrupt_status_;
 | 
			
		||||
		if(delegate_) delegate_->tape_did_change_interrupt_status(this);
 | 
			
		||||
		if(delegate_) delegate_->tape_did_change_interrupt_status(*this);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ public:
 | 
			
		||||
	void clear_interrupts(uint8_t interrupts);
 | 
			
		||||
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void tape_did_change_interrupt_status(Tape *) = 0;
 | 
			
		||||
		virtual void tape_did_change_interrupt_status(Tape &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	inline void set_delegate(Delegate *delegate) { delegate_ = delegate; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -222,11 +222,11 @@ private:
 | 
			
		||||
		card_became_just_in_time_ |= !is_every_cycle;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void card_did_change_select_constraints(Apple::II::Card *card) final {
 | 
			
		||||
		pick_card_messaging_group(card);
 | 
			
		||||
	void card_did_change_select_constraints(Apple::II::Card &card) final {
 | 
			
		||||
		pick_card_messaging_group(&card);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void card_did_change_interrupt_flags(Apple::II::Card *) final {
 | 
			
		||||
	void card_did_change_interrupt_flags(Apple::II::Card &) final {
 | 
			
		||||
		bool nmi = false;
 | 
			
		||||
		bool irq = false;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -100,8 +100,8 @@ class Card {
 | 
			
		||||
		virtual bool irq() { return false; }
 | 
			
		||||
 | 
			
		||||
		struct Delegate {
 | 
			
		||||
			virtual void card_did_change_select_constraints(Card *card) = 0;
 | 
			
		||||
			virtual void card_did_change_interrupt_flags(Card *card) = 0;
 | 
			
		||||
			virtual void card_did_change_select_constraints(Card &) = 0;
 | 
			
		||||
			virtual void card_did_change_interrupt_flags(Card &) = 0;
 | 
			
		||||
		};
 | 
			
		||||
		void set_delegate(Delegate *delegate) {
 | 
			
		||||
			delegate_ = delegate;
 | 
			
		||||
@@ -113,7 +113,7 @@ class Card {
 | 
			
		||||
		void set_select_constraints(int constraints) {
 | 
			
		||||
			if(constraints == select_constraints_) return;
 | 
			
		||||
			select_constraints_ = constraints;
 | 
			
		||||
			if(delegate_) delegate_->card_did_change_select_constraints(this);
 | 
			
		||||
			if(delegate_) delegate_->card_did_change_select_constraints(*this);
 | 
			
		||||
		}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@ public:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void did_change_interrupt_flags() {
 | 
			
		||||
		delegate_->card_did_change_interrupt_flags(this);
 | 
			
		||||
		delegate_->card_did_change_interrupt_flags(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ void DriveSpeedAccumulator::post_sample(uint8_t sample) {
 | 
			
		||||
		const float normalised_sum = float(sample_total_) / float(samples_per_bucket);
 | 
			
		||||
		const float rotation_speed = (normalised_sum - 3.7f) * 17.6f;
 | 
			
		||||
 | 
			
		||||
		delegate_->drive_speed_accumulator_set_drive_speed(this, rotation_speed);
 | 
			
		||||
		delegate_->drive_speed_accumulator_set_drive_speed(*this, rotation_speed);
 | 
			
		||||
		sample_count_ = 0;
 | 
			
		||||
		sample_total_ = 0;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ public:
 | 
			
		||||
	void post_sample(uint8_t sample);
 | 
			
		||||
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void drive_speed_accumulator_set_drive_speed(DriveSpeedAccumulator *, float speed) = 0;
 | 
			
		||||
		virtual void drive_speed_accumulator_set_drive_speed(DriveSpeedAccumulator &, float speed) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	/*!
 | 
			
		||||
		Sets the delegate to receive drive speed changes.
 | 
			
		||||
 
 | 
			
		||||
@@ -478,7 +478,7 @@ public:
 | 
			
		||||
 | 
			
		||||
	// MARK: Interrupt updates.
 | 
			
		||||
 | 
			
		||||
	void did_change_interrupt_status(Zilog::SCC::z8530 *, bool) final {
 | 
			
		||||
	void did_change_interrupt_status(Zilog::SCC::z8530 &, bool) final {
 | 
			
		||||
		update_interrupt_input();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -536,7 +536,7 @@ private:
 | 
			
		||||
		scsi_bus_is_clocked_ = scsi_bus_.preferred_clocking() != ClockingHint::Preference::None;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void drive_speed_accumulator_set_drive_speed(DriveSpeedAccumulator *, float speed) final {
 | 
			
		||||
	void drive_speed_accumulator_set_drive_speed(DriveSpeedAccumulator &, const float speed) final {
 | 
			
		||||
		iwm_.flush();
 | 
			
		||||
		drives_[0].set_rotation_speed(speed);
 | 
			
		||||
		drives_[1].set_rotation_speed(speed);
 | 
			
		||||
 
 | 
			
		||||
@@ -561,7 +561,7 @@ private:
 | 
			
		||||
	void acia6850_did_change_interrupt_status(Motorola::ACIA::ACIA *) final {
 | 
			
		||||
		set_gpip_input();
 | 
			
		||||
	}
 | 
			
		||||
	void dma_controller_did_change_output(DMAController *) final {
 | 
			
		||||
	void dma_controller_did_change_output(DMAController &) final {
 | 
			
		||||
		set_gpip_input();
 | 
			
		||||
 | 
			
		||||
		// Filty hack, here! Should: set the 68000's bus request line. But until
 | 
			
		||||
 
 | 
			
		||||
@@ -135,12 +135,12 @@ void DMAController::run_for(HalfCycles duration) {
 | 
			
		||||
	fdc_.run_for(duration.flush<Cycles>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DMAController::wd1770_did_change_output(WD::WD1770 *) {
 | 
			
		||||
void DMAController::wd1770_did_change_output(WD::WD1770 &) {
 | 
			
		||||
	// Check for a change in interrupt state.
 | 
			
		||||
	const bool old_interrupt_line = interrupt_line_;
 | 
			
		||||
	interrupt_line_ = fdc_.get_interrupt_request_line();
 | 
			
		||||
	if(delegate_ && interrupt_line_ != old_interrupt_line) {
 | 
			
		||||
		delegate_->dma_controller_did_change_output(this);
 | 
			
		||||
		delegate_->dma_controller_did_change_output(*this);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for a change in DRQ state, if it's the FDC that is currently being watched.
 | 
			
		||||
@@ -172,7 +172,7 @@ void DMAController::wd1770_did_change_output(WD::WD1770 *) {
 | 
			
		||||
				// Set bus request.
 | 
			
		||||
				if(!bus_request_line_) {
 | 
			
		||||
					bus_request_line_ = true;
 | 
			
		||||
					if(delegate_) delegate_->dma_controller_did_change_output(this);
 | 
			
		||||
					if(delegate_) delegate_->dma_controller_did_change_output(*this);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -182,7 +182,7 @@ void DMAController::wd1770_did_change_output(WD::WD1770 *) {
 | 
			
		||||
int DMAController::bus_grant(uint16_t *ram, size_t size) {
 | 
			
		||||
	// Being granted the bus negates the request.
 | 
			
		||||
	bus_request_line_ = false;
 | 
			
		||||
	if(delegate_) delegate_->dma_controller_did_change_output(this);
 | 
			
		||||
	if(delegate_) delegate_->dma_controller_did_change_output(*this);
 | 
			
		||||
 | 
			
		||||
	size <<= 1;	// Convert to bytes.
 | 
			
		||||
	if(control_ & Control::Direction) {
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@ public:
 | 
			
		||||
	void set_floppy_disk(std::shared_ptr<Storage::Disk::Disk> disk, size_t drive);
 | 
			
		||||
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void dma_controller_did_change_output(DMAController *) = 0;
 | 
			
		||||
		virtual void dma_controller_did_change_output(DMAController &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	void set_delegate(Delegate *delegate);
 | 
			
		||||
 | 
			
		||||
@@ -86,7 +86,7 @@ private:
 | 
			
		||||
 | 
			
		||||
	} fdc_;
 | 
			
		||||
 | 
			
		||||
	void wd1770_did_change_output(WD::WD1770 *) final;
 | 
			
		||||
	void wd1770_did_change_output(WD::WD1770 &) final;
 | 
			
		||||
 | 
			
		||||
	uint16_t control_ = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -152,11 +152,11 @@ void MachineBase::process_index_hole()	{}
 | 
			
		||||
 | 
			
		||||
// MARK: - Drive VIA delegate
 | 
			
		||||
 | 
			
		||||
void MachineBase::drive_via_did_step_head(void *, const int direction) {
 | 
			
		||||
void MachineBase::drive_via_did_step_head(DriveVIA &, const int direction) {
 | 
			
		||||
	get_drive().step(Storage::Disk::HeadPosition(direction, 2));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MachineBase::drive_via_did_set_data_density(void *, const int density) {
 | 
			
		||||
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)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -252,13 +252,13 @@ void DriveVIA::set_port_output(const uint8_t value, uint8_t) {
 | 
			
		||||
			// Check for a head step.
 | 
			
		||||
			const int step_difference = ((value&3) - (previous_port_b_output_&3))&3;
 | 
			
		||||
			if(step_difference) {
 | 
			
		||||
				if(delegate_) delegate_->drive_via_did_step_head(this, (step_difference == 1) ? 1 : -1);
 | 
			
		||||
				if(delegate_) delegate_->drive_via_did_step_head(*this, (step_difference == 1) ? 1 : -1);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Check for a change in density.
 | 
			
		||||
			const int density_difference = (previous_port_b_output_^value) & (3 << 5);
 | 
			
		||||
			if(density_difference && delegate_) {
 | 
			
		||||
				delegate_->drive_via_did_set_data_density(this, (value >> 5)&3);
 | 
			
		||||
				delegate_->drive_via_did_set_data_density(*this, (value >> 5)&3);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Post the LED status.
 | 
			
		||||
 
 | 
			
		||||
@@ -77,10 +77,9 @@ private:
 | 
			
		||||
*/
 | 
			
		||||
class DriveVIA: public MOS::MOS6522::IRQDelegatePortHandler {
 | 
			
		||||
public:
 | 
			
		||||
	class Delegate {
 | 
			
		||||
		public:
 | 
			
		||||
			virtual void drive_via_did_step_head(void *driveVIA, int direction) = 0;
 | 
			
		||||
			virtual void drive_via_did_set_data_density(void *driveVIA, int density) = 0;
 | 
			
		||||
	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;
 | 
			
		||||
	};
 | 
			
		||||
	void set_delegate(Delegate *);
 | 
			
		||||
 | 
			
		||||
@@ -142,8 +141,8 @@ protected:
 | 
			
		||||
	void mos6522_did_change_interrupt_status(void *mos6522) override;
 | 
			
		||||
 | 
			
		||||
	// to satisfy DriveVIA::Delegate
 | 
			
		||||
	void drive_via_did_step_head(void *driveVIA, int direction) override;
 | 
			
		||||
	void drive_via_did_set_data_density(void *driveVIA, int density) override;
 | 
			
		||||
	void drive_via_did_step_head(DriveVIA &, int direction) override;
 | 
			
		||||
	void drive_via_did_set_data_density(DriveVIA &, int density) override;
 | 
			
		||||
 | 
			
		||||
	CPU::MOS6502::Processor<CPU::MOS6502::Personality::P6502, MachineBase, false> m6502_;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -684,8 +684,8 @@ public:
 | 
			
		||||
		return Utility::TypeRecipient<CharacterMapper>::can_type(c);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void tape_did_change_input(Storage::Tape::BinaryTapePlayer *const tape) final {
 | 
			
		||||
		keyboard_via_.set_control_line_input<MOS::MOS6522::Port::A, MOS::MOS6522::Line::One>(!tape->input());
 | 
			
		||||
	void tape_did_change_input(Storage::Tape::BinaryTapePlayer &tape) final {
 | 
			
		||||
		keyboard_via_.set_control_line_input<MOS::MOS6522::Port::A, MOS::MOS6522::Line::One>(!tape.input());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	KeyboardMapper *get_keyboard_mapper() final {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,18 @@ MachineTypes::MappedKeyboardMachine::MappedKeyboardMachine(const std::set<Inputs
 | 
			
		||||
	keyboard_.set_delegate(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MappedKeyboardMachine::keyboard_did_change_key(Inputs::Keyboard *, Inputs::Keyboard::Key key, bool is_pressed) {
 | 
			
		||||
bool MappedKeyboardMachine::keyboard_did_change_key(
 | 
			
		||||
	Inputs::Keyboard &,
 | 
			
		||||
	const Inputs::Keyboard::Key key,
 | 
			
		||||
	const bool is_pressed
 | 
			
		||||
) {
 | 
			
		||||
	const uint16_t mapped_key = get_keyboard_mapper()->mapped_key_for_key(key);
 | 
			
		||||
	if(mapped_key == KeyNotMapped) return false;
 | 
			
		||||
	set_key_state(mapped_key, is_pressed);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MappedKeyboardMachine::reset_all_keys(Inputs::Keyboard *) {
 | 
			
		||||
void MappedKeyboardMachine::reset_all_keys(Inputs::Keyboard &) {
 | 
			
		||||
	// TODO: unify naming.
 | 
			
		||||
	clear_all_keys();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -150,8 +150,8 @@ public:
 | 
			
		||||
	virtual Inputs::Keyboard &get_keyboard() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	bool keyboard_did_change_key(Inputs::Keyboard *, Inputs::Keyboard::Key, bool is_pressed) override;
 | 
			
		||||
	void reset_all_keys(Inputs::Keyboard *) override;
 | 
			
		||||
	bool keyboard_did_change_key(Inputs::Keyboard &, Inputs::Keyboard::Key, bool is_pressed) override;
 | 
			
		||||
	void reset_all_keys(Inputs::Keyboard &) override;
 | 
			
		||||
	Inputs::Keyboard keyboard_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -408,7 +408,7 @@ template <Analyser::Static::Sega::Target::Model model> class ConcreteMachine:
 | 
			
		||||
			return keyboard_;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool keyboard_did_change_key(Inputs::Keyboard *, Inputs::Keyboard::Key key, bool is_pressed) final {
 | 
			
		||||
		bool keyboard_did_change_key(Inputs::Keyboard &, Inputs::Keyboard::Key key, bool is_pressed) final {
 | 
			
		||||
			if(key == Inputs::Keyboard::Key::Enter) {
 | 
			
		||||
				pause_is_pressed_ = is_pressed;
 | 
			
		||||
				return true;
 | 
			
		||||
@@ -422,7 +422,7 @@ template <Analyser::Static::Sega::Target::Model model> class ConcreteMachine:
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		void reset_all_keys(Inputs::Keyboard *) final {
 | 
			
		||||
		void reset_all_keys(Inputs::Keyboard &) final {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// MARK: - Configuration options.
 | 
			
		||||
 
 | 
			
		||||
@@ -29,12 +29,12 @@ class DiskController: public WD::WD1770 {
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		struct Delegate: public WD1770::Delegate {
 | 
			
		||||
			virtual void disk_controller_did_change_paged_item(DiskController *controller) = 0;
 | 
			
		||||
			virtual void disk_controller_did_change_paged_item(DiskController &) = 0;
 | 
			
		||||
		};
 | 
			
		||||
		inline void set_delegate(Delegate *delegate)	{
 | 
			
		||||
			delegate_ = delegate;
 | 
			
		||||
			WD1770::set_delegate(delegate);
 | 
			
		||||
			if(delegate) delegate->disk_controller_did_change_paged_item(this);
 | 
			
		||||
			if(delegate) delegate->disk_controller_did_change_paged_item(*this);
 | 
			
		||||
		}
 | 
			
		||||
		inline PagedItem get_paged_item() {
 | 
			
		||||
			return paged_item_;
 | 
			
		||||
@@ -47,7 +47,7 @@ class DiskController: public WD::WD1770 {
 | 
			
		||||
			if(paged_item_ == item) return;
 | 
			
		||||
			paged_item_ = item;
 | 
			
		||||
			if(delegate_) {
 | 
			
		||||
				delegate_->disk_controller_did_change_paged_item(this);
 | 
			
		||||
				delegate_->disk_controller_did_change_paged_item(*this);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,7 @@ void Microdisc::set_control_register(uint8_t control, uint8_t changes) {
 | 
			
		||||
		irq_enable_ = bool(control & 0x01);
 | 
			
		||||
		const bool has_irq = get_interrupt_request_line();
 | 
			
		||||
		if(has_irq != had_irq && delegate_) {
 | 
			
		||||
			delegate_->wd1770_did_change_output(this);
 | 
			
		||||
			delegate_->wd1770_did_change_output(*this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -624,7 +624,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// to satisfy Storage::Tape::BinaryTapePlayer::Delegate
 | 
			
		||||
		void tape_did_change_input(Storage::Tape::BinaryTapePlayer *) final {
 | 
			
		||||
		void tape_did_change_input(Storage::Tape::BinaryTapePlayer &) final {
 | 
			
		||||
			set_via_port_b_input();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -648,8 +648,8 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// DiskController::Delegate
 | 
			
		||||
		void disk_controller_did_change_paged_item(DiskController *controller) final {
 | 
			
		||||
			switch(controller->get_paged_item()) {
 | 
			
		||||
		void disk_controller_did_change_paged_item(DiskController &controller) final {
 | 
			
		||||
			switch(controller.get_paged_item()) {
 | 
			
		||||
				default:
 | 
			
		||||
					ram_top_ = basic_visible_ram_top_;
 | 
			
		||||
					paged_rom_ = rom_.data();
 | 
			
		||||
@@ -667,7 +667,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface, CPU::MOS
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// WD::WD1770::Delegate
 | 
			
		||||
		void wd1770_did_change_output(WD::WD1770 *) final {
 | 
			
		||||
		void wd1770_did_change_output(WD::WD1770 &) final {
 | 
			
		||||
			set_interrupt_line();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ void Typer::run_for(const HalfCycles duration) {
 | 
			
		||||
 | 
			
		||||
	if(counter_ < 0 && counter_ + duration >= 0) {
 | 
			
		||||
		if(!type_next_character()) {
 | 
			
		||||
			delegate_->typer_reset(this);
 | 
			
		||||
			delegate_->typer_reset(*this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +41,7 @@ void Typer::run_for(const HalfCycles duration) {
 | 
			
		||||
	while(string_pointer_ < string_.size() && counter_ > frequency_) {
 | 
			
		||||
		counter_ -= frequency_;
 | 
			
		||||
		if(!type_next_character()) {
 | 
			
		||||
			delegate_->typer_reset(this);
 | 
			
		||||
			delegate_->typer_reset(*this);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -65,10 +65,9 @@ class CharacterMapper {
 | 
			
		||||
*/
 | 
			
		||||
class Typer {
 | 
			
		||||
public:
 | 
			
		||||
	class Delegate: public MachineTypes::KeyActions {
 | 
			
		||||
		public:
 | 
			
		||||
	struct Delegate: public MachineTypes::KeyActions {
 | 
			
		||||
		/// Informs the delegate that this typer has reached the end of its content.
 | 
			
		||||
			virtual void typer_reset(Typer *typer) = 0;
 | 
			
		||||
		virtual void typer_reset(Typer &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Typer(const std::string &string, HalfCycles delay, HalfCycles frequency, CharacterMapper &character_mapper, Delegate *delegate);
 | 
			
		||||
@@ -131,7 +130,7 @@ protected:
 | 
			
		||||
		Provided in order to conform to that part of the Typer::Delegate interface that goes above and
 | 
			
		||||
		beyond KeyboardMachine::Machine; responds to the end of typing by clearing all keys.
 | 
			
		||||
	*/
 | 
			
		||||
	void typer_reset(Typer *) override {
 | 
			
		||||
	void typer_reset(Typer &) override {
 | 
			
		||||
		clear_all_keys();
 | 
			
		||||
 | 
			
		||||
		// It's unsafe to deallocate typer right now, since it is the caller, but also it has a small
 | 
			
		||||
 
 | 
			
		||||
@@ -73,14 +73,14 @@ struct LockProtectedDelegate {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate, public LockProtectedDelegate {
 | 
			
		||||
	void speaker_did_complete_samples(Outputs::Speaker::Speaker *speaker, const std::vector<int16_t> &buffer) final {
 | 
			
		||||
	void speaker_did_complete_samples(Outputs::Speaker::Speaker &speaker, const std::vector<int16_t> &buffer) final {
 | 
			
		||||
		[machineAccessLock lock];
 | 
			
		||||
		[machine speaker:speaker didCompleteSamples:buffer.data() length:(int)buffer.size()];
 | 
			
		||||
		[machine speaker:&speaker didCompleteSamples:buffer.data() length:(int)buffer.size()];
 | 
			
		||||
		[machineAccessLock unlock];
 | 
			
		||||
	}
 | 
			
		||||
	void speaker_did_change_input_clock(Outputs::Speaker::Speaker *speaker) final {
 | 
			
		||||
	void speaker_did_change_input_clock(Outputs::Speaker::Speaker &speaker) final {
 | 
			
		||||
		[machineAccessLock lock];
 | 
			
		||||
		[machine speakerDidChangeInputClock:speaker];
 | 
			
		||||
		[machine speakerDidChangeInputClock:&speaker];
 | 
			
		||||
		[machineAccessLock unlock];
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -311,7 +311,7 @@ void CRT::advance_cycles(int number_of_cycles, bool hsync_requested, bool vsync_
 | 
			
		||||
			if(delegate_) {
 | 
			
		||||
				frames_since_last_delegate_call_++;
 | 
			
		||||
				if(frames_since_last_delegate_call_ == 20) {
 | 
			
		||||
					delegate_->crt_did_end_batch_of_frames(this, frames_since_last_delegate_call_, vertical_flywheel_->get_and_reset_number_of_surprises());
 | 
			
		||||
					delegate_->crt_did_end_batch_of_frames(*this, frames_since_last_delegate_call_, vertical_flywheel_->get_and_reset_number_of_surprises());
 | 
			
		||||
					frames_since_last_delegate_call_ = 0;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,9 +44,8 @@ static constexpr bool AlternatesPhase = false;
 | 
			
		||||
 | 
			
		||||
class CRT;
 | 
			
		||||
 | 
			
		||||
class Delegate {
 | 
			
		||||
	public:
 | 
			
		||||
		virtual void crt_did_end_batch_of_frames(CRT *crt, int number_of_frames, int number_of_unexpected_vertical_syncs) = 0;
 | 
			
		||||
struct Delegate {
 | 
			
		||||
	virtual void crt_did_end_batch_of_frames(CRT &, int number_of_frames, int number_of_unexpected_vertical_syncs) = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*!	Models a class 2d analogue output device, accepting a serial stream of data including syncs
 | 
			
		||||
@@ -356,7 +355,7 @@ template <typename Receiver> class CRTFrequencyMismatchWarner: public Outputs::C
 | 
			
		||||
public:
 | 
			
		||||
	CRTFrequencyMismatchWarner(Receiver &receiver) : receiver_(receiver) {}
 | 
			
		||||
 | 
			
		||||
	void crt_did_end_batch_of_frames(Outputs::CRT::CRT *, int number_of_frames, int number_of_unexpected_vertical_syncs) final {
 | 
			
		||||
	void crt_did_end_batch_of_frames(Outputs::CRT::CRT &, int number_of_frames, int number_of_unexpected_vertical_syncs) final {
 | 
			
		||||
		frame_records_[frame_record_pointer_ % frame_records_.size()].number_of_frames = number_of_frames;
 | 
			
		||||
		frame_records_[frame_record_pointer_ % frame_records_.size()].number_of_unexpected_vertical_syncs = number_of_unexpected_vertical_syncs;
 | 
			
		||||
		++frame_record_pointer_;
 | 
			
		||||
 
 | 
			
		||||
@@ -245,7 +245,7 @@ protected:
 | 
			
		||||
		const int scale = static_cast<ConcreteT *>(this)->get_scale();
 | 
			
		||||
 | 
			
		||||
		if(recalculate_filter_if_dirty()) {
 | 
			
		||||
			delegate->speaker_did_change_input_clock(this);
 | 
			
		||||
			delegate->speaker_did_change_input_clock(*this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch(conversion_) {
 | 
			
		||||
 
 | 
			
		||||
@@ -120,13 +120,13 @@ public:
 | 
			
		||||
			Indicates that a new audio packet is ready. If the output is stereo, samples will be interleaved with the first
 | 
			
		||||
			being left, the second being right, etc.
 | 
			
		||||
		*/
 | 
			
		||||
		virtual void speaker_did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer) = 0;
 | 
			
		||||
		virtual void speaker_did_complete_samples(Speaker &, const std::vector<int16_t> &buffer) = 0;
 | 
			
		||||
 | 
			
		||||
		/*!
 | 
			
		||||
			Provides the delegate with a hint that the input clock rate has changed, which provides an opportunity to
 | 
			
		||||
			renegotiate the ideal clock rate, if desired.
 | 
			
		||||
		*/
 | 
			
		||||
		virtual void speaker_did_change_input_clock([[maybe_unused]] Speaker *speaker) {}
 | 
			
		||||
		virtual void speaker_did_change_input_clock(Speaker &) {}
 | 
			
		||||
	};
 | 
			
		||||
	virtual void set_delegate(Delegate *delegate) {
 | 
			
		||||
		delegate_.store(delegate, std::memory_order_relaxed);
 | 
			
		||||
@@ -147,7 +147,7 @@ protected:
 | 
			
		||||
		// Hope for the fast path first: producer and consumer agree about
 | 
			
		||||
		// number of channels.
 | 
			
		||||
		if(is_stereo == stereo_output_) {
 | 
			
		||||
			delegate->speaker_did_complete_samples(this, buffer);
 | 
			
		||||
			delegate->speaker_did_complete_samples(*this, buffer);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -166,7 +166,7 @@ protected:
 | 
			
		||||
				mix_buffer_[(c << 1) + 0] = mix_buffer_[(c << 1) + 1] = buffer[c];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		delegate->speaker_did_complete_samples(this, mix_buffer_);
 | 
			
		||||
		delegate->speaker_did_complete_samples(*this, mix_buffer_);
 | 
			
		||||
	}
 | 
			
		||||
	std::atomic<Delegate *> delegate_{nullptr};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -196,6 +196,6 @@ void BinaryTapePlayer::process(const Storage::Tape::Pulse &pulse) {
 | 
			
		||||
	bool new_input_level = pulse.type == Pulse::High;
 | 
			
		||||
	if(input_level_ != new_input_level) {
 | 
			
		||||
		input_level_ = new_input_level;
 | 
			
		||||
		if(delegate_) delegate_->tape_did_change_input(this);
 | 
			
		||||
		if(delegate_) delegate_->tape_did_change_input(*this);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -168,7 +168,7 @@ public:
 | 
			
		||||
	void run_for(Cycles);
 | 
			
		||||
 | 
			
		||||
	struct Delegate {
 | 
			
		||||
		virtual void tape_did_change_input(BinaryTapePlayer *) = 0;
 | 
			
		||||
		virtual void tape_did_change_input(BinaryTapePlayer &) = 0;
 | 
			
		||||
	};
 | 
			
		||||
	void set_delegate(Delegate *);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user