mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-23 03:29:04 +00:00
Add a clock to the 6522s, enable interrupts.
This commit is contained in:
parent
07c11e8268
commit
1e877c7563
@ -68,7 +68,7 @@ class IRQDelegatePortHandler: public PortHandler {
|
|||||||
/// Sets the delegate that will receive notification of changes in the interrupt line.
|
/// Sets the delegate that will receive notification of changes in the interrupt line.
|
||||||
void set_interrupt_delegate(Delegate *delegate);
|
void set_interrupt_delegate(Delegate *delegate);
|
||||||
|
|
||||||
/// Overrides PortHandler::set_interrupt_status, notifying the delegate if one is set.
|
/// Overrides @c PortHandler::set_interrupt_status, notifying the delegate if one is set.
|
||||||
void set_interrupt_status(bool new_status);
|
void set_interrupt_status(bool new_status);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -256,6 +256,20 @@ template <Analyser::Static::AppleII::Target::Model model, bool has_mockingboard>
|
|||||||
pick_card_messaging_group(card);
|
pick_card_messaging_group(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void card_did_change_interrupt_flags(Apple::II::Card *) final {
|
||||||
|
bool nmi = false;
|
||||||
|
bool irq = false;
|
||||||
|
|
||||||
|
for(const auto &card: cards_) {
|
||||||
|
if(card) {
|
||||||
|
nmi |= card->nmi();
|
||||||
|
irq |= card->irq();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m6502_.set_nmi_line(nmi);
|
||||||
|
m6502_.set_irq_line(irq);
|
||||||
|
}
|
||||||
|
|
||||||
Apple::II::Mockingboard *mockingboard() {
|
Apple::II::Mockingboard *mockingboard() {
|
||||||
return dynamic_cast<Apple::II::Mockingboard *>(cards_[MockingboardSlot - 1].get());
|
return dynamic_cast<Apple::II::Mockingboard *>(cards_[MockingboardSlot - 1].get());
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ class Card {
|
|||||||
|
|
||||||
This is posted only to cards that announced a select constraint. Cards with
|
This is posted only to cards that announced a select constraint. Cards with
|
||||||
no constraints, that want to be informed of every machine cycle, will receive
|
no constraints, that want to be informed of every machine cycle, will receive
|
||||||
a call to perform_bus_operation every cycle and should use that for time keeping.
|
a call to @c perform_bus_operation every cycle and should use that for time keeping.
|
||||||
*/
|
*/
|
||||||
virtual void run_for([[maybe_unused]] Cycles cycles, [[maybe_unused]] int stretches) {}
|
virtual void run_for([[maybe_unused]] Cycles cycles, [[maybe_unused]] int stretches) {}
|
||||||
|
|
||||||
@ -93,8 +93,15 @@ class Card {
|
|||||||
/*! Cards may supply a target for activity observation if desired. */
|
/*! Cards may supply a target for activity observation if desired. */
|
||||||
virtual void set_activity_observer([[maybe_unused]] Activity::Observer *observer) {}
|
virtual void set_activity_observer([[maybe_unused]] Activity::Observer *observer) {}
|
||||||
|
|
||||||
|
/// @returns The current semantic NMI line output of this card.
|
||||||
|
virtual bool nmi() { return false; }
|
||||||
|
|
||||||
|
/// @returns The current semantic IRQ line output of this card.
|
||||||
|
virtual bool irq() { return false; }
|
||||||
|
|
||||||
struct Delegate {
|
struct Delegate {
|
||||||
virtual void card_did_change_select_constraints(Card *card) = 0;
|
virtual void card_did_change_select_constraints(Card *card) = 0;
|
||||||
|
virtual void card_did_change_interrupt_flags(Card *card) = 0;
|
||||||
};
|
};
|
||||||
void set_delegate(Delegate *delegate) {
|
void set_delegate(Delegate *delegate) {
|
||||||
delegate_ = delegate;
|
delegate_ = delegate;
|
||||||
|
@ -18,7 +18,10 @@ namespace Apple::II {
|
|||||||
class Mockingboard: public Card {
|
class Mockingboard: public Card {
|
||||||
public:
|
public:
|
||||||
Mockingboard() :
|
Mockingboard() :
|
||||||
vias_{ {handlers_[0]}, {handlers_[1]} } {}
|
vias_{ {handlers_[0]}, {handlers_[1]} } {
|
||||||
|
set_select_constraints(0);
|
||||||
|
handlers_[0].card = handlers_[1].card = this;
|
||||||
|
}
|
||||||
|
|
||||||
void perform_bus_operation(Select select, bool is_read, uint16_t address, uint8_t *value) final {
|
void perform_bus_operation(Select select, bool is_read, uint16_t address, uint8_t *value) final {
|
||||||
if(!(select & Device)) {
|
if(!(select & Device)) {
|
||||||
@ -33,8 +36,32 @@ class Mockingboard: public Card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_for(Cycles cycles, int) final {
|
||||||
|
vias_[0].run_for(cycles);
|
||||||
|
vias_[1].run_for(cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool nmi() final {
|
||||||
|
return handlers_[1].interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool irq() final {
|
||||||
|
return handlers_[0].interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void did_change_interrupt_flags() {
|
||||||
|
delegate_->card_did_change_interrupt_flags(this);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class AYVIA: public MOS::MOS6522::IRQDelegatePortHandler {
|
struct AYVIA: public MOS::MOS6522::PortHandler {
|
||||||
|
void set_interrupt_status(bool status) {
|
||||||
|
interrupt = status;
|
||||||
|
card->did_change_interrupt_flags();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool interrupt;
|
||||||
|
Mockingboard *card = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
MOS::MOS6522::MOS6522<AYVIA> vias_[2];
|
MOS::MOS6522::MOS6522<AYVIA> vias_[2];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user