diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index 8f27661..dd3c710 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -39,10 +39,12 @@ namespace EightBit { uint8_t& S() { return s; } uint8_t& P() { return p; } + PinLevel& NMI() { return m_nmiLine; } // In PinLevel& SO() { return m_soLine; } // In protected: - virtual void reset() final; + virtual void handleRESET() final; + virtual void handleIRQ() final; virtual uint8_t SUB(uint8_t operand, uint8_t data, int borrow = 0); uint8_t SBC(uint8_t operand, uint8_t data); @@ -55,6 +57,10 @@ namespace EightBit { uint8_t ADD_d(uint8_t operand, uint8_t data, int carry); private: + void handleNMI(); + void handleSO(); + void handleHALT(); + void interrupt(uint8_t vector); void adjustZero(uint8_t datum) { clearFlag(P(), ZF, datum); } @@ -324,6 +330,7 @@ namespace EightBit { uint8_t s = 0; // stack pointer uint8_t p = 0; // processor status + PinLevel m_nmiLine = Low; PinLevel m_soLine = Low; register16_t m_intermediate; diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index a37ae6e..029cd92 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -17,37 +17,56 @@ void EightBit::MOS6502::powerOn() { raise(SO()); } +void EightBit::MOS6502::handleSO() { + raise(SO()); + P() |= VF; +} + +void EightBit::MOS6502::handleRESET() { + Processor::handleRESET(); + jump(getWordPaged(0xff, RSTvector)); + addCycles(4); // ?? TBC +} + + +void EightBit::MOS6502::handleNMI() { + raise(NMI()); + interrupt(NMIvector); + addCycles(4); // ?? TBC +} + +void EightBit::MOS6502::handleIRQ() { + Processor::handleIRQ(); + interrupt(IRQvector); + addCycles(4); // ?? TBC +} + +void EightBit::MOS6502::handleHALT() { + execute(0xea); // NOP + addCycles(2); +} + int EightBit::MOS6502::step() { resetCycles(); - auto returned = 0; if (LIKELY(powered())) { ExecutingInstruction.fire(*this); if (UNLIKELY(lowered(SO()))) { - P() |= VF; - raise(SO()); + handleSO(); } - if (UNLIKELY(lowered(NMI()))) { - raise(NMI()); - interrupt(NMIvector); - returned = 4; // ?? TBC - } else if (UNLIKELY(lowered(INT()))) { - raise(INT()); - interrupt(IRQvector); - returned = 4; // ?? TBC + if (lowered(RESET())) { + handleRESET(); + } else if (UNLIKELY(lowered(NMI()))) { + handleNMI(); + } else if (UNLIKELY(lowered(IRQ()))) { + handleIRQ(); } else if (UNLIKELY(lowered(HALT()))) { - execute(0xea); // NOP - returned = 2; // + handleHALT(); } else { - returned = execute(fetchByte()); + execute(fetchByte()); } ExecutedInstruction.fire(*this); } - return returned; -} - -void EightBit::MOS6502::reset() { - Processor::reset(); - jump(getWordPaged(0xff, RSTvector)); + return cycles(); } void EightBit::MOS6502::interrupt(uint8_t vector) { diff --git a/M6502/test/Board.cpp b/M6502/test/Board.cpp index 4aa182a..56a4b68 100644 --- a/M6502/test/Board.cpp +++ b/M6502/test/Board.cpp @@ -21,7 +21,7 @@ void Board::initialise() { switch (m_configuration.getLoadMethod()) { case Configuration::LoadMethod::Ram: - m_ram.load(programPath, loadAddress); + m_ram.load(programPath, loadAddress.word); break; case Configuration::LoadMethod::Rom: // m_rom.load(programPath, loadAddress); @@ -58,7 +58,10 @@ void Board::initialise() { m_pollInterval = m_configuration.getPollInterval(); CPU().powerOn(); - CPU().PC().word = m_configuration.getStartAddress(); + + poke(0x00, 0x4c); + poke(0x01, m_configuration.getStartAddress().low); + poke(0x02, m_configuration.getStartAddress().high); } void Board::Cpu_ExecutingInstruction_Profile(const EightBit::MOS6502& cpu) { @@ -101,14 +104,14 @@ void Board::Cpu_ExecutingInstruction_Debug(EightBit::MOS6502& cpu) { } void Board::Memory_ReadingByte_Input(EightBit::EventArgs) { - if (ADDRESS().word == m_configuration.getInputAddress()) { + if (ADDRESS().word == m_configuration.getInputAddress().word) { if (!!DATA()) write(0); } } void Board::Memory_WrittenByte_Output(EightBit::EventArgs) { - if (ADDRESS().word == m_configuration.getOutputAddress()) { + if (ADDRESS().word == m_configuration.getOutputAddress().word) { #ifdef _MSC_VER _putch(DATA()); #endif @@ -125,6 +128,6 @@ void Board::Cpu_ExecutedInstruction_Poll(const EightBit::MOS6502& cpu) { void Board::pollKeyboard() { #ifdef _MSC_VER if (_kbhit()) - poke(m_configuration.getInputAddress(), _getch()); + poke(m_configuration.getInputAddress().word, _getch()); #endif } \ No newline at end of file diff --git a/M6502/test/Configuration.cpp b/M6502/test/Configuration.cpp deleted file mode 100644 index 297621d..0000000 --- a/M6502/test/Configuration.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "stdafx.h" -#include "Configuration.h" - -Configuration::Configuration() -: m_debugMode(false), - m_profileMode(false), - m_loadAddress(0x400), - m_startAddress(0x400), - m_allowInput(false), - m_inputAddress(0xbff0), - m_allowOutput(false), - m_outputAddress(0xbff0), - m_pollInterval(2000000 / 50), // 2Mhz, 50 times a second; - m_stopCondition(StopCondition::Loop), - m_romDirectory("roms"), - m_program("6502_functional_test.bin"), - m_loadMethod(LoadMethod::Ram) { -} diff --git a/M6502/test/Configuration.h b/M6502/test/Configuration.h index d28479e..0f5ed54 100644 --- a/M6502/test/Configuration.h +++ b/M6502/test/Configuration.h @@ -2,6 +2,7 @@ #include #include +#include class Configuration { public: @@ -15,7 +16,7 @@ public: Rom }; - Configuration(); + Configuration() = default; bool isDebugMode() const { return m_debugMode; } void setDebugMode(bool value) { m_debugMode = value; } @@ -23,14 +24,14 @@ public: bool isProfileMode() const { return m_profileMode; } void setProfileMode(bool value) { m_profileMode = value; } - uint16_t getLoadAddress() const { return m_loadAddress; } - uint16_t getStartAddress() const { return m_startAddress; } + EightBit::register16_t getLoadAddress() const { return m_loadAddress; } + EightBit::register16_t getStartAddress() const { return m_startAddress; } bool allowInput() const { return m_allowInput; } - uint16_t getInputAddress() const { return m_inputAddress; } + EightBit::register16_t getInputAddress() const { return m_inputAddress; } bool allowOutput() const { return m_allowOutput; } - uint16_t getOutputAddress() const { return m_outputAddress; } + EightBit::register16_t getOutputAddress() const { return m_outputAddress; } uint64_t getPollInterval() const { return m_pollInterval; } @@ -42,17 +43,17 @@ public: LoadMethod getLoadMethod() const { return m_loadMethod; } private: - bool m_debugMode; - bool m_profileMode; - uint16_t m_loadAddress; - uint16_t m_startAddress; - bool m_allowInput; - uint16_t m_inputAddress; - bool m_allowOutput; - uint16_t m_outputAddress; - uint64_t m_pollInterval; - StopCondition m_stopCondition; - std::string m_romDirectory; - std::string m_program; - LoadMethod m_loadMethod; + bool m_debugMode = false; + bool m_profileMode = false; + EightBit::register16_t m_loadAddress = 0x400; + EightBit::register16_t m_startAddress = 0x400; + bool m_allowInput = false; + EightBit::register16_t m_inputAddress = 0xbff0; + bool m_allowOutput = false; + EightBit::register16_t m_outputAddress = 0xbff0; + uint64_t m_pollInterval = 2000000 / 50; + StopCondition m_stopCondition = StopCondition::Loop; + std::string m_romDirectory = "roms"; + std::string m_program = "6502_functional_test.bin"; + LoadMethod m_loadMethod = LoadMethod::Ram; }; diff --git a/M6502/test/test_M6502.vcxproj b/M6502/test/test_M6502.vcxproj index 06139dc..bc88bab 100644 --- a/M6502/test/test_M6502.vcxproj +++ b/M6502/test/test_M6502.vcxproj @@ -154,7 +154,6 @@ - Create Create diff --git a/M6502/test/test_M6502.vcxproj.filters b/M6502/test/test_M6502.vcxproj.filters index ee00c3a..2bd3957 100644 --- a/M6502/test/test_M6502.vcxproj.filters +++ b/M6502/test/test_M6502.vcxproj.filters @@ -31,8 +31,5 @@ Source Files - - Source Files - \ No newline at end of file diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index e6839f8..3973ea9 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -70,10 +70,11 @@ namespace EightBit { uint8_t& DP() { return m_dp; } uint8_t& CC() { return m_cc; } - PinLevel& IRQ() { return INT(); } - PinLevel& FIRQ() { return m_firq; } + PinLevel& NMI() { return m_nmiLine; } // In + PinLevel& FIRQ() { return m_firqLine; } // In protected: + virtual void powerOn() final; // Default push/pop handlers @@ -83,7 +84,7 @@ namespace EightBit { // Interrupt (etc.) handlers virtual void handleRESET() final; - virtual void handleNMI() final; + virtual void handleIRQ() final; private: const uint8_t RESETvector = 0xfe; // RESET vector @@ -124,7 +125,7 @@ namespace EightBit { // Interrupt (etc.) handlers - void handleIRQ(); + void handleNMI(); void handleFIRQ(); // Execution helpers @@ -322,7 +323,8 @@ namespace EightBit { uint8_t m_dp; uint8_t m_cc; - PinLevel m_firq; + PinLevel m_nmiLine = Low; + PinLevel m_firqLine = Low; bool m_prefix10 = false; bool m_prefix11 = false; diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index bba3e53..8959941 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -7,6 +7,12 @@ EightBit::mc6809::mc6809(Bus& bus) : BigEndianProcessor(bus) {} +void EightBit::mc6809::powerOn() { + Processor::powerOn(); + raise(NMI()); + raise(FIRQ()); +} + int EightBit::mc6809::step() { resetCycles(); if (LIKELY(powered())) { @@ -33,21 +39,21 @@ void EightBit::mc6809::handleRESET() { Processor::handleRESET(); raise(NMI()); DP() = 0; - setFlag(CC(), IF | FF); + setFlag(CC(), IF | FF); // Disable all IRQs jump(getWordPaged(0xff, RESETvector)); } void EightBit::mc6809::handleNMI() { - Processor::handleNMI(); + raise(NMI()); saveEntireRegisterState(); jump(getWordPaged(0xff, NMIvector)); addCycles(21); } void EightBit::mc6809::handleIRQ() { - Processor::handleINT(); // Synonymous + Processor::handleIRQ(); saveEntireRegisterState(); - setFlag(CC(), IF); + setFlag(CC(), IF); // Disable IRQ jump(getWordPaged(0xff, IRQvector)); addCycles(21); } @@ -57,7 +63,7 @@ void EightBit::mc6809::handleFIRQ() { clearFlag(CC(), EF); pushWordS(PC()); pushS(CC()); - setFlag(CC(), IF | FF); + setFlag(CC(), IF | FF); // Disable all IRQs jump(getWordPaged(0xff, FIRQvector)); addCycles(12); } @@ -65,17 +71,12 @@ void EightBit::mc6809::handleFIRQ() { // int EightBit::mc6809::execute(uint8_t opcode) { - const bool prefixed = m_prefix10 || m_prefix11; - if (LIKELY(!prefixed)) { + if (m_prefix10) + execute10(opcode); + else if (m_prefix11) + execute11(opcode); + else executeUnprefixed(opcode); - } else { - if (m_prefix10) - execute10(opcode); - else if (m_prefix11) - execute11(opcode); - else - UNREACHABLE; - } assert(cycles() > 0); return cycles(); } diff --git a/Ricoh2A03/inc/Ricoh2A03.h b/Ricoh2A03/inc/Ricoh2A03.h index fab8bc5..4b4e447 100644 --- a/Ricoh2A03/inc/Ricoh2A03.h +++ b/Ricoh2A03/inc/Ricoh2A03.h @@ -10,8 +10,6 @@ namespace EightBit { Ricoh2A03(Bus& bus); virtual ~Ricoh2A03() = default; - int clockCycles() const { return cycles(); } - protected: virtual uint8_t SUB(uint8_t operand, uint8_t data, int borrow) final; virtual uint8_t ADD(uint8_t operand, uint8_t data, int carry) final; diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index b9e4a08..de65207 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -51,6 +51,7 @@ namespace EightBit { Signal ExecutingInstruction; Signal ExecutedInstruction; + PinLevel& NMI() { return m_nmiLine; } // In PinLevel& M1() { return m_m1Line; } // Out virtual int execute(uint8_t opcode) final; @@ -86,10 +87,10 @@ namespace EightBit { protected: virtual void handleRESET() final; - virtual void handleNMI() final; virtual void handleINT() final; private: + PinLevel m_nmiLine = Low; PinLevel m_m1Line = Low; InputOutput& m_ports; @@ -120,6 +121,8 @@ namespace EightBit { int8_t m_displacement = 0; bool m_displaced = false; + void handleNMI(); + uint16_t displacedAddress() { assert(m_displaced); return MEMPTR().word = (m_prefixDD ? IX() : IY()).word + m_displacement; diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 7018cf6..3b3c5cc 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -51,7 +51,7 @@ void EightBit::Z80::handleRESET() { } void EightBit::Z80::handleNMI() { - Processor::handleNMI(); + raise(NMI()); raise(HALT()); IFF1() = false; restart(0x66); diff --git a/inc/Processor.h b/inc/Processor.h index 1b6c941..e0a41d5 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -74,7 +74,7 @@ namespace EightBit { PinLevel& RESET() { return m_resetLine; } PinLevel& HALT() { return m_haltLine; } PinLevel& INT() { return m_intLine; } - PinLevel& NMI() { return m_nmiLine; } + PinLevel& IRQ() { return INT(); } // Synonym PinLevel& POWER() { return m_powerLine; } bool powered() { return raised(POWER()); } @@ -84,9 +84,10 @@ namespace EightBit { int run(int limit); virtual int step() = 0; - virtual int execute(uint8_t opcode) = 0; + int cycles() const { return m_cycles; } + protected: static void clearFlag(uint8_t& f, const int flag) { f &= ~flag; } static void setFlag(uint8_t& f, const int flag) { f |= flag; } @@ -107,8 +108,8 @@ namespace EightBit { void proceed() { ++PC(); raise(HALT()); } virtual void handleRESET(); - virtual void handleNMI(); virtual void handleINT(); + virtual void handleIRQ(); uint8_t getBytePaged(uint8_t page, uint8_t offset) { return BUS().read(register16_t(offset, page)); @@ -159,7 +160,6 @@ namespace EightBit { jump(popWord()); } - int cycles() const { return m_cycles; } void resetCycles() { m_cycles = 0; } void addCycles(const int extra) { m_cycles += extra; } void addCycle() { ++m_cycles; } @@ -170,7 +170,6 @@ namespace EightBit { register16_t m_pc; PinLevel m_intLine = Low; - PinLevel m_nmiLine = Low; PinLevel m_haltLine = Low; PinLevel m_resetLine = Low; PinLevel m_powerLine = Low; diff --git a/src/Processor.cpp b/src/Processor.cpp index cb0af3a..4eaca27 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -9,7 +9,6 @@ void EightBit::Processor::powerOn() { raise(RESET()); raise(HALT()); raise(INT()); - raise(NMI()); raise(POWER()); } @@ -18,14 +17,14 @@ void EightBit::Processor::handleRESET() { PC() = 0; } -void EightBit::Processor::handleNMI() { - raise(NMI()); -} - void EightBit::Processor::handleINT() { raise(INT()); } +void EightBit::Processor::handleIRQ() { + raise(IRQ()); +} + int EightBit::Processor::run(const int limit) { int current = 0; while (LIKELY(powered()) && current < limit)