Add a clock to the 6522s, enable interrupts.

This commit is contained in:
Thomas Harte 2024-02-14 22:01:03 -05:00
parent 07c11e8268
commit 1e877c7563
4 changed files with 52 additions and 4 deletions

View File

@ -68,7 +68,7 @@ class IRQDelegatePortHandler: public PortHandler {
/// Sets the delegate that will receive notification of changes in the interrupt line.
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);
private:

View File

@ -256,6 +256,20 @@ template <Analyser::Static::AppleII::Target::Model model, bool has_mockingboard>
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() {
return dynamic_cast<Apple::II::Mockingboard *>(cards_[MockingboardSlot - 1].get());
}

View File

@ -54,7 +54,7 @@ class Card {
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
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) {}
@ -93,8 +93,15 @@ class Card {
/*! Cards may supply a target for activity observation if desired. */
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 {
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) {
delegate_ = delegate;

View File

@ -18,7 +18,10 @@ namespace Apple::II {
class Mockingboard: public Card {
public:
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 {
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:
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];