Tidy up some C++ code (concentrating on the Z80 at the moment).

Signed-off-by: Adrian Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2021-01-09 08:41:48 +00:00
parent 26cc613c66
commit 4d2d1d214a
9 changed files with 301 additions and 260 deletions

View File

@ -1,14 +1,13 @@
#pragma once
#include <cstdint>
#include <cassert>
#include <stdexcept>
#include <array>
#include <functional>
#include <IntelProcessor.h>
#include <EventArgs.h>
#include <Signal.h>
#include <Register.h>
#include <EightBitCompilerDefinitions.h>
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<std::array<register16_t, 3>, 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<register16_t(void)> addresser_t;
void loadAccumulatorIndirect(addresser_t addresser);
void storeAccumulatorIndirect(addresser_t addresser);
typedef std::function<uint8_t(void)> 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<Z80>(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);

View File

@ -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<Z80>(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:

View File

@ -11,12 +11,13 @@ namespace EightBit {
Signal<EventArgs> 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;

View File

@ -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();

16
src/ClockedChip.cpp Normal file
View File

@ -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;
}

View File

@ -178,6 +178,7 @@
<ItemGroup>
<ClCompile Include="BigEndianProcessor.cpp" />
<ClCompile Include="Bus.cpp" />
<ClCompile Include="ClockedChip.cpp" />
<ClCompile Include="Device.cpp" />
<ClCompile Include="EventArgs.cpp" />
<ClCompile Include="InputOutput.cpp" />

View File

@ -121,5 +121,8 @@
<ClCompile Include="IntelHexFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClockedChip.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -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

View File

@ -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);