From 92d23d82d6bff7271e1e0a146c9f96139be855ec Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Mon, 14 Jan 2019 02:10:17 +0000 Subject: [PATCH] Start big refactor of device/CPU pin usage (to allow pin events throughout). Signed-off-by: Adrian Conlon --- Intel8080/inc/Intel8080.h | 1 + Intel8080/test/Board.cpp | 23 +++-- Intel8080/test/Board.h | 7 +- LR35902/fusetest_LR35902/FuseTestRunner.cpp | 17 ++-- LR35902/fusetest_LR35902/FuseTestRunner.h | 7 +- LR35902/inc/GameBoyBus.h | 4 +- LR35902/src/GameBoyBus.cpp | 12 +-- M6502/inc/mos6502.h | 43 +++++++-- M6502/src/mos6502.cpp | 57 ++++++++---- M6502/test/Board.cpp | 19 ++-- M6502/test/Board.h | 7 +- MC6809/inc/mc6809.h | 54 ++++++++++-- MC6809/src/Disassembly.cpp | 2 +- MC6809/src/mc6809.cpp | 92 +++++++++++++++----- MC6809/test/Board.cpp | 37 ++++---- MC6809/test/Board.h | 21 +++-- MC6809/unittest/Board.cpp | 23 +++-- MC6809/unittest/Board.h | 5 +- MC6809/unittest/mc6809_tests.cpp | 48 +++++----- MC6850/inc/MC6850.h | 6 +- MC6850/src/MC6850.cpp | Bin 7250 -> 6634 bytes Z80/fusetest_Z80/FuseTestRunner.cpp | 19 ++-- Z80/fusetest_Z80/FuseTestRunner.h | 7 +- Z80/inc/Z80.h | 20 ++++- Z80/src/Z80.cpp | 59 ++++++++----- Z80/test/Board.cpp | 26 +++--- Z80/test/Board.h | 7 +- inc/Bus.h | 6 +- inc/Device.h | 14 +-- inc/IntelProcessor.h | 21 ++++- inc/Processor.h | 27 +++--- inc/TestHarness.h | 3 +- src/Bus.cpp | 6 +- src/Device.cpp | 8 +- src/IntelProcessor.cpp | 20 ++++- src/Processor.cpp | 28 +++--- 36 files changed, 508 insertions(+), 248 deletions(-) diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index 797ba31..fee414e 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/Intel8080/test/Board.cpp b/Intel8080/test/Board.cpp index cab3490..93d86cf 100644 --- a/Intel8080/test/Board.cpp +++ b/Intel8080/test/Board.cpp @@ -10,15 +10,16 @@ Board::Board(const Configuration& configuration) m_disassembler(*this) { } -void Board::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); - CPU().reset(); +void Board::raisePOWER() { + EightBit::Bus::raisePOWER(); + CPU().raisePOWER(); + CPU().raiseRESET(); + CPU().raiseINT(); } -void Board::powerOff() { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Board::lowerPOWER() { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Board::initialise() { @@ -30,6 +31,10 @@ void Board::initialise() { m_ram.load(romDirectory + "/8080EX1.COM", 0x100); // Cringle/Bartholomew //m_ram.load(romDirectory + "/CPUTEST.COM", 0x100); // SuperSoft diagnostics + m_cpu.LoweredHALT.connect([this](EightBit::EventArgs) { + lowerPOWER(); + }); + m_cpu.ExecutingInstruction.connect(std::bind(&Board::Cpu_ExecutingInstruction_Cpm, this, std::placeholders::_1)); if (m_configuration.isProfileMode()) { @@ -49,8 +54,8 @@ void Board::initialise() { void Board::Cpu_ExecutingInstruction_Cpm(EightBit::Intel8080& cpu) { switch (cpu.PC().word) { case 0x0: // CP/M warm start - if (++m_warmstartCount == 3) { - powerOff(); + if (++m_warmstartCount == 2) { + lowerPOWER(); if (m_configuration.isProfileMode()) { m_profiler.dump(); } diff --git a/Intel8080/test/Board.h b/Intel8080/test/Board.h index 697d196..6b5f660 100644 --- a/Intel8080/test/Board.h +++ b/Intel8080/test/Board.h @@ -17,11 +17,12 @@ public: EightBit::Intel8080& CPU() { return m_cpu; } const EightBit::Intel8080& CPU() const { return m_cpu; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; + + virtual void initialise() final; protected: - virtual void initialise() final; virtual EightBit::MemoryMapping mapping(uint16_t address) final { return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; } diff --git a/LR35902/fusetest_LR35902/FuseTestRunner.cpp b/LR35902/fusetest_LR35902/FuseTestRunner.cpp index c1a5c70..65ed458 100644 --- a/LR35902/fusetest_LR35902/FuseTestRunner.cpp +++ b/LR35902/fusetest_LR35902/FuseTestRunner.cpp @@ -9,16 +9,18 @@ Fuse::TestRunner::TestRunner(const Test& test, const ExpectedTestResult& expecte // -void Fuse::TestRunner::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); +void Fuse::TestRunner::raisePOWER() { + EightBit::Bus::raisePOWER(); + CPU().raisePOWER(); + CPU().raiseRESET(); + CPU().raiseINT(); initialiseRegisters(); initialiseMemory(); } -void Fuse::TestRunner::powerOff() { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Fuse::TestRunner::lowerPOWER() { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Fuse::TestRunner::initialise() { @@ -182,7 +184,8 @@ void Fuse::TestRunner::checkMemory() { void Fuse::TestRunner::run() { - powerOn(); + raisePOWER(); + initialise(); auto allowedCycles = m_test.registerState.tstates; try { CPU().run(allowedCycles); diff --git a/LR35902/fusetest_LR35902/FuseTestRunner.h b/LR35902/fusetest_LR35902/FuseTestRunner.h index 4ab5c86..64f8a20 100644 --- a/LR35902/fusetest_LR35902/FuseTestRunner.h +++ b/LR35902/fusetest_LR35902/FuseTestRunner.h @@ -21,7 +21,6 @@ namespace Fuse { EightBit::Ram m_ram = 0x10000; - void initialise(); void initialiseRegisters(); void initialiseMemory(); @@ -47,7 +46,9 @@ namespace Fuse { bool failed() const { return m_failed; } bool unimplemented() const { return m_unimplemented; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; + + void initialise(); }; } \ No newline at end of file diff --git a/LR35902/inc/GameBoyBus.h b/LR35902/inc/GameBoyBus.h index b783750..fe8574c 100644 --- a/LR35902/inc/GameBoyBus.h +++ b/LR35902/inc/GameBoyBus.h @@ -36,8 +36,8 @@ namespace EightBit { Bus() noexcept; - virtual void powerOn() override; - virtual void powerOff() override; + virtual void raisePOWER() override; + virtual void lowerPOWER() override; auto& CPU() { return m_cpu; } auto& VRAM() { return m_videoRam; } diff --git a/LR35902/src/GameBoyBus.cpp b/LR35902/src/GameBoyBus.cpp index 1f2d567..40923ae 100644 --- a/LR35902/src/GameBoyBus.cpp +++ b/LR35902/src/GameBoyBus.cpp @@ -8,15 +8,15 @@ EightBit::GameBoy::Bus::Bus() noexcept WrittenByte.connect(std::bind(&GameBoy::Bus::Bus_WrittenByte, this, std::placeholders::_1)); } -void EightBit::GameBoy::Bus::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); +void EightBit::GameBoy::Bus::raisePOWER() { + EightBit::Bus::raisePOWER(); + CPU().raisePOWER(); reset(); } -void EightBit::GameBoy::Bus::powerOff() { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void EightBit::GameBoy::Bus::lowerPOWER() { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void EightBit::GameBoy::Bus::reset() { diff --git a/M6502/inc/mos6502.h b/M6502/inc/mos6502.h index e29249e..9b16e3d 100644 --- a/M6502/inc/mos6502.h +++ b/M6502/inc/mos6502.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace EightBit { @@ -30,9 +31,30 @@ namespace EightBit { Signal ExecutingInstruction; Signal ExecutedInstruction; - virtual int execute() final; - virtual int step() final; - virtual void powerOn() final; + Signal RaisedNMI; + Signal LoweredNMI; + + Signal RaisedSO; + Signal LoweredSO; + + Signal RaisedSYNC; + Signal LoweredSYNC; + + Signal RaisedRDY; + Signal LoweredRDY; + + int execute() final; + int step() final; + void raisePOWER() final; + + virtual void lowerNMI(); + virtual void raiseNMI(); + + virtual void lowerSO(); + virtual void raiseSO(); + + virtual void lowerRDY(); + virtual void raiseRDY(); auto& X() { return x; } auto& Y() { return y; } @@ -48,8 +70,11 @@ namespace EightBit { auto& RDY() { return m_rdyLine; } // In protected: + virtual void lowerSYNC(); + virtual void raiseSYNC(); + virtual void handleRESET() final; - virtual void handleIRQ() final; + virtual void handleINT() final; virtual void busWrite() final; virtual uint8_t busRead() final; @@ -186,15 +211,15 @@ namespace EightBit { uint8_t s = 0; // stack pointer uint8_t p = 0; // processor status - PinLevel m_nmiLine = PinLevel::Low; // Active low - PinLevel m_soLine = PinLevel::Low; // Active low - PinLevel m_syncLine = PinLevel::Low; // Active high - PinLevel m_rdyLine = PinLevel::Low; // Active high + PinLevel m_nmiLine = PinLevel::Low; // In, Active low + PinLevel m_soLine = PinLevel::Low; // In, Active low + PinLevel m_syncLine = PinLevel::Low; // Out, Active high + PinLevel m_rdyLine = PinLevel::Low; // In, Active high register16_t m_intermediate; bool m_handlingRESET = false; bool m_handlingNMI = false; - bool m_handlingIRQ = false; + bool m_handlingINT = false; }; } \ No newline at end of file diff --git a/M6502/src/mos6502.cpp b/M6502/src/mos6502.cpp index af1ab4a..703a071 100644 --- a/M6502/src/mos6502.cpp +++ b/M6502/src/mos6502.cpp @@ -4,18 +4,45 @@ EightBit::MOS6502::MOS6502(Bus& bus) : LittleEndianProcessor(bus) {} -void EightBit::MOS6502::powerOn() { - - LittleEndianProcessor::powerOn(); - +void EightBit::MOS6502::raisePOWER() { + LittleEndianProcessor::raisePOWER(); X() = Bit7; Y() = 0; A() = 0; P() = RF; S() = Mask8; + lowerSYNC(); +} +void EightBit::MOS6502::lowerNMI() { + lower(NMI()); +} + +void EightBit::MOS6502::raiseNMI() { raise(NMI()); +} + +void EightBit::MOS6502::lowerSO() { + lower(SO()); +} + +void EightBit::MOS6502::raiseSO() { raise(SO()); +} + +void EightBit::MOS6502::lowerSYNC() { + lower(SYNC()); +} + +void EightBit::MOS6502::raiseSYNC() { + raise(SYNC()); +} + +void EightBit::MOS6502::lowerRDY() { + lower(RDY()); +} + +void EightBit::MOS6502::raiseRDY() { raise(RDY()); } @@ -27,14 +54,14 @@ int EightBit::MOS6502::step() { if (UNLIKELY(lowered(SO()))) handleSO(); if (LIKELY(raised(RDY()))) { - lower(SYNC()); // Instruction fetch beginning + lowerSYNC(); // Instruction fetch beginning opcode() = BUS().read(PC()++); // can't use fetchByte if (UNLIKELY(lowered(RESET()))) handleRESET(); else if (UNLIKELY(lowered(NMI()))) handleNMI(); - else if (UNLIKELY(lowered(IRQ()) && !interruptMasked())) - handleIRQ(); + else if (UNLIKELY(lowered(INT()) && !interruptMasked())) + handleINT(); execute(); } } @@ -45,33 +72,33 @@ int EightBit::MOS6502::step() { // Interrupt (etc.) handlers void EightBit::MOS6502::handleSO() { - raise(SO()); + raiseSO(); P() |= VF; } void EightBit::MOS6502::handleRESET() { - raise(RESET()); + raiseRESET(); m_handlingRESET = true; opcode() = 0x00; // BRK } void EightBit::MOS6502::handleNMI() { - raise(NMI()); + raiseNMI(); m_handlingNMI = true; opcode() = 0x00; // BRK } -void EightBit::MOS6502::handleIRQ() { +void EightBit::MOS6502::handleINT() { raise(INT()); - m_handlingIRQ = true; + m_handlingINT = true; opcode() = 0x00; // BRK } void EightBit::MOS6502::interrupt() { const bool reset = m_handlingRESET; const bool nmi = m_handlingNMI; - const bool irq = m_handlingIRQ; + const bool irq = m_handlingINT; const bool hardware = nmi || irq || reset; const bool software = !hardware; if (reset) { @@ -85,7 +112,7 @@ void EightBit::MOS6502::interrupt() { setFlag(P(), IF); // Disable IRQ const uint8_t vector = reset ? RSTvector : (nmi ? NMIvector : IRQvector); jump(getWordPaged(0xff, vector)); - m_handlingRESET = m_handlingNMI = m_handlingIRQ = false; + m_handlingRESET = m_handlingNMI = m_handlingINT = false; } // @@ -104,7 +131,7 @@ uint8_t EightBit::MOS6502::busRead() { int EightBit::MOS6502::execute() { - raise(SYNC()); // Instruction fetch has now completed + raiseSYNC(); // Instruction fetch has now completed switch (opcode()) { diff --git a/M6502/test/Board.cpp b/M6502/test/Board.cpp index c265516..6ed4310 100644 --- a/M6502/test/Board.cpp +++ b/M6502/test/Board.cpp @@ -10,14 +10,19 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration) {} -void Board::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); +void Board::raisePOWER() { + EightBit::Bus::raisePOWER(); + CPU().raisePOWER(); + CPU().raiseRESET(); + CPU().raiseINT(); + CPU().raiseNMI(); + CPU().raiseSO(); + CPU().raiseRDY(); } -void Board::powerOff() { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Board::lowerPOWER() { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Board::initialise() { @@ -53,7 +58,7 @@ void Board::initialise() { if (m_oldPC != pc) { m_oldPC = pc; } else { - powerOff(); + lowerPOWER(); auto test = peek(0x0200); std::cout << std::endl << "** Test=" << std::hex << (int)test; } diff --git a/M6502/test/Board.h b/M6502/test/Board.h index 14efda5..ab427e2 100644 --- a/M6502/test/Board.h +++ b/M6502/test/Board.h @@ -17,11 +17,12 @@ public: EightBit::MOS6502& CPU() { return m_cpu; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; + + virtual void initialise() final; protected: - virtual void initialise() final; virtual EightBit::MemoryMapping mapping(uint16_t address) final { return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; } diff --git a/MC6809/inc/mc6809.h b/MC6809/inc/mc6809.h index c04c76c..965b060 100644 --- a/MC6809/inc/mc6809.h +++ b/MC6809/inc/mc6809.h @@ -57,10 +57,34 @@ namespace EightBit { Signal ExecutingInstruction; Signal ExecutedInstruction; + Signal RaisedNMI; + Signal LoweredNMI; + + Signal RaisedFIRQ; + Signal LoweredFIRQ; + + Signal RaisedHALT; + Signal LoweredHALT; + + Signal RaisedBA; + Signal LoweredBA; + + Signal RaisedBS; + Signal LoweredBS; + virtual int execute() final; virtual int step() final; - virtual void powerOn() final; + virtual void raisePOWER() final; + + virtual void lowerNMI(); + virtual void raiseNMI(); + + virtual void lowerFIRQ(); + virtual void raiseFIRQ(); + + virtual void lowerHALT(); + virtual void raiseHALT(); auto& D() { return m_d; } auto& A() { return D().high; } @@ -75,8 +99,9 @@ namespace EightBit { auto& CC() { return m_cc; } const auto& CC() const { return m_cc; } - auto& NMI() { return m_nmiLine; } // In - auto& FIRQ() { return m_firqLine; } // In + [[nodiscard]] auto& NMI() noexcept { return m_nmiLine; } // In + [[nodiscard]] auto& FIRQ() noexcept { return m_firqLine; } // In + [[nodiscard]] auto& HALT() noexcept { return m_haltLine; } // In // |---------------|-----------------------------------| // | MPU State | | @@ -92,6 +117,10 @@ namespace EightBit { auto& BA() { return m_baLine; } // Out auto& BS() { return m_bsLine; } // Out + [[nodiscard]] auto halted() noexcept { return lowered(HALT()); } + void halt() noexcept { --PC(); lowerHALT(); } + void proceed() noexcept { ++PC(); raiseHALT(); } + protected: // Default push/pop handlers @@ -101,7 +130,15 @@ namespace EightBit { // Interrupt (etc.) handlers virtual void handleRESET() final; - virtual void handleIRQ() final; + virtual void handleINT() final; + + // Line handlers + + virtual void lowerBA(); + virtual void raiseBA(); + + virtual void lowerBS(); + virtual void raiseBS(); private: const uint8_t RESETvector = 0xfe; // RESET vector @@ -368,11 +405,12 @@ namespace EightBit { uint8_t m_dp = 0; uint8_t m_cc = 0; - PinLevel m_nmiLine = PinLevel::Low; - PinLevel m_firqLine = PinLevel::Low; + PinLevel m_nmiLine = PinLevel::Low; // In, Active low + PinLevel m_firqLine = PinLevel::Low; // In, Active low + PinLevel m_haltLine = PinLevel::Low; // In, Active low - PinLevel m_baLine = PinLevel::Low; - PinLevel m_bsLine = PinLevel::Low; + PinLevel m_baLine = PinLevel::Low; // Out, Bus available + PinLevel m_bsLine = PinLevel::Low; // Out, Bus status bool m_prefix10 = false; bool m_prefix11 = false; diff --git a/MC6809/src/Disassembly.cpp b/MC6809/src/Disassembly.cpp index 324382a..6825835 100644 --- a/MC6809/src/Disassembly.cpp +++ b/MC6809/src/Disassembly.cpp @@ -108,7 +108,7 @@ bool EightBit::Disassembly::ignore() { || CPU().lowered(CPU().RESET()) || CPU().lowered(CPU().NMI()) || (CPU().lowered(CPU().FIRQ()) && !(CPU().CC() & mc6809::FF)) - || (CPU().lowered(CPU().IRQ()) && !(CPU().CC() & mc6809::IF)); + || (CPU().lowered(CPU().INT()) && !(CPU().CC() & mc6809::IF)); } std::string EightBit::Disassembly::disassemble(uint16_t current) { diff --git a/MC6809/src/mc6809.cpp b/MC6809/src/mc6809.cpp index 99aaae0..562999a 100644 --- a/MC6809/src/mc6809.cpp +++ b/MC6809/src/mc6809.cpp @@ -7,10 +7,60 @@ EightBit::mc6809::mc6809(Bus& bus) : BigEndianProcessor(bus) {} -void EightBit::mc6809::powerOn() { - BigEndianProcessor::powerOn(); +void EightBit::mc6809::raisePOWER() { + BigEndianProcessor::raisePOWER(); + lowerBA(); + lowerBS(); +} + +void EightBit::mc6809::lowerNMI() { + lower(NMI()); + LoweredNMI.fire(EventArgs::empty()); +} + +void EightBit::mc6809::raiseNMI() { + raise(NMI()); + RaisedNMI.fire(EventArgs::empty()); +} + +void EightBit::mc6809::lowerFIRQ() { + lower(FIRQ()); + LoweredFIRQ.fire(EventArgs::empty()); +} + +void EightBit::mc6809::raiseFIRQ() { + raise(FIRQ()); + RaisedFIRQ.fire(EventArgs::empty()); +} + +void EightBit::mc6809::lowerHALT() { + lower(HALT()); + LoweredHALT.fire(EventArgs::empty()); +} + +void EightBit::mc6809::raiseHALT() { + raise(HALT()); + RaisedHALT.fire(EventArgs::empty()); +} + +void EightBit::mc6809::lowerBA() { lower(BA()); + LoweredNMI.fire(EventArgs::empty()); +} + +void EightBit::mc6809::raiseBA() { + raise(BA()); + RaisedBA.fire(EventArgs::empty()); +} + +void EightBit::mc6809::lowerBS() { lower(BS()); + LoweredBS.fire(EventArgs::empty()); +} + +void EightBit::mc6809::raiseBS() { + raise(BS()); + RaisedBS.fire(EventArgs::empty()); } int EightBit::mc6809::step() { @@ -26,8 +76,8 @@ int EightBit::mc6809::step() { handleNMI(); else if (UNLIKELY(lowered(FIRQ()) && !fastInterruptMasked())) handleFIRQ(); - else if (UNLIKELY(lowered(IRQ()) && !interruptMasked())) - handleIRQ(); + else if (UNLIKELY(lowered(INT()) && !interruptMasked())) + handleINT(); else Processor::execute(fetchByte()); } @@ -38,15 +88,15 @@ int EightBit::mc6809::step() { // Interrupt (etc.) handlers void EightBit::mc6809::handleHALT() { - raise(BA()); - raise(BS()); + raiseBA(); + raiseBS(); } void EightBit::mc6809::handleRESET() { BigEndianProcessor::handleRESET(); - raise(NMI()); - lower(BA()); - raise(BS()); + raiseNMI(); + lowerBA(); + raiseBS(); DP() = 0; setFlag(CC(), IF); // Disable IRQ setFlag(CC(), FF); // Disable FIRQ @@ -55,9 +105,9 @@ void EightBit::mc6809::handleRESET() { } void EightBit::mc6809::handleNMI() { - raise(NMI()); - lower(BA()); - raise(BS()); + raiseNMI(); + lowerBA(); + raiseBS(); saveEntireRegisterState(); setFlag(CC(), IF); // Disable IRQ setFlag(CC(), FF); // Disable FIRQ @@ -65,10 +115,10 @@ void EightBit::mc6809::handleNMI() { tick(12); } -void EightBit::mc6809::handleIRQ() { - BigEndianProcessor::handleIRQ(); - lower(BA()); - raise(BS()); +void EightBit::mc6809::handleINT() { + BigEndianProcessor::handleINT(); + lowerBA(); + raiseBS(); saveEntireRegisterState(); setFlag(CC(), IF); // Disable IRQ jump(getWordPaged(0xff, IRQvector)); @@ -76,9 +126,9 @@ void EightBit::mc6809::handleIRQ() { } void EightBit::mc6809::handleFIRQ() { - raise(FIRQ()); - lower(BA()); - raise(BS()); + raiseFIRQ(); + lowerBA(); + raiseBS(); savePartialRegisterState(); setFlag(CC(), IF); // Disable IRQ setFlag(CC(), FF); // Disable FIRQ @@ -89,8 +139,8 @@ void EightBit::mc6809::handleFIRQ() { // int EightBit::mc6809::execute() { - lower(BA()); - lower(BS()); + lowerBA(); + lowerBS(); const bool prefixed = m_prefix10 || m_prefix11; const bool unprefixed = !prefixed; if (unprefixed) { diff --git a/MC6809/test/Board.cpp b/MC6809/test/Board.cpp index 8b86e34..cefe5a5 100644 --- a/MC6809/test/Board.cpp +++ b/MC6809/test/Board.cpp @@ -4,29 +4,31 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration) {} -void Board::powerOn() { +void Board::raisePOWER() { - EightBit::Bus::powerOn(); + EightBit::Bus::raisePOWER(); // Get the CPU ready for action - CPU().powerOn(); - CPU().raise(CPU().NMI()); - CPU().raise(CPU().FIRQ()); - CPU().reset(); + CPU().raisePOWER(); + CPU().lowerRESET(); + CPU().raiseINT(); + CPU().raiseNMI(); + CPU().raiseFIRQ(); + CPU().raiseHALT(); // Get the ACIA ready for action ADDRESS() = 0b1010000000000000; ACIA().DATA() = EightBit::mc6850::CR0 | EightBit::mc6850::CR1; // Master reset updateAciaPinsWrite(); ACIA().lower(ACIA().CTS()); - ACIA().powerOn(); + ACIA().raisePOWER(); accessAcia(); } -void Board::powerOff() { - ACIA().powerOff(); - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Board::lowerPOWER() { + ACIA().lowerPOWER(); + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Board::initialise() { @@ -88,7 +90,7 @@ void Board::initialise() { assert(cpu.cycles() > 0); m_totalCycleCount += cpu.cycles(); if (m_totalCycleCount > Configuration::TerminationCycles) - powerOff(); + lowerPOWER(); }); } } @@ -107,13 +109,12 @@ EightBit::MemoryMapping Board::mapping(uint16_t address) { return { m_rom, 0xc000, EightBit::Chip::Mask16, EightBit::MemoryMapping::AccessLevel::ReadOnly }; } -void Board::updateAciaPins(const EightBit::Chip::PinLevel rw) { - ACIA().RW() = rw; +void Board::updateAciaPins() { ACIA().DATA() = DATA(); - ACIA().match(ACIA().RS(), ADDRESS().word & EightBit::Chip::Bit0); - ACIA().match(ACIA().CS0(), ADDRESS().word & EightBit::Chip::Bit15); - ACIA().match(ACIA().CS1(), ADDRESS().word & EightBit::Chip::Bit13); - ACIA().match(ACIA().CS2(), ADDRESS().word & EightBit::Chip::Bit14); + ADDRESS().word & EightBit::Chip::Bit0 ? ACIA().raise(ACIA().RS()) : ACIA().lower(ACIA().RS()); + ADDRESS().word & EightBit::Chip::Bit15 ? ACIA().raise(ACIA().CS0()) : ACIA().lower(ACIA().CS0()); + ADDRESS().word & EightBit::Chip::Bit13 ? ACIA().raise(ACIA().CS1()) : ACIA().lower(ACIA().CS1()); + ADDRESS().word & EightBit::Chip::Bit14 ? ACIA().raise(ACIA().CS2()) : ACIA().lower(ACIA().CS2()); } bool Board::accessAcia() { diff --git a/MC6809/test/Board.h b/MC6809/test/Board.h index 0d3e6dd..e4898e1 100644 --- a/MC6809/test/Board.h +++ b/MC6809/test/Board.h @@ -19,11 +19,12 @@ public: auto& CPU() { return m_cpu; } auto& ACIA() { return m_acia; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; + + virtual void initialise() final; protected: - virtual void initialise() final; virtual EightBit::MemoryMapping mapping(uint16_t address) final; private: @@ -46,9 +47,17 @@ private: bool m_ignoreDisassembly = false; // Use the bus data to update the ACIA access/address pins - void updateAciaPinsRead() { updateAciaPins(EightBit::Chip::PinLevel::High); } - void updateAciaPinsWrite() { updateAciaPins(EightBit::Chip::PinLevel::Low); } - void updateAciaPins(EightBit::Chip::PinLevel rw); + void updateAciaPinsRead() { + ACIA().raise(ACIA().RW()); + updateAciaPins(); + } + + void updateAciaPinsWrite() { + ACIA().lower(ACIA().RW()); + updateAciaPins(); + } + + void updateAciaPins(); bool accessAcia(); }; diff --git a/MC6809/unittest/Board.cpp b/MC6809/unittest/Board.cpp index a9716a8..e93dd67 100644 --- a/MC6809/unittest/Board.cpp +++ b/MC6809/unittest/Board.cpp @@ -6,17 +6,22 @@ Board::Board() m_disassembler(*this, m_cpu) { } -void Board::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); - CPU().raise(CPU().NMI()); - CPU().raise(CPU().FIRQ()); - CPU().reset(); +void Board::raisePOWER() { + EightBit::Bus::raisePOWER(); + + CPU().raisePOWER(); + + CPU().lowerRESET(); + CPU().raiseINT(); + + CPU().raiseNMI(); + CPU().raiseFIRQ(); + CPU().raiseHALT(); } -void Board::powerOff() { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Board::lowerPOWER() { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Board::initialise() { diff --git a/MC6809/unittest/Board.h b/MC6809/unittest/Board.h index fc8bba2..edae038 100644 --- a/MC6809/unittest/Board.h +++ b/MC6809/unittest/Board.h @@ -11,11 +11,12 @@ public: EightBit::mc6809& CPU() { return m_cpu; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; protected: virtual void initialise() final; + virtual EightBit::MemoryMapping mapping(uint16_t address) final; private: diff --git a/MC6809/unittest/mc6809_tests.cpp b/MC6809/unittest/mc6809_tests.cpp index 7bd5862..644ac33 100644 --- a/MC6809/unittest/mc6809_tests.cpp +++ b/MC6809/unittest/mc6809_tests.cpp @@ -9,7 +9,7 @@ TEST_CASE("Add Accumulator B to Index Register X Unsigned", "[ABX]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -70,7 +70,7 @@ TEST_CASE("Add Accumulator B to Index Register X Unsigned", "[ABX]") { TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -153,7 +153,7 @@ TEST_CASE("Add Memory Plus Carry to Accumulator", "[ADC][ADCA]") { TEST_CASE("Add Memory to Accumulator", "[ADD][ADDA][ADDB][ADDD]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -350,7 +350,7 @@ TEST_CASE("Add Memory to Accumulator", "[ADD][ADDA][ADDB][ADDD]") { TEST_CASE("Logical AND Accumulator", "[AND][ANDA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -370,7 +370,7 @@ TEST_CASE("Logical AND Accumulator", "[AND][ANDA]") { TEST_CASE("Shift Accumulator or Memory Byte Left", "[ASL][ASLA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -389,7 +389,7 @@ TEST_CASE("Shift Accumulator or Memory Byte Left", "[ASL][ASLA]") { TEST_CASE("Shift Accumulator or Memory Byte Right", "[ASR][ASRA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -408,7 +408,7 @@ TEST_CASE("Shift Accumulator or Memory Byte Right", "[ASR][ASRA]") { TEST_CASE("Bit Test", "[BIT][BITA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -427,7 +427,7 @@ TEST_CASE("Bit Test", "[BIT][BITA]") { TEST_CASE("Clear Accumulator or Memory", "[CLR][CLRA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -447,7 +447,7 @@ TEST_CASE("Clear Accumulator or Memory", "[CLR][CLRA]") { TEST_CASE("Compare Memory with a Register", "[CMP][CMPA][CMPB][CMPX]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -544,7 +544,7 @@ TEST_CASE("Compare Memory with a Register", "[CMP][CMPA][CMPB][CMPX]") { TEST_CASE("Decrement Accumulator or Memory", "[DEC][DECA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -593,7 +593,7 @@ TEST_CASE("Decrement Accumulator or Memory", "[DEC][DECA]") { TEST_CASE("Increment Accumulator or Memory Location by 1", "[INC][INCA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -640,7 +640,7 @@ TEST_CASE("Increment Accumulator or Memory Location by 1", "[INC][INCA]") { TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][SBCB]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -729,7 +729,7 @@ TEST_CASE("Subtract Memory from Accumulator with Borrow (8-bit)", "[SBC][SBCA][S TEST_CASE("Subtract Memory from Register", "[SUB][SUBA]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -826,7 +826,7 @@ TEST_CASE("Subtract Memory from Register", "[SUB][SUBA]") { TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -847,7 +847,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { REQUIRE(cpu.A() == 1); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BGT2") { @@ -858,7 +858,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { REQUIRE(cpu.A() == 2); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BGT3") { @@ -869,7 +869,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { REQUIRE(cpu.A() == 1); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BGT4") { @@ -880,7 +880,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { REQUIRE(cpu.A() == 2); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BGT5") { @@ -895,7 +895,7 @@ TEST_CASE(" Branch if Greater Than Zero", "[BGT]") { TEST_CASE(" Branch if Higher", "[BHI]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -920,7 +920,7 @@ TEST_CASE(" Branch if Higher", "[BHI]") { TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") { Board board; - board.powerOn(); + board.raisePOWER(); auto& cpu = board.CPU(); cpu.step(); // Step over the reset @@ -941,7 +941,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") { REQUIRE(cpu.A() == 2); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BLE2") { @@ -952,7 +952,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") { REQUIRE(cpu.A() == 1); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BLE3") { @@ -963,7 +963,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") { REQUIRE(cpu.A() == 2); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BLE4") { @@ -974,7 +974,7 @@ TEST_CASE("Branch on Less than or Equal to Zero", "[BLE]") { REQUIRE(cpu.A() == 1); } - cpu.reset(); + cpu.lowerRESET(); cpu.step(); SECTION("BLE5") { diff --git a/MC6850/inc/MC6850.h b/MC6850/inc/MC6850.h index 2447e17..f1bbf8c 100644 --- a/MC6850/inc/MC6850.h +++ b/MC6850/inc/MC6850.h @@ -8,7 +8,7 @@ namespace EightBit { class mc6850 final : public ClockedChip { public: - void powerOn() final; + void raisePOWER() final; // +--------+----------------------------------------------------------------------------------+ // | | Buffer address | @@ -271,10 +271,6 @@ namespace EightBit { void startTransmit(); void completeReceive(); - bool isInterruptRequired() const; - bool isTransmitInterruptRequired() const; - bool isReceiveInterruptRequired() const; - bool transmitInterruptEnabled() const { return m_transmitControl == ReadyLowInterruptEnabled; } bool receiveInterruptEnabled() const { return m_receiveControl == ReceiveInterruptEnable; } diff --git a/MC6850/src/MC6850.cpp b/MC6850/src/MC6850.cpp index 2fa2e81abaa43a9bbc635e69d24195370ebfd582..41d4c8badf4dabece9c3f87135b12a55f1ad2fd9 100644 GIT binary patch delta 189 zcmca)@yd8Z1*32gLn1>aLoq`tLjZ$6LpXygL(t?_Mop~Z`QqY}dzkq)KVXz#pDe_w z#;U+z&!8}QHIt;c0)rKU0z(c%K0`Uss3Haph9HIzhTzS{oYvfvJ(z?hbMf*`R+6?6 s)@0yi;9}qeLb&3|irnIx_lYcEocx28XYvwhnaMuVLO2z!6FbHP0M-C0#Q*>R delta 450 zcmaE5e92-%1tV_(Lq0<}Ln=cNgFi#ws30F@G@{Q)J`lnM;J$h-IEuIgs`LO1zSRl-brFotZEEuz@R=Z KX3POKg#iGYdSVs; diff --git a/Z80/fusetest_Z80/FuseTestRunner.cpp b/Z80/fusetest_Z80/FuseTestRunner.cpp index dee822b..3fcbdd2 100644 --- a/Z80/fusetest_Z80/FuseTestRunner.cpp +++ b/Z80/fusetest_Z80/FuseTestRunner.cpp @@ -10,15 +10,18 @@ Fuse::TestRunner::TestRunner(const Test& test, const ExpectedTestResult& expecte // -void Fuse::TestRunner::powerOn() { - EightBit::Bus::powerOn(); - m_cpu.powerOn(); +void Fuse::TestRunner::raisePOWER() { + EightBit::Bus::raisePOWER(); + m_cpu.raisePOWER(); + m_cpu.raiseRESET(); + m_cpu.raiseINT(); + m_cpu.raiseNMI(); initialiseRegisters(); } -void Fuse::TestRunner::powerOff() { - m_cpu.powerOff(); - EightBit::Bus::powerOff(); +void Fuse::TestRunner::lowerPOWER() { + m_cpu.lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Fuse::TestRunner::initialise() { @@ -327,8 +330,8 @@ void Fuse::TestRunner::checkMemory() { } void Fuse::TestRunner::run() { - - powerOn(); + raisePOWER(); + initialise(); auto allowedCycles = m_test.registerState.tstates; try { m_cpu.run(allowedCycles); diff --git a/Z80/fusetest_Z80/FuseTestRunner.h b/Z80/fusetest_Z80/FuseTestRunner.h index 576761d..cb0b982 100644 --- a/Z80/fusetest_Z80/FuseTestRunner.h +++ b/Z80/fusetest_Z80/FuseTestRunner.h @@ -35,7 +35,6 @@ namespace Fuse { EightBit::register16_t actual, EightBit::register16_t expected) const; protected: - virtual void initialise() final; virtual EightBit::MemoryMapping mapping(uint16_t address) final { return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; } @@ -47,7 +46,9 @@ namespace Fuse { bool failed() const { return m_failed; } bool unimplemented() const { return m_unimplemented; } - virtual void powerOn() final; - virtual void powerOff() final; + virtual void raisePOWER() final; + virtual void lowerPOWER() final; + + virtual void initialise() final; }; } \ No newline at end of file diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index d02a81e..f54faff 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -51,12 +52,22 @@ namespace EightBit { Signal ExecutingInstruction; Signal ExecutedInstruction; + Signal RaisedNMI; + Signal LoweredNMI; + + Signal RaisedM1; + Signal LoweredM1; + [[nodiscard]] auto& NMI() { return m_nmiLine; } // In [[nodiscard]] auto& M1() { return m_m1Line; } // Out int execute() final; int step() final; - void powerOn() final; + + void raisePOWER() final; + + void raiseNMI(); + void lowerNMI(); [[nodiscard]] register16_t& AF() final; [[nodiscard]] register16_t& BC() final; @@ -90,8 +101,8 @@ namespace EightBit { void handleINT() final; private: - PinLevel m_nmiLine = PinLevel::Low; - PinLevel m_m1Line = PinLevel::Low; + PinLevel m_nmiLine = PinLevel::Low; // In, Active low + PinLevel m_m1Line = PinLevel::Low; // Out, Active low InputOutput& m_ports; @@ -121,6 +132,9 @@ namespace EightBit { int8_t m_displacement = 0; bool m_displaced = false; + void raiseM1(); + void lowerM1(); + void handleNMI(); [[nodiscard]] uint16_t displacedAddress() { diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index 2f3d741..8924fd7 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -24,12 +24,11 @@ EightBit::register16_t& EightBit::Z80::HL() { return m_registers[m_registerSet][HL_IDX]; } -void EightBit::Z80::powerOn() { +void EightBit::Z80::raisePOWER() { - IntelProcessor::powerOn(); + IntelProcessor::raisePOWER(); - raise(NMI()); - raise(M1()); + raiseM1(); di(); IM() = 0; @@ -46,6 +45,26 @@ void EightBit::Z80::powerOn() { m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; } +void EightBit::Z80::raiseNMI() { + raise(NMI()); + RaisedNMI.fire(EventArgs::empty()); +} + +void EightBit::Z80::lowerNMI() { + lower(NMI()); + LoweredNMI.fire(EventArgs::empty()); +} + +void EightBit::Z80::raiseM1() { + raise(M1()); + RaisedM1.fire(EventArgs::empty()); +} + +void EightBit::Z80::lowerM1() { + lower(M1()); + LoweredM1.fire(EventArgs::empty()); +} + void EightBit::Z80::handleRESET() { IntelProcessor::handleRESET(); di(); @@ -53,8 +72,8 @@ void EightBit::Z80::handleRESET() { } void EightBit::Z80::handleNMI() { - raise(NMI()); - raise(HALT()); + raiseNMI(); + raiseHALT(); IFF1() = false; restart(0x66); tick(13); @@ -62,12 +81,12 @@ void EightBit::Z80::handleNMI() { void EightBit::Z80::handleINT() { IntelProcessor::handleINT(); - raise(HALT()); + raiseHALT(); if (IFF1()) { di(); switch (IM()) { case 0: // i8080 equivalent - Processor::execute(BUS().DATA()); + IntelProcessor::execute(BUS().DATA()); break; case 1: restart(7 << 3); @@ -663,7 +682,7 @@ int EightBit::Z80::step() { ExecutingInstruction.fire(*this); if (LIKELY(powered())) { m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; - lower(M1()); + lowerM1(); if (UNLIKELY(lowered(RESET()))) { handleRESET(); } else if (UNLIKELY(lowered(NMI()))) { @@ -671,9 +690,9 @@ int EightBit::Z80::step() { } else if (UNLIKELY(lowered(INT()))) { handleINT(); } else if (UNLIKELY(lowered(HALT()))) { - Processor::execute(0); // NOP + IntelProcessor::execute(0); // NOP } else { - Processor::execute(fetchByte()); + IntelProcessor::execute(fetchByte()); } } ExecutedInstruction.fire(*this); @@ -686,7 +705,7 @@ int EightBit::Z80::execute() { if (LIKELY(!(m_prefixCB && m_displaced))) { ++REFRESH(); - raise(M1()); + raiseM1(); } const auto& decoded = getDecodedOpcode(opcode()); @@ -1363,8 +1382,8 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in m_prefixCB = true; if (UNLIKELY(m_displaced)) fetchDisplacement(); - lower(M1()); - Processor::execute(fetchByte()); + lowerM1(); + IntelProcessor::execute(fetchByte()); break; case 2: // OUT (n),A writePort(fetchByte()); @@ -1413,18 +1432,18 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 1: // DD prefix m_displaced = m_prefixDD = true; - lower(M1()); - Processor::execute(fetchByte()); + lowerM1(); + IntelProcessor::execute(fetchByte()); break; case 2: // ED prefix m_prefixED = true; - lower(M1()); - Processor::execute(fetchByte()); + lowerM1(); + IntelProcessor::execute(fetchByte()); break; case 3: // FD prefix m_displaced = m_prefixFD = true; - lower(M1()); - Processor::execute(fetchByte()); + lowerM1(); + IntelProcessor::execute(fetchByte()); break; default: UNREACHABLE; diff --git a/Z80/test/Board.cpp b/Z80/test/Board.cpp index c067551..f086bc9 100644 --- a/Z80/test/Board.cpp +++ b/Z80/test/Board.cpp @@ -4,15 +4,17 @@ Board::Board(const Configuration& configuration) : m_configuration(configuration) {} -void Board::powerOn() { - EightBit::Bus::powerOn(); - CPU().powerOn(); - CPU().reset(); +void Board::raisePOWER() { + EightBit::Bus::raisePOWER(); + CPU().raisePOWER(); + CPU().raiseRESET(); + CPU().raiseINT(); + CPU().raiseNMI(); } -void Board::powerOff() noexcept { - CPU().powerOff(); - EightBit::Bus::powerOff(); +void Board::lowerPOWER() noexcept { + CPU().lowerPOWER(); + EightBit::Bus::lowerPOWER(); } void Board::initialise() { @@ -20,13 +22,15 @@ void Board::initialise() { auto romDirectory = m_configuration.getRomDirectory(); m_ram.load(romDirectory + "/zexall.com", 0x100); // Cringle/Bartholomew + m_cpu.LoweredHALT.connect([this](EightBit::EventArgs) { + lowerPOWER(); + }); + m_cpu.ExecutingInstruction.connect([this] (EightBit::Z80& cpu) { - if (UNLIKELY(EightBit::Chip::lowered(cpu.HALT()))) - powerOff(); switch (cpu.PC().word) { case 0x0: // CP/M warm start - if (++m_warmstartCount == 3) { - powerOff(); + if (++m_warmstartCount == 2) { + lowerPOWER(); if (m_configuration.isProfileMode()) m_profiler.dump(); } diff --git a/Z80/test/Board.h b/Z80/test/Board.h index 2fe517f..27d2c4e 100644 --- a/Z80/test/Board.h +++ b/Z80/test/Board.h @@ -18,11 +18,12 @@ public: EightBit::Z80& CPU() noexcept { return m_cpu; } - void powerOn() final; - void powerOff() noexcept final; + void raisePOWER() final; + void lowerPOWER() noexcept final; + + void initialise() final; protected: - void initialise() final; EightBit::MemoryMapping mapping(uint16_t address) noexcept final { return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite }; } diff --git a/inc/Bus.h b/inc/Bus.h index 3c28d02..ef1bc3a 100644 --- a/inc/Bus.h +++ b/inc/Bus.h @@ -48,12 +48,12 @@ namespace EightBit { write(value); } - virtual void powerOn(); - virtual void powerOff(); + virtual void raisePOWER(); + virtual void lowerPOWER(); - protected: virtual void initialise() = 0; + protected: [[nodiscard]] uint8_t& reference(uint16_t address); [[nodiscard]] auto& reference(const register16_t address) { return reference(address.word); } [[nodiscard]] uint8_t& reference() { return reference(ADDRESS()); } diff --git a/inc/Device.h b/inc/Device.h index d4fc1ba..de82a98 100644 --- a/inc/Device.h +++ b/inc/Device.h @@ -1,5 +1,8 @@ #pragma once +#include "EventArgs.h" +#include "Signal.h" + namespace EightBit { class Device { public: @@ -12,20 +15,21 @@ namespace EightBit { static constexpr auto lowered(const PinLevel line) { return line == PinLevel::Low; } static void lower(PinLevel& line) noexcept { line = PinLevel::Low; } - static void match(PinLevel& line, int value); - virtual ~Device() {}; + Signal RaisedPOWER; + Signal LoweredPOWER; + [[nodiscard]] auto& POWER() noexcept { return m_powerLine; } [[nodiscard]] auto powered() noexcept { return raised(POWER()); } - virtual void powerOn(); - virtual void powerOff() { lower(POWER()); } + virtual void raisePOWER(); + virtual void lowerPOWER(); protected: Device() {}; private: - PinLevel m_powerLine = PinLevel::Low; + PinLevel m_powerLine = PinLevel::Low; // In }; } diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index 8ad7fc8..c631f97 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -6,7 +6,8 @@ #include "Bus.h" #include "LittleEndianProcessor.h" #include "Register.h" - +#include "EventArgs.h" +#include "Signal.h" #include "EightBitCompilerDefinitions.h" namespace EightBit { @@ -33,6 +34,11 @@ namespace EightBit { ~IntelProcessor() = default; + Signal RaisedHALT; + Signal LoweredHALT; + + [[nodiscard]] auto& HALT() noexcept { return m_haltLine; } + [[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept { return m_decodedOpcodes[i]; } @@ -57,7 +63,7 @@ namespace EightBit { [[nodiscard]] auto& H() { return HL().high; } [[nodiscard]] auto& L() { return HL().low; } - void powerOn() override; + void raisePOWER() override; protected: IntelProcessor(Bus& bus); @@ -117,6 +123,8 @@ namespace EightBit { return m_halfCarryTableSub[index & Mask3]; } + void handleRESET() override; + void push(uint8_t value) final; [[nodiscard]] uint8_t pop() final; @@ -164,9 +172,18 @@ namespace EightBit { void ret() final; + [[nodiscard]] auto halted() noexcept { return lowered(HALT()); } + void halt() noexcept { --PC(); lowerHALT(); } + void proceed() noexcept { ++PC(); raiseHALT(); } + + virtual void lowerHALT(); + virtual void raiseHALT(); + private: std::array m_decodedOpcodes; register16_t m_sp = Mask16; register16_t m_memptr; + + PinLevel m_haltLine = PinLevel::Low; // Out, Active low }; } diff --git a/inc/Processor.h b/inc/Processor.h index 7db829e..6d75fb1 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -5,6 +5,8 @@ #include "ClockedChip.h" #include "Bus.h" #include "Register.h" +#include "EventArgs.h" +#include "Signal.h" #include "EightBitCompilerDefinitions.h" @@ -17,15 +19,22 @@ namespace EightBit { ~Processor() {}; + Signal RaisedRESET; + Signal LoweredRESET; + + Signal RaisedINT; + Signal LoweredINT; + [[nodiscard]] auto& PC() noexcept { return m_pc; } [[nodiscard]] auto& RESET() noexcept { return m_resetLine; } - [[nodiscard]] auto& HALT() noexcept { return m_haltLine; } [[nodiscard]] auto& INT() noexcept { return m_intLine; } - [[nodiscard]] auto& IRQ() noexcept { return INT(); } // Synonym - void powerOn() override; - void reset() noexcept { lower(RESET()); } + virtual void lowerRESET(); + virtual void raiseRESET(); + + virtual void lowerINT(); + virtual void raiseINT(); int run(int limit); virtual int step() = 0; @@ -41,13 +50,8 @@ namespace EightBit { [[nodiscard]] auto& opcode() noexcept { return m_opcode; } [[nodiscard]] auto& BUS() noexcept { return m_bus; } - [[nodiscard]] auto halted() noexcept { return lowered(HALT()); } - void halt() noexcept { --PC(); lower(HALT()); } - void proceed() noexcept { ++PC(); raise(HALT()); } - virtual void handleRESET(); virtual void handleINT(); - virtual void handleIRQ(); void busWrite(register16_t address, uint8_t data); void busWrite(uint8_t data); @@ -108,8 +112,7 @@ namespace EightBit { uint8_t m_opcode = Mask8; register16_t m_pc; - PinLevel m_intLine = PinLevel::Low; - PinLevel m_haltLine = PinLevel::Low; - PinLevel m_resetLine = PinLevel::Low; + PinLevel m_intLine = PinLevel::Low; // In + PinLevel m_resetLine = PinLevel::Low; // In }; } diff --git a/inc/TestHarness.h b/inc/TestHarness.h index db3329b..3becd33 100644 --- a/inc/TestHarness.h +++ b/inc/TestHarness.h @@ -60,7 +60,8 @@ namespace EightBit { m_totalCycles = m_instructions = 0L; m_startHostCycles = currentHostCycles(); - m_board.powerOn(); + m_board.initialise(); + m_board.raisePOWER(); auto& cpu = m_board.CPU(); diff --git a/src/Bus.cpp b/src/Bus.cpp index afd1188..7232bed 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -8,11 +8,9 @@ #include #include -void EightBit::Bus::powerOn() { - initialise(); -} +void EightBit::Bus::raisePOWER() {} -void EightBit::Bus::powerOff() {} +void EightBit::Bus::lowerPOWER() {} uint8_t EightBit::Bus::read() { ReadingByte.fire(EventArgs::empty()); diff --git a/src/Device.cpp b/src/Device.cpp index 32cd909..e94b15c 100644 --- a/src/Device.cpp +++ b/src/Device.cpp @@ -1,10 +1,12 @@ #include "stdafx.h" #include "Device.h" -void EightBit::Device::powerOn() { +void EightBit::Device::raisePOWER() { raise(POWER()); + RaisedPOWER.fire(EventArgs::empty()); } -void EightBit::Device::match(PinLevel& line, int value) { - value ? raise(line) : lower(line); +void EightBit::Device::lowerPOWER() { + lower(POWER()); + LoweredPOWER.fire(EventArgs::empty()); } diff --git a/src/IntelProcessor.cpp b/src/IntelProcessor.cpp index 5e3e93d..3160d67 100644 --- a/src/IntelProcessor.cpp +++ b/src/IntelProcessor.cpp @@ -7,11 +7,27 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus) m_decodedOpcodes[i] = i; } -void EightBit::IntelProcessor::powerOn() { - Processor::powerOn(); +void EightBit::IntelProcessor::raisePOWER() { + Processor::raisePOWER(); + raiseHALT(); SP() = AF() = BC() = DE() = HL() = Mask16; } +void EightBit::IntelProcessor::lowerHALT() { + lower(HALT()); + LoweredHALT.fire(EventArgs::empty()); +} + +void EightBit::IntelProcessor::raiseHALT() { + raise(HALT()); + RaisedHALT.fire(EventArgs::empty()); +} + +void EightBit::IntelProcessor::handleRESET() { + Processor::handleRESET(); + PC() = 0; +} + void EightBit::IntelProcessor::push(const uint8_t value) { BUS().write(--SP(), value); } diff --git a/src/Processor.cpp b/src/Processor.cpp index b11cbae..5ec87ab 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -5,24 +5,32 @@ EightBit::Processor::Processor(Bus& bus) : m_bus(bus) { } -void EightBit::Processor::powerOn() { - Chip::powerOn(); +void EightBit::Processor::lowerRESET() { + lower(RESET()); + LoweredRESET.fire(EventArgs::empty()); +} + +void EightBit::Processor::raiseRESET() { raise(RESET()); - raise(HALT()); + RaisedRESET.fire(EventArgs::empty()); +} + +void EightBit::Processor::lowerINT() { + lower(INT()); + LoweredINT.fire(EventArgs::empty()); +} + +void EightBit::Processor::raiseINT() { raise(INT()); + RaisedINT.fire(EventArgs::empty()); } void EightBit::Processor::handleRESET() { - raise(RESET()); - PC() = 0; + raiseRESET(); } void EightBit::Processor::handleINT() { - raise(INT()); -} - -void EightBit::Processor::handleIRQ() { - raise(IRQ()); + raiseINT(); } void EightBit::Processor::busWrite(const register16_t address, const uint8_t data) {