From 21e8360dc1e5d2c46bf643d892f2c9896cccf061 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Fri, 24 Aug 2018 12:14:14 +0100 Subject: [PATCH] First stab at interrupt handling on the 6809 processor. Signed-off-by: Adrian Conlon --- MC6809/inc/mc6809.h | 6 ++++++ MC6809/src/mc6809.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index 05e373d..8fe0c36 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -122,6 +122,12 @@ namespace EightBit { void execute10(uint8_t opcode); void execute11(uint8_t opcode); + // Interrupt handlers + + void handleNMI(); + void handleIRQ(); + void handleFIRQ(); + // Register selection for "indexed" register16_t& RR(int which); diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index bf4a9e0..bf9a5a6 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -13,19 +13,55 @@ int EightBit::mc6809::step() { if (LIKELY(powered())) { m_prefix10 = m_prefix11 = false; ExecutingInstruction.fire(*this); - return execute(fetchByte()); + if (lowered(NMI())) + handleNMI(); + else if (lowered(FIRQ()) && !(CC() & FF)) + handleFIRQ(); + else if (lowered(IRQ()) && !(CC() & IF)) + handleIRQ(); + else + execute(fetchByte()); ExecutedInstruction.fire(*this); } return cycles(); } +// Interrupt (etc.) handlers + void EightBit::mc6809::reset() { Processor::reset(); DP() = 0; // Reestablish zero page - CC() |= (IF & FF); // Disable interrupts + CC() |= (IF & FF); // Disable IRQ and FIRQ jump(getWordPaged(0xff, RESETvector)); } +void EightBit::mc6809::handleNMI() { + raise(NMI()); + addCycles(21); + saveEntireRegisterState(); + jump(getWordPaged(0xff, NMIvector)); +} + +void EightBit::mc6809::handleIRQ() { + raise(IRQ()); + addCycles(21); + saveEntireRegisterState(); + CC() |= IF; // Disable IRQ + jump(getWordPaged(0xff, IRQvector)); +} + +void EightBit::mc6809::handleFIRQ() { + addCycles(12); + raise(FIRQ()); + CC() &= ~EF; // Clear the EF flag. i.e. this only saves PC and CC + pushWordS(PC()); + pushS(CC()); + CC() |= (IF & FF); // Disable IRQ and FIRQ + jump(getWordPaged(0xff, FIRQvector)); +} + +// + int EightBit::mc6809::execute(uint8_t opcode) { const bool prefixed = m_prefix10 || m_prefix11; if (LIKELY(!prefixed)) {