From 4d2d1d214ab033931a041df777ce131a5e3af04a Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sat, 9 Jan 2021 08:41:48 +0000 Subject: [PATCH] Tidy up some C++ code (concentrating on the Z80 at the moment). Signed-off-by: Adrian Conlon --- Z80/inc/Z80.h | 242 ++++++----------------------------- Z80/src/Z80.cpp | 229 ++++++++++++++++++++++++++++----- inc/ClockedChip.h | 7 +- inc/Processor.h | 30 +---- src/ClockedChip.cpp | 16 +++ src/EightBit.vcxproj | 1 + src/EightBit.vcxproj.filters | 3 + src/Makefile | 2 +- src/Processor.cpp | 31 +++++ 9 files changed, 301 insertions(+), 260 deletions(-) create mode 100644 src/ClockedChip.cpp diff --git a/Z80/inc/Z80.h b/Z80/inc/Z80.h index 479a7d2..6229c4a 100644 --- a/Z80/inc/Z80.h +++ b/Z80/inc/Z80.h @@ -1,14 +1,13 @@ #pragma once #include -#include -#include +#include +#include #include #include #include #include -#include namespace EightBit { @@ -99,19 +98,14 @@ namespace EightBit { [[nodiscard]] auto& IFF1() { return m_iff1; } [[nodiscard]] auto& IFF2() { return m_iff2; } - void exx() { - m_registerSet ^= 1; - } + void exx() { m_registerSet ^= 1; } + void exxAF() { m_accumulatorFlagsSet ^= 1; } - void exxAF() { - m_accumulatorFlagsSet ^= 1; - } + [[nodiscard]] auto requestingIO() const { return lowered(IORQ()); } + [[nodiscard]] auto requestingMemory() const { return lowered(MREQ()); } - [[nodiscard]] bool requestingIO() const { return lowered(IORQ()); } - [[nodiscard]] bool requestingMemory() const { return lowered(MREQ()); } - - [[nodiscard]] bool requestingRead() const { return lowered(RD()); } - [[nodiscard]] bool requestingWrite() const { return lowered(WR()); } + [[nodiscard]] auto requestingRead() const { return lowered(RD()); } + [[nodiscard]] auto requestingWrite() const { return lowered(WR()); } // ** From the Z80 CPU User Manual // RFSH.Refresh(output, active Low). RFSH, together with MREQ, indicates that the lower @@ -150,11 +144,6 @@ namespace EightBit { DEFINE_PIN_ACTIVATOR_LOW(RD) DEFINE_PIN_ACTIVATOR_LOW(WR) - auto readBusDataM1() { - _ActivateM1 m1(*this); - return BUS().DATA(); - } - enum { BC_IDX, DE_IDX, HL_IDX }; std::array, 2> m_registers; @@ -179,194 +168,39 @@ namespace EightBit { bool m_prefixFD = false; int8_t m_displacement = 0; - bool m_displaced = false; void handleNMI(); + void resetPrefixes(); + + [[nodiscard]] auto displaced() const { return m_prefixDD || m_prefixFD; } [[nodiscard]] uint16_t displacedAddress(); void fetchDisplacement(); [[nodiscard]] uint8_t fetchOpCode(); + uint8_t readBusDataM1(); + typedef std::function addresser_t; + void loadAccumulatorIndirect(addresser_t addresser); + void storeAccumulatorIndirect(addresser_t addresser); + typedef std::function reader_t; + void readInternalRegister(reader_t reader); - void loadAccumulatorIndirect(addresser_t addresser) { - (MEMPTR() = BUS().ADDRESS() = addresser())++; - A() = memoryRead(); - } + [[nodiscard]] register16_t& HL2(); + [[nodiscard]] register16_t& RP(int rp); + [[nodiscard]] register16_t& RP2(int rp); - void storeAccumulatorIndirect(addresser_t addresser) { - (MEMPTR() = BUS().ADDRESS() = addresser())++; - MEMPTR().high = BUS().DATA() = A(); - memoryWrite(); - } + [[nodiscard]] uint8_t R(int r); + void R(int r, uint8_t value); + void R2(int r, uint8_t value); - void readInternalRegister(reader_t reader) { - F() = adjustSZXY(F(), A() = reader()); - F() = clearBit(F(), NF | HC); - F() = setBit(F(), PF, IFF2()); - tick(); - } - - [[nodiscard]] auto& HL2() { - if (LIKELY(!m_displaced)) - return HL(); - if (m_prefixDD) - return IX(); - // Must be FD prefix - return IY(); - } - - [[nodiscard]] auto& RP(const int rp) { - ASSUME(rp >= 0); - ASSUME(rp <= 3); - switch (rp) { - case 0b00: - return BC(); - case 0b01: - return DE(); - case 0b10: - return HL2(); - case 0b11: - return SP(); - default: - UNREACHABLE; - } - } - - [[nodiscard]] auto& RP2(const int rp) { - ASSUME(rp >= 0); - ASSUME(rp <= 3); - switch (rp) { - case 0b00: - return BC(); - case 0b01: - return DE(); - case 0b10: - return HL2(); - case 0b11: - return AF(); - default: - UNREACHABLE; - } - } - - [[nodiscard]] auto R(const int r) { - ASSUME(r >= 0); - ASSUME(r <= 7); - switch (r) { - case 0: - return B(); - case 1: - return C(); - case 2: - return D(); - case 3: - return E(); - case 4: - return HL2().high; - case 5: - return HL2().low; - case 6: - return IntelProcessor::memoryRead(UNLIKELY(m_displaced) ? displacedAddress() : HL().word); - case 7: - return A(); - default: - UNREACHABLE; - } - } - - void R(const int r, const uint8_t value) { - ASSUME(r >= 0); - ASSUME(r <= 7); - 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(m_displaced) ? displacedAddress() : HL().word, value); - break; - case 7: - A() = value; - break; - default: - UNREACHABLE; - } - } - - void R2(const int r, const uint8_t value) { - ASSUME(r >= 0); - ASSUME(r <= 7); - switch (r) { - case 0: - B() = value; - break; - case 1: - C() = value; - break; - case 2: - D() = value; - break; - case 3: - E() = value; - break; - case 4: - H() = value; - break; - case 5: - L() = value; - break; - case 6: - IntelProcessor::memoryWrite(HL(), value); - break; - case 7: - A() = value; - break; - default: - UNREACHABLE; - } - } - - [[nodiscard]] static auto adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { - return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation)); - } - - [[nodiscard]] static auto adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { - return setBit(f, HC, calculateHalfCarrySub(before, value, calculation)); - } - - [[nodiscard]] static uint8_t adjustOverflowAdd(uint8_t f, const uint8_t before, const uint8_t value, const uint8_t calculation) { - return adjustOverflowAdd(f, before & SF, value & SF, calculation & SF); - } - - [[nodiscard]] static uint8_t adjustOverflowAdd(uint8_t f, const int beforeNegative, const int valueNegative, const int afterNegative) { - const auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative); - return setBit(f, VF, overflow); - } - - [[nodiscard]] static uint8_t adjustOverflowSub(uint8_t f, const uint8_t before, const uint8_t value, const uint8_t calculation) { - return adjustOverflowSub(f, before & SF, value & SF, calculation & SF); - } - - [[nodiscard]] static uint8_t adjustOverflowSub(uint8_t f, const int beforeNegative, const int valueNegative, const int afterNegative) { - const auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative); - return setBit(f, VF, overflow); - } + [[nodiscard]] static uint8_t adjustHalfCarryAdd(uint8_t f, uint8_t before, uint8_t value, int calculation); + [[nodiscard]] static uint8_t adjustHalfCarrySub(uint8_t f, uint8_t before, uint8_t value, int calculation); + [[nodiscard]] static uint8_t adjustOverflowAdd(uint8_t f, uint8_t before, uint8_t value, uint8_t calculation); + [[nodiscard]] static uint8_t adjustOverflowAdd(uint8_t f, int beforeNegative, int valueNegative, int afterNegative); + [[nodiscard]] static uint8_t adjustOverflowSub(uint8_t f, uint8_t before, uint8_t value, uint8_t calculation); + [[nodiscard]] static uint8_t adjustOverflowSub(uint8_t f, int beforeNegative, int valueNegative, int afterNegative); [[nodiscard]] static bool convertCondition(uint8_t f, int flag); @@ -420,41 +254,41 @@ namespace EightBit { static void scf(uint8_t& f, uint8_t operand); static void ccf(uint8_t& f, uint8_t operand); - static uint8_t cpl(uint8_t& f, uint8_t operand); + [[nodiscard]] static uint8_t cpl(uint8_t& f, uint8_t operand); void xhtl(register16_t& exchange); void blockCompare(uint8_t& f, uint8_t value, register16_t source, register16_t& counter); void cpi(uint8_t& f, uint8_t value); - bool cpir(uint8_t& f, uint8_t value); + [[nodiscard]] bool cpir(uint8_t& f, uint8_t value); void cpd(uint8_t& f, uint8_t value); - bool cpdr(uint8_t& f, uint8_t value); + [[nodiscard]] bool cpdr(uint8_t& f, uint8_t value); void blockLoad(uint8_t& f, uint8_t a, register16_t source, register16_t destination, register16_t& counter); void ldi(uint8_t& f, uint8_t a); - bool ldir(uint8_t& f, uint8_t a); + [[nodiscard]] bool ldir(uint8_t& f, uint8_t a); void ldd(uint8_t& f, uint8_t a); - bool lddr(uint8_t& f, uint8_t a); + [[nodiscard]] bool lddr(uint8_t& f, uint8_t a); void blockIn(register16_t& source, register16_t destination); void ini(); - bool inir(); + [[nodiscard]] bool inir(); void ind(); - bool indr(); + [[nodiscard]] bool indr(); void blockOut(register16_t source, register16_t& destination); void outi(); - bool otir(); + [[nodiscard]] bool otir(); void outd(); - bool otdr(); + [[nodiscard]] bool otdr(); [[nodiscard]] uint8_t neg(uint8_t& f, uint8_t operand); diff --git a/Z80/src/Z80.cpp b/Z80/src/Z80.cpp index d65d852..2149e51 100644 --- a/Z80/src/Z80.cpp +++ b/Z80/src/Z80.cpp @@ -25,7 +25,7 @@ EightBit::Z80::Z80(Bus& bus) AF() = IX() = IY() = BC() = DE() = HL() = Mask16; - m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; + resetPrefixes(); }); RaisedM1.connect([this](EventArgs) { @@ -186,9 +186,33 @@ uint8_t EightBit::Z80::decrement(uint8_t& f, const uint8_t operand) { return result; } +uint8_t EightBit::Z80::adjustHalfCarryAdd(const uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation)); +} + +uint8_t EightBit::Z80::adjustHalfCarrySub(const uint8_t f, const uint8_t before, const uint8_t value, const int calculation) { + return setBit(f, HC, calculateHalfCarrySub(before, value, calculation)); +} + +uint8_t EightBit::Z80::adjustOverflowAdd(const uint8_t f, const uint8_t before, const uint8_t value, const uint8_t calculation) { + return adjustOverflowAdd(f, before & SF, value & SF, calculation & SF); +} + +uint8_t EightBit::Z80::adjustOverflowAdd(const uint8_t f, const int beforeNegative, const int valueNegative, const int afterNegative) { + const auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative); + return setBit(f, VF, overflow); +} + +uint8_t EightBit::Z80::adjustOverflowSub(const uint8_t f, const uint8_t before, const uint8_t value, const uint8_t calculation) { + return adjustOverflowSub(f, before & SF, value & SF, calculation & SF); +} + +uint8_t EightBit::Z80::adjustOverflowSub(const uint8_t f, const int beforeNegative, const int valueNegative, const int afterNegative) { + const auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative); + return setBit(f, VF, overflow); +} + bool EightBit::Z80::convertCondition(const uint8_t f, int flag) { - ASSUME(flag >= 0); - ASSUME(flag <= 7); switch (flag) { case 0: return !(f & ZF); @@ -447,8 +471,6 @@ uint8_t EightBit::Z80::srl(uint8_t& f, const uint8_t operand) { } void EightBit::Z80::bit(uint8_t& f, const int n, const uint8_t operand) { - ASSUME(n >= 0); - ASSUME(n <= 7); f = setBit(f, HC); f = clearBit(f, NF); const auto discarded = operand & Chip::bit(n); @@ -457,14 +479,10 @@ void EightBit::Z80::bit(uint8_t& f, const int n, const uint8_t operand) { } uint8_t EightBit::Z80::res(const int n, const uint8_t operand) { - ASSUME(n >= 0); - ASSUME(n <= 7); return clearBit(operand, Chip::bit(n)); } uint8_t EightBit::Z80::set(const int n, const uint8_t operand) { - ASSUME(n >= 0); - ASSUME(n <= 7); return setBit(operand, Chip::bit(n)); } @@ -584,7 +602,7 @@ bool EightBit::Z80::cpdr(uint8_t& f, uint8_t value) { void EightBit::Z80::blockLoad(uint8_t& f, const uint8_t a, const register16_t source, const register16_t destination, register16_t& counter) { const auto value = IntelProcessor::memoryRead(source); - IntelProcessor::memoryWrite(destination, value); + IntelProcessor::memoryWrite(destination); const auto xy = a + value; f = setBit(f, XF, xy & Bit3); f = setBit(f, YF, xy & Bit1); @@ -748,8 +766,13 @@ uint8_t EightBit::Z80::portRead() { // +void EightBit::Z80::resetPrefixes() { + m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; +} + +// + uint16_t EightBit::Z80::displacedAddress() { - assert(m_displaced); return MEMPTR().word = (m_prefixDD ? IX() : IY()).word + m_displacement; } @@ -757,6 +780,13 @@ void EightBit::Z80::fetchDisplacement() { m_displacement = fetchByte(); } +// + +uint8_t EightBit::Z80::readBusDataM1() { + _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 @@ -803,11 +833,152 @@ uint8_t EightBit::Z80::fetchOpCode() { return returned; } +void EightBit::Z80::loadAccumulatorIndirect(addresser_t addresser) { + (MEMPTR() = BUS().ADDRESS() = addresser())++; + A() = memoryRead(); +} + +void EightBit::Z80::storeAccumulatorIndirect(addresser_t addresser) { + (MEMPTR() = BUS().ADDRESS() = addresser())++; + MEMPTR().high = BUS().DATA() = A(); + memoryWrite(); +} + +void EightBit::Z80::readInternalRegister(reader_t reader) { + F() = adjustSZXY(F(), A() = reader()); + F() = clearBit(F(), NF | HC); + F() = setBit(F(), PF, IFF2()); + tick(); +} + +EightBit::register16_t& EightBit::Z80::HL2() { + if (UNLIKELY(m_prefixDD)) + return IX(); + if (UNLIKELY(m_prefixFD)) + return IY(); + return HL(); +} + +EightBit::register16_t& EightBit::Z80::RP(const int rp) { + switch (rp) { + case 0b00: + return BC(); + case 0b01: + return DE(); + case 0b10: + return HL2(); + case 0b11: + return SP(); + default: + UNREACHABLE; + } +} + +EightBit::register16_t& EightBit::Z80::RP2(const int rp) { + switch (rp) { + case 0b00: + return BC(); + case 0b01: + return DE(); + case 0b10: + return HL2(); + case 0b11: + return AF(); + default: + UNREACHABLE; + } +} + +uint8_t EightBit::Z80::R(const int r) { + switch (r) { + case 0: + return B(); + case 1: + return C(); + case 2: + return D(); + case 3: + return E(); + case 4: + return HL2().high; + case 5: + return HL2().low; + case 6: + return IntelProcessor::memoryRead(UNLIKELY(displaced()) ? displacedAddress() : HL().word); + case 7: + return A(); + default: + UNREACHABLE; + } +} + +void EightBit::Z80::R(const int r, const uint8_t value) { + 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().word, value); + break; + case 7: + A() = value; + break; + default: + UNREACHABLE; + } +} + +void EightBit::Z80::R2(const int r, const uint8_t value) { + switch (r) { + case 0: + B() = value; + break; + case 1: + C() = value; + break; + case 2: + D() = value; + break; + case 3: + E() = value; + break; + case 4: + H() = value; + break; + case 5: + L() = value; + break; + case 6: + IntelProcessor::memoryWrite(HL(), value); + break; + case 7: + A() = value; + break; + default: + UNREACHABLE; + } +} + int EightBit::Z80::step() { resetCycles(); ExecutingInstruction.fire(*this); if (LIKELY(powered())) { - m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false; + resetPrefixes(); bool handled = false; if (lowered(RESET())) { handleRESET(); @@ -855,10 +1026,10 @@ int EightBit::Z80::execute() { void EightBit::Z80::executeCB(const int x, const int y, const int z) { const bool memoryZ = z == 6; - const bool indirect = (!m_displaced && memoryZ) || m_displaced; + const bool indirect = (!displaced() && memoryZ) || displaced(); uint8_t operand; - if (m_displaced) { + if (displaced()) { tick(2); operand = IntelProcessor::memoryRead(displacedAddress()); } else { @@ -915,7 +1086,7 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) { } if (update) { tick(); - if (m_displaced) { + if (displaced()) { IntelProcessor::memoryWrite(operand); if (!memoryZ) R2(z, operand); @@ -1240,7 +1411,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in tick(2); break; case 4: { // 8-bit INC - if (memoryY && m_displaced) { + if (memoryY && displaced()) { fetchDisplacement(); tick(5); } @@ -1251,7 +1422,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; } case 5: { // 8-bit DEC - if (memoryY && m_displaced) { + if (memoryY && displaced()) { fetchDisplacement(); tick(5); } @@ -1262,10 +1433,10 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; } case 6: { // 8-bit load immediate - if (memoryY && m_displaced) + if (memoryY && displaced()) fetchDisplacement(); const auto value = fetchByte(); - if (m_displaced) + if (displaced()) tick(2); R(y, value); // LD r,n break; @@ -1309,19 +1480,19 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in lowerHALT(); } else { bool normal = true; - if (m_displaced) { + if (displaced()) { if (memoryZ || memoryY) fetchDisplacement(); if (memoryZ) { switch (y) { case 4: - if (m_displaced) + if (displaced()) tick(5); H() = R(z); normal = false; break; case 5: - if (m_displaced) + if (displaced()) tick(5); L() = R(z); normal = false; @@ -1331,13 +1502,13 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in if (memoryY) { switch (z) { case 4: - if (m_displaced) + if (displaced()) tick(5); R(y, H()); normal = false; break; case 5: - if (m_displaced) + if (displaced()) tick(5); R(y, L()); normal = false; @@ -1346,14 +1517,14 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in } } if (normal) { - if (m_displaced) + if (displaced()) tick(5); R(y, R(z)); } } break; case 2: { // Operate on accumulator and register/memory location - if (memoryZ && m_displaced) { + if (memoryZ && displaced()) { fetchDisplacement(); tick(5); } @@ -1431,7 +1602,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in break; case 1: // CB prefix m_prefixCB = true; - if (m_displaced) { + if (displaced()) { fetchDisplacement(); IntelProcessor::execute(fetchByte()); } else { @@ -1474,7 +1645,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in call(MEMPTR() = fetchWord()); break; case 1: // DD prefix - m_displaced = m_prefixDD = true; + m_prefixDD = true; IntelProcessor::execute(fetchOpCode()); break; case 2: // ED prefix @@ -1482,7 +1653,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in IntelProcessor::execute(fetchOpCode()); break; case 3: // FD prefix - m_displaced = m_prefixFD = true; + m_prefixFD = true; IntelProcessor::execute(fetchOpCode()); break; default: diff --git a/inc/ClockedChip.h b/inc/ClockedChip.h index 611ec1c..3613079 100644 --- a/inc/ClockedChip.h +++ b/inc/ClockedChip.h @@ -11,12 +11,13 @@ namespace EightBit { Signal Ticked; - void tick(const int extra) { for (int i = 0; i < extra; ++i) tick(); } - void tick() { ++m_cycles; Ticked.fire(); } [[nodiscard]] auto cycles() const noexcept { return m_cycles; } + void tick(int extra); + void tick(); + protected: - void resetCycles() noexcept { m_cycles = 0; } + void resetCycles() noexcept; private: int m_cycles = 0; diff --git a/inc/Processor.h b/inc/Processor.h index 2be17fb..80c5047 100644 --- a/inc/Processor.h +++ b/inc/Processor.h @@ -40,6 +40,7 @@ namespace EightBit { virtual void handleINT(); void memoryWrite(register16_t address, uint8_t data); + void memoryWrite(register16_t address); void memoryWrite(uint8_t data); virtual void memoryWrite(); virtual void busWrite(); @@ -48,17 +49,10 @@ namespace EightBit { virtual uint8_t memoryRead(); virtual uint8_t busRead(); - auto getBytePaged(const uint8_t page, const uint8_t offset) { - return memoryRead(register16_t(offset, page)); - } + uint8_t getBytePaged(uint8_t page, uint8_t offset); + void setBytePaged(uint8_t page, uint8_t offset, uint8_t value); - void setBytePaged(const uint8_t page, const uint8_t offset, const uint8_t value) { - memoryWrite(register16_t(offset, page), value); - } - - auto fetchByte() { - return memoryRead(PC()++); - } + uint8_t fetchByte(); [[nodiscard]] virtual register16_t getWord() = 0; virtual void setWord(register16_t value) = 0; @@ -74,20 +68,10 @@ namespace EightBit { virtual void pushWord(register16_t value) = 0; [[nodiscard]] virtual register16_t popWord() = 0; - [[nodiscard]] auto getWord(const register16_t address) { - BUS().ADDRESS() = address; - return getWord(); - } - - void setWord(const register16_t address, const register16_t value) { - BUS().ADDRESS() = address; - setWord(value); - } - - void jump(const register16_t destination) noexcept { - PC() = destination; - } + register16_t getWord(register16_t address); + void setWord(register16_t address, register16_t value); + void jump(const register16_t destination) noexcept; virtual void call(register16_t destination); virtual void ret(); diff --git a/src/ClockedChip.cpp b/src/ClockedChip.cpp new file mode 100644 index 0000000..86f5bef --- /dev/null +++ b/src/ClockedChip.cpp @@ -0,0 +1,16 @@ +#include "stdafx.h" +#include "ClockedChip.h" + +void EightBit::ClockedChip::tick(const int extra) { + for (int i = 0; i < extra; ++i) + tick(); +} + +void EightBit::ClockedChip::tick() { + ++m_cycles; + Ticked.fire(); +} + +void EightBit::ClockedChip::resetCycles() noexcept { + m_cycles = 0; +} diff --git a/src/EightBit.vcxproj b/src/EightBit.vcxproj index 1c06082..45ab58e 100644 --- a/src/EightBit.vcxproj +++ b/src/EightBit.vcxproj @@ -178,6 +178,7 @@ + diff --git a/src/EightBit.vcxproj.filters b/src/EightBit.vcxproj.filters index d831fb2..905720c 100644 --- a/src/EightBit.vcxproj.filters +++ b/src/EightBit.vcxproj.filters @@ -121,5 +121,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 795bea3..f8f28ab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ LIB = libeightbit.a CXXFLAGS = -I ../inc -CXXFILES = BigEndianProcessor.cpp Bus.cpp Device.cpp EventArgs.cpp InputOutput.cpp IntelHexFile.cpp IntelProcessor.cpp LittleEndianProcessor.cpp Memory.cpp Processor.cpp Ram.cpp Rom.cpp UnusedMemory.cpp +CXXFILES = BigEndianProcessor.cpp Bus.cpp ClockedChip.cpp Device.cpp EventArgs.cpp InputOutput.cpp IntelHexFile.cpp IntelProcessor.cpp LittleEndianProcessor.cpp Memory.cpp Processor.cpp Ram.cpp Rom.cpp UnusedMemory.cpp include ../compile.mk include ../lib_build.mk diff --git a/src/Processor.cpp b/src/Processor.cpp index 1709b0a..e43ba5b 100644 --- a/src/Processor.cpp +++ b/src/Processor.cpp @@ -21,6 +21,11 @@ void EightBit::Processor::memoryWrite(const register16_t address, const uint8_t memoryWrite(data); } +void EightBit::Processor::memoryWrite(const register16_t address) { + BUS().ADDRESS() = address; + memoryWrite(); +} + void EightBit::Processor::memoryWrite(const uint8_t data) { BUS().DATA() = data; memoryWrite(); @@ -47,6 +52,28 @@ uint8_t EightBit::Processor::busRead() { return BUS().read(); } +uint8_t EightBit::Processor::getBytePaged(const uint8_t page, const uint8_t offset) { + return memoryRead(register16_t(offset, page)); +} + +void EightBit::Processor::setBytePaged(const uint8_t page, const uint8_t offset, const uint8_t value) { + memoryWrite(register16_t(offset, page), value); +} + +uint8_t EightBit::Processor::fetchByte() { + return memoryRead(PC()++); +} + +EightBit::register16_t EightBit::Processor::getWord(const register16_t address) { + BUS().ADDRESS() = address; + return getWord(); +} + +void EightBit::Processor::setWord(const register16_t address, const register16_t value) { + BUS().ADDRESS() = address; + setWord(value); +} + int EightBit::Processor::run(const int limit) { int current = 0; while (LIKELY(powered() && (current < limit))) @@ -67,6 +94,10 @@ int8_t EightBit::Processor::signExtend(const int b, uint8_t x) noexcept { return result; } +void EightBit::Processor::jump(const register16_t destination) noexcept { + PC() = destination; +} + void EightBit::Processor::call(const register16_t destination) { pushWord(PC()); jump(destination);