diff --git a/Z80/HarteTest_Z80/HarteTest_Z80.vcxproj b/Z80/HarteTest_Z80/HarteTest_Z80.vcxproj index 7b7ec5f..d5d4239 100644 --- a/Z80/HarteTest_Z80/HarteTest_Z80.vcxproj +++ b/Z80/HarteTest_Z80/HarteTest_Z80.vcxproj @@ -168,9 +168,6 @@ - - {d8726a1b-bbfe-47ef-9860-26b90140ba66} - {a9c24bd9-0cb4-4c84-b09b-46b815f9da47} diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 72097c2..ad87314 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -135,16 +135,14 @@ namespace EightBit { void handleRESET() noexcept final; void handleINT() noexcept final; - void pushWord(register16_t destination) noexcept final; - + void memoryUpdate(int ticks) noexcept; void memoryWrite() noexcept final; uint8_t memoryRead() noexcept final; + void refreshMemory() noexcept; - void busWrite() noexcept final; - uint8_t busRead() noexcept final; + void jumpRelative(int8_t offset) noexcept final; - void jr(int8_t offset) noexcept final; - int jrConditional(int condition) noexcept final; + void call(register16_t destination) override; private: bool m_interruptPending = false; @@ -189,17 +187,17 @@ namespace EightBit { [[nodiscard]] constexpr auto displaced() const noexcept { return m_prefixDD || m_prefixFD; } - [[nodiscard]] constexpr const register16_t& displacedAddress() noexcept { + [[nodiscard]] constexpr void displaceAddress() noexcept { const auto& index_register = m_prefixDD ? IX() : IY(); const auto address = index_register.word + m_displacement; MEMPTR().word = address; - return MEMPTR(); + BUS().ADDRESS() = MEMPTR(); } void fetchDisplacement() noexcept; - [[nodiscard]] uint8_t fetchInstruction() noexcept; + [[nodiscard]] uint8_t fetchInstruction() noexcept final; - uint8_t readBusDataM1() noexcept; + uint8_t readDataUnderInterrupt(); typedef std::function addresser_t; void loadAccumulatorIndirect(addresser_t addresser) noexcept; @@ -212,8 +210,8 @@ namespace EightBit { [[nodiscard]] register16_t& RP(int rp) noexcept; [[nodiscard]] register16_t& RP2(int rp) noexcept; - [[nodiscard]] uint8_t R(int r) noexcept; - void R(int r, uint8_t value) noexcept; + [[nodiscard]] uint8_t& R(int r, MemoryMapping::AccessLevel access = MemoryMapping::AccessLevel::ReadOnly) noexcept; + void R(int r, uint8_t value, int ticks = 1) noexcept; void R2(int r, uint8_t value) noexcept; [[nodiscard]] static constexpr auto zeroTest(uint8_t data) noexcept { return data & ZF; } @@ -341,7 +339,7 @@ namespace EightBit { return adjustOverflowSub(input, signTest(before), signTest(value), signTest(calculation)); } - [[nodiscard]] constexpr bool convertCondition(int flag) noexcept { + [[nodiscard]] bool convertCondition(int flag) noexcept override { switch (flag) { case 0: return zero() == 0; @@ -407,10 +405,7 @@ namespace EightBit { void retn() noexcept; void reti() noexcept; - void returnConditionalFlag(int flag) noexcept; - void jrConditionalFlag(int flag) noexcept; - void callConditionalFlag(int flag) noexcept; - void jumpConditionalFlag(int flag) noexcept; + void returnConditionalFlag(int flag) noexcept final; [[nodiscard]] register16_t sbc(register16_t operand, register16_t value) noexcept; [[nodiscard]] register16_t adc(register16_t operand, register16_t value) noexcept; @@ -583,9 +578,10 @@ namespace EightBit { adjustXY(((Q() ^ F()) | A())); } - void cpl() noexcept { + void cpl() noexcept final { setBit(HC | NF); - adjustXY(A() = ~A()); + IntelProcessor::cpl(); + adjustXY(A()); } void xhtl(register16_t& exchange) noexcept; diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index d85393a..c50ddff 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -141,76 +141,57 @@ const EightBit::register16_t& EightBit::Z80::HL() const noexcept { return m_registers[m_registerSet][HL_IDX]; } -void EightBit::Z80::pushWord(const register16_t destination) noexcept { +void EightBit::Z80::memoryUpdate(int ticks) noexcept { + assert(ticks > 0 && "Ticks must be greater than zero"); + WritingMemory.fire(); + tick(ticks); + lowerMREQ(); + lowerWR(); + tick(); + IntelProcessor::memoryWrite(); + raiseWR(); + raiseMREQ(); tick(); - IntelProcessor::pushWord(destination); + WrittenMemory.fire(); } void EightBit::Z80::memoryWrite() noexcept { + memoryUpdate(1); +} - class _Writer final { - Z80& m_parent; - public: - _Writer(Z80& parent) noexcept - : m_parent(parent) { - m_parent.WritingMemory.fire(); - m_parent.tick(2); - m_parent.lowerMREQ(); - } - - ~_Writer() noexcept { - m_parent.raiseMREQ(); - m_parent.WrittenMemory.fire(); - } - }; - - _Writer writer(*this); - IntelProcessor::memoryWrite(); +void EightBit::Z80::refreshMemory() noexcept { + assert(lowered(M1()) && "M1 must be lowered to refresh memory"); + BUS().ADDRESS() = { REFRESH(), IV() }; + lowerRFSH(); + tick(); + lowerMREQ(); + raiseMREQ(); + raiseRFSH(); } uint8_t EightBit::Z80::memoryRead() noexcept { - - class _Reader final { - Z80& m_parent; - public: - _Reader(Z80& parent) noexcept - : m_parent(parent) { - m_parent.ReadingMemory.fire(); - if (lowered(m_parent.M1())) - m_parent.tick(); - m_parent.tick(2); - m_parent.lowerMREQ(); - } - - ~_Reader() noexcept { - m_parent.raiseMREQ(); - m_parent.ReadMemory.fire(); - } - }; - - _Reader reader(*this); - return IntelProcessor::memoryRead(); -} - -void EightBit::Z80::busWrite() noexcept { + ReadingMemory.fire(); tick(); - _ActivateWR writer(*this); - IntelProcessor::busWrite(); -} - -uint8_t EightBit::Z80::busRead() noexcept { + lowerMREQ(); + lowerRD(); + tick(); + IntelProcessor::memoryRead(); + raiseRD(); + raiseMREQ(); + if (lowered(M1())) + refreshMemory(); tick(); - _ActivateRD reader(*this); - return IntelProcessor::busRead(); + ReadMemory.fire(); + return BUS().DATA(); } void EightBit::Z80::handleRESET() noexcept { IntelProcessor::handleRESET(); disableInterrupts(); + IM() = 0; IV() = 0; REFRESH() = 0; SP().word = AF().word = Mask16; - tick(3); } void EightBit::Z80::handleNMI() noexcept { @@ -218,18 +199,32 @@ void EightBit::Z80::handleNMI() noexcept { raiseHALT(); IFF2() = IFF1(); IFF1() = false; - readBusDataM1(); + lowerM1(); + raiseM1(); restart(0x66); } +uint8_t EightBit::Z80::readDataUnderInterrupt() { + lowerM1(); + tick(3); + lowerIORQ(); + tick(); + const auto data = BUS().DATA(); + raiseIORQ(); + assert(cycles() == 4); + refreshMemory(); + assert(cycles() == 5); + raiseM1(); + return data; +} + void EightBit::Z80::handleINT() noexcept { + IntelProcessor::handleINT(); - tick(2); // 2 extra clock cycles introduced to allow the bus to settle - uint8_t data; - { - _ActivateIORQ iorq(*this); - data = readBusDataM1(); - } + + const auto data = readDataUnderInterrupt(); + tick(); + assert(cycles() == 6); switch (IM()) { case 0: // i8080 equivalent @@ -237,11 +232,13 @@ void EightBit::Z80::handleINT() noexcept { break; case 1: restart(7 << 3); + assert(cycles() == 13); break; case 2: - tick(7); // How long to allow fetching data from the device... + tick(); MEMPTR() = Processor::getWordPaged(IV(), data); call(MEMPTR()); + assert(cycles() == 13); break; default: UNREACHABLE; @@ -257,23 +254,12 @@ void EightBit::Z80::enableInterrupts() { } void EightBit::Z80::returnConditionalFlag(const int flag) noexcept { + const auto condition = convertCondition(flag); tick(); - if (convertCondition(flag)) + if (condition) ret(); } -void EightBit::Z80::jrConditionalFlag(const int flag) noexcept { - jrConditional(convertCondition(flag)); -} - -void EightBit::Z80::jumpConditionalFlag(const int flag) noexcept { - jumpConditional(convertCondition(flag)); -} - -void EightBit::Z80::callConditionalFlag(const int flag) noexcept { - callConditional(convertCondition(flag)); -} - void EightBit::Z80::retn() noexcept { ret(); IFF1() = IFF2(); @@ -283,15 +269,15 @@ void EightBit::Z80::reti() noexcept { retn(); } -void EightBit::Z80::jr(int8_t offset) noexcept { - IntelProcessor::jr(offset); - tick(5); + +void EightBit::Z80::call(register16_t destination) { + tick(); + Processor::call(destination); } -int EightBit::Z80::jrConditional(const int condition) noexcept { - if (!IntelProcessor::jrConditional(condition)) - tick(3); - return condition; +void EightBit::Z80::jumpRelative(int8_t offset) noexcept { + IntelProcessor::jumpRelative(offset); + tick(5); } EightBit::register16_t EightBit::Z80::sbc(const register16_t operand, const register16_t value) noexcept { @@ -345,7 +331,6 @@ EightBit::register16_t EightBit::Z80::add(const register16_t operand, const regi MEMPTR() = operand + 1; - tick(7); return intermediate(); } @@ -353,12 +338,13 @@ void EightBit::Z80::xhtl(register16_t& exchange) noexcept { MEMPTR().low = IntelProcessor::memoryRead(SP()); ++BUS().ADDRESS(); MEMPTR().high = memoryRead(); - tick(); - IntelProcessor::memoryWrite(exchange.high); + BUS().DATA() = exchange.high; exchange.high = MEMPTR().high; + memoryUpdate(2); --BUS().ADDRESS(); - IntelProcessor::memoryWrite(exchange.low); + BUS().DATA() = exchange.low; exchange.low = MEMPTR().low; + memoryUpdate(1); tick(2); } @@ -597,7 +583,7 @@ void EightBit::Z80::writePort(const uint8_t port) noexcept { void EightBit::Z80::writePort() noexcept { MEMPTR() = BUS().ADDRESS(); - //tick(2); + tick(2); lowerIORQ(); lowerWR(); tick(); @@ -620,11 +606,12 @@ void EightBit::Z80::readPort(const uint8_t port) noexcept { void EightBit::Z80::readPort() noexcept { MEMPTR() = BUS().ADDRESS(); - //tick(2); + tick(2); tick(); lowerIORQ(); lowerRD(); BUS().DATA() = m_ports.read(BUS().ADDRESS()); + tick(); raiseRD(); raiseIORQ(); tick(); @@ -638,11 +625,6 @@ void EightBit::Z80::fetchDisplacement() noexcept { // -uint8_t EightBit::Z80::readBusDataM1() noexcept { - _ActivateM1 m1(*this); - return BUS().DATA(); -} - // ** From the Z80 CPU User Manual // Figure 5 depicts the timing during an M1 (op code fetch) cycle. The Program Counter is @@ -671,22 +653,10 @@ uint8_t EightBit::Z80::readBusDataM1() noexcept { // CPU.The HALT acknowledge signal is active during this time indicating that the processor // is in the HALT state uint8_t EightBit::Z80::fetchInstruction() noexcept { - uint8_t returned; - { - _ActivateM1 m1(*this); - const auto halted = lowered(HALT()); - returned = IntelProcessor::memoryRead(PC()); - if (UNLIKELY(halted)) - returned = 0; // NOP - else - PC()++; - } - BUS().ADDRESS() = { REFRESH(), IV() }; - { - _ActivateRFSH rfsh(*this); - _ActivateMREQ mreq(*this); - } - return returned; + lowerM1(); + IntelProcessor::fetchInstruction(); + raiseM1(); + return BUS().DATA(); } void EightBit::Z80::loadAccumulatorIndirect(addresser_t addresser) noexcept { @@ -745,7 +715,7 @@ EightBit::register16_t& EightBit::Z80::RP2(const int rp) noexcept { } } -uint8_t EightBit::Z80::R(const int r) noexcept { +uint8_t& EightBit::Z80::R(const int r, MemoryMapping::AccessLevel access) noexcept { switch (r) { case 0: return B(); @@ -760,7 +730,21 @@ uint8_t EightBit::Z80::R(const int r) noexcept { case 5: return HL2().low; case 6: - return IntelProcessor::memoryRead(UNLIKELY(displaced()) ? displacedAddress() : HL()); + if (displaced()) + displaceAddress(); + else + BUS().ADDRESS() = HL(); + switch (access) { + case MemoryMapping::AccessLevel::ReadOnly: + memoryRead(); + break; + case MemoryMapping::AccessLevel::WriteOnly: + break; + default: + UNREACHABLE; + break; + } + return BUS().DATA(); case 7: return A(); default: @@ -768,35 +752,11 @@ uint8_t EightBit::Z80::R(const int r) noexcept { } } -void EightBit::Z80::R(const int r, const uint8_t value) noexcept { - switch (r) { - case 0: - B() = value; - break; - case 1: - C() = value; - break; - case 2: - D() = value; - break; - case 3: - E() = value; - break; - case 4: - HL2().high = value; - break; - case 5: - HL2().low = value; - break; - case 6: - IntelProcessor::memoryWrite(UNLIKELY(displaced()) ? displacedAddress() : HL(), value); - break; - case 7: - A() = value; - break; - default: - UNREACHABLE; - } +void EightBit::Z80::R(const int r, const uint8_t value, const int ticks) noexcept { + + R(r, MemoryMapping::AccessLevel::WriteOnly) = value; + if (r == 6) + memoryUpdate(ticks); } void EightBit::Z80::R2(const int r, const uint8_t value) noexcept { @@ -879,11 +839,13 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) noexcept { const bool memoryZ = z == 6; const bool indirect = (!displaced() && memoryZ) || displaced(); + const auto direct = !indirect; uint8_t operand; if (displaced()) { tick(2); - operand = IntelProcessor::memoryRead(displacedAddress()); + displaceAddress(); + operand = memoryRead(); } else { operand = R(z); } @@ -923,8 +885,8 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) noexcept { break; } case 1: // BIT y, r[z] bit(y, operand); - adjustXY(indirect ? MEMPTR().high : operand); - if (memoryZ) + adjustXY(direct ? operand : MEMPTR().high); + if (indirect) tick(); break; case 2: // RES y, r[z] @@ -937,8 +899,8 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) noexcept { UNREACHABLE; } if (update) { - tick(); if (displaced()) { + tick(); IntelProcessor::memoryWrite(operand); if (!memoryZ) R2(z, operand); @@ -980,6 +942,7 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p default: UNREACHABLE; } + tick(7); break; case 3: // Retrieve/store register pair from/to immediate address BUS().ADDRESS() = fetchWord(); @@ -1147,16 +1110,16 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 2: // DJNZ d tick(); - jrConditional(--B()); + jumpRelativeConditional(--B()); break; case 3: // JR d - jr(fetchByte()); + jumpRelative(fetchByte()); break; case 4: // JR cc,d case 5: case 6: case 7: - jrConditionalFlag(y - 4); + jumpRelativeConditionalFlag(y - 4); break; default: UNREACHABLE; @@ -1169,6 +1132,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 1: // ADD HL,rp HL2() = add(HL2(), RP(p)); + tick(7); break; default: UNREACHABLE; @@ -1237,9 +1201,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in tick(5); } const auto original = R(y); - if (memoryY) - tick(); - R(y, increment(original)); + R(y, increment(original), 2); break; } case 5: { // 8-bit DEC @@ -1248,16 +1210,14 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in tick(5); } const auto original = R(y); - if (memoryY) - tick(); - R(y, decrement(original)); + R(y, decrement(original), 2); break; } case 6: { // 8-bit load immediate if (memoryY && displaced()) fetchDisplacement(); const auto value = fetchByte(); - if (displaced()) + if (memoryY) tick(2); R(y, value); // LD r,n break; @@ -1297,24 +1257,20 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in } break; case 1: // 8-bit loading - if ((memoryZ && memoryY)) { // Exception (replaces LD (HL), (HL)) - lowerHALT(); - } else { + if (!(memoryZ && memoryY)) { bool normal = true; if (displaced()) { - if (memoryZ || memoryY) + if (memoryZ || memoryY) { fetchDisplacement(); + tick(5); + } if (memoryZ) { switch (y) { case 4: - if (displaced()) - tick(5); H() = R(z); normal = false; break; case 5: - if (displaced()) - tick(5); L() = R(z); normal = false; break; @@ -1323,25 +1279,20 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in if (memoryY) { switch (z) { case 4: - if (displaced()) - tick(5); R(y, H()); normal = false; break; case 5: - if (displaced()) - tick(5); R(y, L()); normal = false; break; } } } - if (normal) { - if (displaced()) - tick(5); + if (normal) R(y, R(z)); - } + } else { + lowerHALT(); // Exception (replaces LD (HL), (HL)) } break; case 2: { // Operate on accumulator and register/memory location @@ -1399,7 +1350,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in exx(); break; case 2: // JP (HL) - jump(HL2()); + Processor::jump(HL2()); break; case 3: // LD SP,HL SP() = HL2(); @@ -1459,6 +1410,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in case 5: // PUSH & various ops switch (q) { case 0: // PUSH rp2[p] + tick(); pushWord(RP2(p)); break; case 1: diff --git a/inc/IntelProcessor.h b/inc/IntelProcessor.h index b8d4027..8fa04c4 100644 --- a/inc/IntelProcessor.h +++ b/inc/IntelProcessor.h @@ -150,26 +150,55 @@ namespace EightBit { // + register16_t& incrementPC() override; + uint8_t fetchInstruction() override; + + // + [[nodiscard]] register16_t getWord() final; void setWord(register16_t value) final; // virtual void restart(uint8_t address); - virtual int callConditional(int condition); - virtual int jumpConditional(int condition); - virtual int returnConditional(int condition); - virtual void jr(int8_t offset) noexcept; - virtual int jrConditional(int condition); + virtual void callConditional(bool condition); + virtual void jumpConditional(bool condition); + virtual void jumpRelativeConditional(bool condition); + virtual void returnConditional(bool condition); + virtual void jumpIndirect(); + virtual void jump(); + void callIndirect(); + void call(); + virtual void jumpRelative(int8_t offset) noexcept; + void jumpRelative(uint8_t offset) noexcept { jumpRelative((int8_t)offset); } void ret() override; virtual void fetchWordMEMPTR(); - void jumpIndirect(); - void callIndirect(); - void resetWorkingRegisters() noexcept; + [[nodiscard]] virtual bool convertCondition(int flag) noexcept = 0; + + virtual void jumpConditionalFlag(int flag) { + jumpConditional(convertCondition(flag)); + } + + virtual void jumpRelativeConditionalFlag(int flag) { + jumpRelativeConditional(convertCondition(flag)); + } + + virtual void returnConditionalFlag(int flag) { + returnConditional(convertCondition(flag)); + } + + virtual void callConditionalFlag(int flag) { + callConditional(convertCondition(flag)); + } + + virtual void cpl() noexcept { + A() = ~A(); + } + private: static std::array m_halfCarryTableAdd; static std::array m_halfCarryTableSub; diff --git a/inc/Processor.h b/inc/Processor.h index f620f41..43a484d 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -70,7 +70,13 @@ namespace EightBit { virtual uint8_t memoryRead(); virtual uint8_t busRead(); + virtual register16_t& incrementPC(); + virtual register16_t& decrementPC(); + + virtual void immediateAddress(); + uint8_t fetchByte(); + virtual uint8_t fetchInstruction(); [[nodiscard]] virtual register16_t getWord() = 0; virtual void setWord(register16_t value) = 0; diff --git a/src/IntelProcessor.cpp b/src/IntelProcessor.cpp index 6368f88..e2328c6 100644 --- a/src/IntelProcessor.cpp +++ b/src/IntelProcessor.cpp @@ -9,9 +9,6 @@ EightBit::IntelProcessor::IntelProcessor(Bus& bus) for (int i = 0; i < 0x100; ++i) m_decodedOpcodes.at(i) = i; - LoweredHALT.connect([this](EventArgs) noexcept { --PC(); }); - RaisedHALT.connect([this](EventArgs) noexcept { ++PC(); }); - RaisedPOWER.connect([this](EventArgs) { PC() = SP() = Mask16; resetWorkingRegisters(); @@ -37,7 +34,7 @@ DEFINE_PIN_LEVEL_CHANGERS(HALT, IntelProcessor); void EightBit::IntelProcessor::handleRESET() { Processor::handleRESET(); disableInterrupts(); - jump(0); + Processor::jump(0); } void EightBit::IntelProcessor::handleINT() { @@ -54,6 +51,18 @@ uint8_t EightBit::IntelProcessor::pop() { return memoryRead(SP()++); } + +EightBit::register16_t& EightBit::IntelProcessor::incrementPC() { + if (raised(HALT())) + Processor::incrementPC(); + return PC(); +} + +uint8_t EightBit::IntelProcessor::fetchInstruction() { + fetchByte(); + return lowered(HALT()) ? (uint8_t)0 : BUS().DATA(); +} + EightBit::register16_t EightBit::IntelProcessor::getWord() { const auto returned = LittleEndianProcessor::getWord(); MEMPTR() = BUS().ADDRESS(); @@ -66,41 +75,38 @@ void EightBit::IntelProcessor::setWord(const register16_t value) { } void EightBit::IntelProcessor::restart(const uint8_t address) { - call(MEMPTR() = { address, 0 }); + MEMPTR() = { address, 0 }; + call(); } -int EightBit::IntelProcessor::callConditional(const int condition) { +void EightBit::IntelProcessor::callConditional(bool condition) { fetchWordMEMPTR(); if (condition) - call(MEMPTR()); - return condition; + call(); } -int EightBit::IntelProcessor::jumpConditional(const int condition) { +void EightBit::IntelProcessor::jumpConditional(bool condition) { fetchWordMEMPTR(); if (condition) - jump(MEMPTR()); - return condition; + jump(); } -int EightBit::IntelProcessor::returnConditional(const int condition) { +void EightBit::IntelProcessor::jumpRelativeConditional(bool condition) { + const auto offset = fetchByte(); + if (condition) + jumpRelative(offset); +} + +void EightBit::IntelProcessor::returnConditional(bool condition) { if (condition) ret(); - return condition; } -void EightBit::IntelProcessor::jr(const int8_t offset) noexcept { - jump(MEMPTR() = PC() + offset); +void EightBit::IntelProcessor::jumpRelative(const int8_t offset) noexcept { + MEMPTR() = PC() + offset; + jump(); } -int EightBit::IntelProcessor::jrConditional(const int condition) { - const auto offsetAddress = PC()++; - if (condition) { - const auto offset = memoryRead(offsetAddress); - jr(offset); - } - return condition; -} void EightBit::IntelProcessor::ret() { LittleEndianProcessor::ret(); @@ -114,12 +120,20 @@ void EightBit::IntelProcessor::fetchWordMEMPTR() { void EightBit::IntelProcessor::jumpIndirect() { fetchWordMEMPTR(); - jump(MEMPTR()); + jump(); +} + +void EightBit::IntelProcessor::jump() { + Processor::jump(MEMPTR()); } void EightBit::IntelProcessor::callIndirect() { fetchWordMEMPTR(); - call(MEMPTR()); + call(); +} + +void EightBit::IntelProcessor::call() { + Processor::call(MEMPTR()); } bool EightBit::IntelProcessor::operator==(const EightBit::IntelProcessor& rhs) const noexcept { diff --git a/src/Processor.cpp b/src/Processor.cpp index d4d3d38..dfaa1b7 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -80,8 +80,28 @@ void EightBit::Processor::setWordPaged(const uint8_t page, const uint8_t offset, setWordPaged(value); } +EightBit::register16_t& EightBit::Processor::incrementPC() { + PC()++; + return PC(); +} + +EightBit::register16_t& EightBit::Processor::decrementPC() { + PC()--; + return PC(); +} + +void EightBit::Processor::immediateAddress() { + BUS().ADDRESS() = PC(); + incrementPC(); +} + uint8_t EightBit::Processor::fetchByte() { - return memoryRead(PC()++); + immediateAddress(); + return memoryRead(); +} + +uint8_t EightBit::Processor::fetchInstruction() { + return fetchByte(); } EightBit::register16_t EightBit::Processor::getWord(const register16_t address) {