mirror of
https://github.com/TomHarte/CLK.git
synced 2025-03-08 00:35:47 +00:00
Moves interrupt level selection outside the loop.
This commit is contained in:
parent
4aca6c5ef8
commit
0469f0240b
@ -64,6 +64,7 @@ std::uint8_t z8530::read(int address) {
|
||||
}
|
||||
|
||||
pointer_ = 0;
|
||||
update_delegate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -110,10 +111,12 @@ void z8530::write(int address, std::uint8_t value) {
|
||||
}
|
||||
}
|
||||
}
|
||||
update_delegate();
|
||||
}
|
||||
|
||||
void z8530::set_dcd(int port, bool level) {
|
||||
channels_[port].set_dcd(level);
|
||||
update_delegate();
|
||||
}
|
||||
|
||||
// MARK: - Channel implementations
|
||||
@ -255,3 +258,11 @@ bool z8530::Channel::get_interrupt_line() {
|
||||
(interrupt_mask_ & 1) && external_status_interrupt_;
|
||||
// TODO: other potential causes of an interrupt.
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,13 @@ class z8530 {
|
||||
void reset();
|
||||
bool get_interrupt_line();
|
||||
|
||||
struct Delegate {
|
||||
virtual void did_change_interrupt_status(z8530 *, bool new_status) = 0;
|
||||
};
|
||||
void set_delegate(Delegate *delegate) {
|
||||
delegate_ = delegate;
|
||||
}
|
||||
|
||||
/*
|
||||
**Interface for serial port input.**
|
||||
*/
|
||||
@ -79,6 +86,10 @@ class z8530 {
|
||||
uint8_t interrupt_vector_ = 0;
|
||||
|
||||
uint8_t master_interrupt_control_ = 0;
|
||||
|
||||
bool previous_interrupt_line_ = false;
|
||||
void update_delegate();
|
||||
Delegate *delegate_ = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -51,7 +51,8 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
||||
public MediaTarget::Machine,
|
||||
public MouseMachine::Machine,
|
||||
public CPU::MC68000::BusHandler,
|
||||
public KeyboardMachine::MappedMachine {
|
||||
public KeyboardMachine::MappedMachine,
|
||||
public Zilog::SCC::z8530::Delegate {
|
||||
public:
|
||||
using Target = Analyser::Static::Macintosh::Target;
|
||||
|
||||
@ -112,6 +113,9 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
||||
iwm_.iwm.set_drive(0, &drives_[0]);
|
||||
iwm_.iwm.set_drive(1, &drives_[1]);
|
||||
|
||||
// Make sure interrupt changes from the SCC are observed.
|
||||
scc_.set_delegate(this);
|
||||
|
||||
// The Mac runs at 7.8336mHz.
|
||||
set_clock_rate(double(CLOCK_RATE));
|
||||
audio_.speaker.set_input_rate(float(CLOCK_RATE) / 2.0f);
|
||||
@ -208,16 +212,6 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
||||
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, false);
|
||||
}
|
||||
|
||||
// Update interrupt input. TODO: move this into a VIA/etc delegate callback?
|
||||
// Double TODO: does this really cascade like this?
|
||||
if(scc_.get_interrupt_line()) {
|
||||
mc68000_.set_interrupt_level(2);
|
||||
} else if(via_.get_interrupt_line()) {
|
||||
mc68000_.set_interrupt_level(1);
|
||||
} else {
|
||||
mc68000_.set_interrupt_level(0);
|
||||
}
|
||||
|
||||
// A null cycle leaves nothing else to do.
|
||||
if(!(cycle.operation & (Microcycle::NewAddress | Microcycle::SameAddress))) return delay;
|
||||
|
||||
@ -433,6 +427,24 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
||||
|
||||
// TODO: clear all keys.
|
||||
|
||||
// MARK: Interrupt updates.
|
||||
|
||||
void did_change_interrupt_status(Zilog::SCC::z8530 *sender, bool new_status) override {
|
||||
update_interrupt_input();
|
||||
}
|
||||
|
||||
void update_interrupt_input() {
|
||||
// Update interrupt input.
|
||||
// TODO: does this really cascade like this?
|
||||
if(scc_.get_interrupt_line()) {
|
||||
mc68000_.set_interrupt_level(2);
|
||||
} else if(via_.get_interrupt_line()) {
|
||||
mc68000_.set_interrupt_level(1);
|
||||
} else {
|
||||
mc68000_.set_interrupt_level(0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void update_video() {
|
||||
video_.run_for(time_since_video_update_.flush());
|
||||
@ -554,6 +566,10 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
||||
audio_.flush();
|
||||
}
|
||||
|
||||
void set_interrupt_status(bool status) {
|
||||
machine_.update_interrupt_input();
|
||||
}
|
||||
|
||||
private:
|
||||
ConcreteMachine &machine_;
|
||||
RealTimeClock &clock_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user