mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-02-01 00:34:06 +00:00
Tidy return parameter usage a little within the EightBit library.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
deb9a6d43c
commit
9960ad6012
@ -51,31 +51,31 @@ namespace EightBit {
|
||||
Signal<Z80> ExecutingInstruction;
|
||||
Signal<Z80> ExecutedInstruction;
|
||||
|
||||
auto& NMI() { return m_nmiLine; } // In
|
||||
auto& M1() { return m_m1Line; } // Out
|
||||
[[nodiscard]] auto& NMI() { return m_nmiLine; } // In
|
||||
[[nodiscard]] auto& M1() { return m_m1Line; } // Out
|
||||
|
||||
int execute(uint8_t opcode) final;
|
||||
int step() final;
|
||||
void powerOn() final;
|
||||
|
||||
register16_t& AF() final;
|
||||
register16_t& BC() final;
|
||||
register16_t& DE() final;
|
||||
register16_t& HL() final;
|
||||
[[nodiscard]] register16_t& AF() final;
|
||||
[[nodiscard]] register16_t& BC() final;
|
||||
[[nodiscard]] register16_t& DE() final;
|
||||
[[nodiscard]] register16_t& HL() final;
|
||||
|
||||
auto& IX() { return m_ix; }
|
||||
auto& IXH() { return IX().high; }
|
||||
auto& IXL() { return IX().low; }
|
||||
[[nodiscard]] auto& IX() { return m_ix; }
|
||||
[[nodiscard]] auto& IXH() { return IX().high; }
|
||||
[[nodiscard]] auto& IXL() { return IX().low; }
|
||||
|
||||
auto& IY() { return m_iy; }
|
||||
auto& IYH() { return IY().high; }
|
||||
auto& IYL() { return IY().low; }
|
||||
[[nodiscard]] auto& IY() { return m_iy; }
|
||||
[[nodiscard]] auto& IYH() { return IY().high; }
|
||||
[[nodiscard]] auto& IYL() { return IY().low; }
|
||||
|
||||
auto& REFRESH() { return m_refresh; }
|
||||
auto& IV() { return iv; }
|
||||
auto& IM() { return m_interruptMode; }
|
||||
auto& IFF1() { return m_iff1; }
|
||||
auto& IFF2() { return m_iff2; }
|
||||
[[nodiscard]] auto& REFRESH() { return m_refresh; }
|
||||
[[nodiscard]] auto& IV() { return iv; }
|
||||
[[nodiscard]] auto& IM() { return m_interruptMode; }
|
||||
[[nodiscard]] auto& IFF1() { return m_iff1; }
|
||||
[[nodiscard]] auto& IFF2() { return m_iff2; }
|
||||
|
||||
void exx() {
|
||||
m_registerSet ^= 1;
|
||||
@ -123,7 +123,7 @@ namespace EightBit {
|
||||
|
||||
void handleNMI();
|
||||
|
||||
uint16_t displacedAddress() {
|
||||
[[nodiscard]] uint16_t displacedAddress() {
|
||||
assert(m_displaced);
|
||||
return MEMPTR().word = (m_prefixDD ? IX() : IY()).word + m_displacement;
|
||||
}
|
||||
@ -132,7 +132,7 @@ namespace EightBit {
|
||||
m_displacement = fetchByte();
|
||||
}
|
||||
|
||||
auto& HL2() {
|
||||
[[nodiscard]] auto& HL2() {
|
||||
if (LIKELY(!m_displaced))
|
||||
return HL();
|
||||
if (m_prefixDD)
|
||||
@ -141,7 +141,7 @@ namespace EightBit {
|
||||
return IY();
|
||||
}
|
||||
|
||||
auto& RP(const int rp) {
|
||||
[[nodiscard]] auto& RP(const int rp) {
|
||||
ASSUME(rp >= 0);
|
||||
ASSUME(rp <= 3);
|
||||
switch (rp) {
|
||||
@ -158,7 +158,7 @@ namespace EightBit {
|
||||
}
|
||||
}
|
||||
|
||||
auto& RP2(const int rp) {
|
||||
[[nodiscard]] auto& RP2(const int rp) {
|
||||
ASSUME(rp >= 0);
|
||||
ASSUME(rp <= 3);
|
||||
switch (rp) {
|
||||
@ -175,7 +175,7 @@ namespace EightBit {
|
||||
}
|
||||
}
|
||||
|
||||
auto R(const int r) {
|
||||
[[nodiscard]] auto R(const int r) {
|
||||
ASSUME(r >= 0);
|
||||
ASSUME(r <= 7);
|
||||
switch (r) {
|
||||
@ -233,7 +233,7 @@ namespace EightBit {
|
||||
}
|
||||
}
|
||||
|
||||
auto R2(const int r) {
|
||||
[[nodiscard]] auto R2(const int r) {
|
||||
ASSUME(r >= 0);
|
||||
ASSUME(r <= 7);
|
||||
switch (r) {
|
||||
@ -317,14 +317,14 @@ namespace EightBit {
|
||||
setFlag(f, VF, overflow);
|
||||
}
|
||||
|
||||
void subtract(uint8_t& operand, uint8_t value, int carry = 0);
|
||||
uint8_t subtract(uint8_t operand, uint8_t value, int carry = 0);
|
||||
|
||||
void executeCB(int x, int y, int z);
|
||||
void executeED(int x, int y, int z, int p, int q);
|
||||
void executeOther(int x, int y, int z, int p, int q);
|
||||
|
||||
void increment(uint8_t& operand);
|
||||
void decrement(uint8_t& operand);
|
||||
[[nodiscard]] uint8_t increment(uint8_t operand);
|
||||
[[nodiscard]] uint8_t decrement(uint8_t operand);
|
||||
|
||||
void di();
|
||||
void ei();
|
||||
@ -350,18 +350,18 @@ namespace EightBit {
|
||||
void orr(uint8_t value);
|
||||
void compare(uint8_t value);
|
||||
|
||||
void rlc(uint8_t& operand);
|
||||
void rrc(uint8_t& operand);
|
||||
void rl(uint8_t& operand);
|
||||
void rr(uint8_t& operand);
|
||||
void sla(uint8_t& operand);
|
||||
void sra(uint8_t& operand);
|
||||
void sll(uint8_t& operand);
|
||||
void srl(uint8_t& operand);
|
||||
[[nodiscard]] uint8_t rlc(uint8_t operand);
|
||||
[[nodiscard]] uint8_t rrc(uint8_t operand);
|
||||
[[nodiscard]] uint8_t rl(uint8_t operand);
|
||||
[[nodiscard]] uint8_t rr(uint8_t operand);
|
||||
[[nodiscard]] uint8_t sla(uint8_t operand);
|
||||
[[nodiscard]] uint8_t sra(uint8_t operand);
|
||||
[[nodiscard]] uint8_t sll(uint8_t operand);
|
||||
[[nodiscard]] uint8_t srl(uint8_t operand);
|
||||
|
||||
uint8_t bit(int n, uint8_t operand);
|
||||
static uint8_t res(int n, uint8_t operand);
|
||||
static uint8_t set(int n, uint8_t operand);
|
||||
[[nodiscard]] uint8_t bit(int n, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t res(int n, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t set(int n, uint8_t operand);
|
||||
|
||||
void daa();
|
||||
|
||||
|
131
Z80/src/Z80.cpp
131
Z80/src/Z80.cpp
@ -91,18 +91,22 @@ void EightBit::Z80::ei() {
|
||||
IFF1() = IFF2() = true;
|
||||
}
|
||||
|
||||
void EightBit::Z80::increment(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::increment(const uint8_t operand) {
|
||||
clearFlag(F(), NF);
|
||||
adjustSZXY<Z80>(F(), ++operand);
|
||||
setFlag(F(), VF, operand == Bit7);
|
||||
clearFlag(F(), HC, lowNibble(operand));
|
||||
const uint8_t result = operand + 1;
|
||||
adjustSZXY<Z80>(F(), result);
|
||||
setFlag(F(), VF, result == Bit7);
|
||||
clearFlag(F(), HC, lowNibble(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::decrement(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::decrement(const uint8_t operand) {
|
||||
setFlag(F(), NF);
|
||||
clearFlag(F(), HC, lowNibble(operand));
|
||||
adjustSZXY<Z80>(F(), --operand);
|
||||
setFlag(F(), VF, operand == Mask7);
|
||||
const uint8_t result = operand - 1;
|
||||
adjustSZXY<Z80>(F(), result);
|
||||
setFlag(F(), VF, result == Mask7);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool EightBit::Z80::jrConditionalFlag(const int flag) {
|
||||
@ -284,20 +288,23 @@ void EightBit::Z80::adc(const uint8_t value) {
|
||||
add(value, F() & CF);
|
||||
}
|
||||
|
||||
void EightBit::Z80::subtract(uint8_t& operand, const uint8_t value, const int carry) {
|
||||
uint8_t EightBit::Z80::subtract(const uint8_t operand, const uint8_t value, const int carry) {
|
||||
|
||||
const register16_t result = operand - value - carry;
|
||||
const register16_t subtraction = operand - value - carry;
|
||||
const auto result = subtraction.low;
|
||||
|
||||
adjustHalfCarrySub(F(), operand, value, result.low);
|
||||
adjustOverflowSub(F(), operand, value, result.low);
|
||||
adjustHalfCarrySub(F(), operand, value, result);
|
||||
adjustOverflowSub(F(), operand, value, result);
|
||||
|
||||
setFlag(F(), NF);
|
||||
setFlag(F(), CF, result.high & CF);
|
||||
adjustSZ<Z80>(F(), operand = result.low);
|
||||
setFlag(F(), CF, subtraction.high & CF);
|
||||
adjustSZ<Z80>(F(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::sub(const uint8_t value, const int carry) {
|
||||
subtract(A(), value, carry);
|
||||
A() = subtract(A(), value, carry);
|
||||
adjustXY<Z80>(F(), A());
|
||||
}
|
||||
|
||||
@ -322,65 +329,79 @@ void EightBit::Z80::orr(const uint8_t value) {
|
||||
}
|
||||
|
||||
void EightBit::Z80::compare(const uint8_t value) {
|
||||
auto original = A();
|
||||
subtract(original, value);
|
||||
subtract(A(), value);
|
||||
adjustXY<Z80>(F(), value);
|
||||
}
|
||||
|
||||
void EightBit::Z80::rlc(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::rlc(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
const auto carry = operand & Bit7;
|
||||
setFlag(F(), CF, carry);
|
||||
adjustXY<Z80>(F(), operand = (operand << 1) | (carry >> 7));
|
||||
const uint8_t result = (operand << 1) | (carry >> 7);
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::rrc(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::rrc(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
const auto carry = operand & Bit0;
|
||||
setFlag(F(), CF, carry);
|
||||
adjustXY<Z80>(F(), operand = (operand >> 1) | (carry << 7));
|
||||
const uint8_t result = (operand >> 1) | (carry << 7);
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::rl(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::rl(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
const auto carry = F() & CF;
|
||||
setFlag(F(), CF, operand & Bit7);
|
||||
adjustXY<Z80>(F(), operand = (operand << 1) | carry);
|
||||
const uint8_t result = (operand << 1) | carry;
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::rr(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::rr(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
const auto carry = F() & CF;
|
||||
setFlag(F(), CF, operand & Bit0);
|
||||
adjustXY<Z80>(F(), operand = (operand >> 1) | (carry << 7));
|
||||
const uint8_t result = (operand >> 1) | (carry << 7);
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void EightBit::Z80::sla(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::sla(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
setFlag(F(), CF, operand & Bit7);
|
||||
adjustXY<Z80>(F(), operand <<= 1);
|
||||
const uint8_t result = operand << 1;
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::sra(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::sra(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
setFlag(F(), CF, operand & Bit0);
|
||||
adjustXY<Z80>(F(), operand = (operand >> 1) | (operand & Bit7));
|
||||
const uint8_t result = (operand >> 1) | (operand & Bit7);
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::sll(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::sll(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
setFlag(F(), CF, operand & Bit7);
|
||||
adjustXY<Z80>(F(), operand = (operand << 1) | Bit0);
|
||||
const uint8_t result = (operand << 1) | Bit0;
|
||||
adjustXY<Z80>(F(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::Z80::srl(uint8_t& operand) {
|
||||
uint8_t EightBit::Z80::srl(const uint8_t operand) {
|
||||
clearFlag(F(), NF | HC);
|
||||
setFlag(F(), CF, operand & Bit0);
|
||||
operand = (operand >> 1) & ~Bit7;
|
||||
adjustXY<Z80>(F(), operand);
|
||||
setFlag(F(), ZF, operand);
|
||||
const uint8_t result = (operand >> 1) & ~Bit7;
|
||||
adjustXY<Z80>(F(), result);
|
||||
setFlag(F(), ZF, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::Z80::bit(const int n, const uint8_t operand) {
|
||||
@ -544,7 +565,7 @@ void EightBit::Z80::blockIn(register16_t& source, const register16_t destination
|
||||
MEMPTR() = BUS().ADDRESS() = source;
|
||||
const auto value = readPort();
|
||||
BUS().write(destination, value);
|
||||
decrement(source.high);
|
||||
source.high = decrement(source.high);
|
||||
setFlag(F(), NF);
|
||||
}
|
||||
|
||||
@ -572,7 +593,7 @@ void EightBit::Z80::blockOut(const register16_t source, register16_t& destinatio
|
||||
const auto value = BUS().read(source);
|
||||
BUS().ADDRESS() = destination;
|
||||
writePort();
|
||||
decrement(destination.high);
|
||||
destination.high = decrement(destination.high);
|
||||
MEMPTR() = destination;
|
||||
setFlag(F(), NF, value & Bit7);
|
||||
setFlag(F(), HC | CF, (L() + value) > 0xff);
|
||||
@ -708,28 +729,28 @@ void EightBit::Z80::executeCB(const int x, const int y, const int z) {
|
||||
auto operand = LIKELY(!m_displaced) ? R(z) : BUS().read(displacedAddress());
|
||||
switch (y) {
|
||||
case 0:
|
||||
rlc(operand);
|
||||
operand = rlc(operand);
|
||||
break;
|
||||
case 1:
|
||||
rrc(operand);
|
||||
operand = rrc(operand);
|
||||
break;
|
||||
case 2:
|
||||
rl(operand);
|
||||
operand = rl(operand);
|
||||
break;
|
||||
case 3:
|
||||
rr(operand);
|
||||
operand = rr(operand);
|
||||
break;
|
||||
case 4:
|
||||
sla(operand);
|
||||
operand = sla(operand);
|
||||
break;
|
||||
case 5:
|
||||
sra(operand);
|
||||
operand = sra(operand);
|
||||
break;
|
||||
case 6:
|
||||
sll(operand);
|
||||
operand = sll(operand);
|
||||
break;
|
||||
case 7:
|
||||
srl(operand);
|
||||
operand = srl(operand);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
@ -1177,26 +1198,22 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
}
|
||||
addCycles(6);
|
||||
break;
|
||||
case 4: { // 8-bit INC
|
||||
case 4: // 8-bit INC
|
||||
if (UNLIKELY(m_displaced && memoryY))
|
||||
fetchDisplacement();
|
||||
auto operand = R(y);
|
||||
increment(operand);
|
||||
R(y, operand);
|
||||
R(y, increment(R(y)));
|
||||
addCycles(4);
|
||||
break;
|
||||
} case 5: { // 8-bit DEC
|
||||
case 5: // 8-bit DEC
|
||||
if (UNLIKELY(memoryY)) {
|
||||
addCycles(7);
|
||||
if (UNLIKELY(m_displaced))
|
||||
fetchDisplacement();
|
||||
}
|
||||
auto operand = R(y);
|
||||
decrement(operand);
|
||||
R(y, operand);
|
||||
R(y, decrement(R(y)));
|
||||
addCycles(4);
|
||||
break;
|
||||
} case 6: // 8-bit load immediate
|
||||
case 6: // 8-bit load immediate
|
||||
if (UNLIKELY(memoryY)) {
|
||||
addCycles(3);
|
||||
if (UNLIKELY(m_displaced))
|
||||
@ -1208,16 +1225,16 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
case 7: // Assorted operations on accumulator/flags
|
||||
switch (y) {
|
||||
case 0:
|
||||
rlc(A());
|
||||
A() = rlc(A());
|
||||
break;
|
||||
case 1:
|
||||
rrc(A());
|
||||
A() = rrc(A());
|
||||
break;
|
||||
case 2:
|
||||
rl(A());
|
||||
A() = rl(A());
|
||||
break;
|
||||
case 3:
|
||||
rr(A());
|
||||
A() = rr(A());
|
||||
break;
|
||||
case 4:
|
||||
daa();
|
||||
|
28
inc/Bus.h
28
inc/Bus.h
@ -22,21 +22,21 @@ namespace EightBit {
|
||||
Signal<EventArgs> ReadingByte;
|
||||
Signal<EventArgs> ReadByte;
|
||||
|
||||
auto ADDRESS() const noexcept { return m_address; }
|
||||
auto& ADDRESS() noexcept { return m_address; }
|
||||
[[nodiscard]] auto ADDRESS() const noexcept { return m_address; }
|
||||
[[nodiscard]] auto& ADDRESS() noexcept { return m_address; }
|
||||
|
||||
auto DATA() const noexcept { return m_data; }
|
||||
auto& DATA() noexcept { return m_data; }
|
||||
[[nodiscard]] auto DATA() const noexcept { return m_data; }
|
||||
[[nodiscard]] auto& DATA() noexcept { return m_data; }
|
||||
|
||||
auto peek() { return reference(); }
|
||||
auto peek(const uint16_t address) { return reference(address); }
|
||||
auto peek(const register16_t address) { return reference(address.word); }
|
||||
[[nodiscard]] auto peek() { return reference(); }
|
||||
[[nodiscard]] auto peek(const uint16_t address) { return reference(address); }
|
||||
[[nodiscard]] auto peek(const register16_t address) { return reference(address.word); }
|
||||
void poke(const uint8_t value) { reference() = value; }
|
||||
void poke(const uint16_t address, const uint8_t value) { reference(address) = value; }
|
||||
void poke(const register16_t address, const uint8_t value) { reference(address.word) = value; }
|
||||
|
||||
uint8_t read();
|
||||
template<class T> auto read(const T address) {
|
||||
[[nodiscard]] uint8_t read();
|
||||
template<class T> [[nodiscard]] auto read(const T address) {
|
||||
ADDRESS() = address;
|
||||
return read();
|
||||
}
|
||||
@ -54,12 +54,12 @@ namespace EightBit {
|
||||
protected:
|
||||
virtual void initialise() = 0;
|
||||
|
||||
virtual MemoryMapping mapping(uint16_t address) = 0;
|
||||
uint8_t& reference(uint16_t address);
|
||||
auto& reference(const register16_t address) { return reference(address.word); }
|
||||
uint8_t& reference() { return reference(ADDRESS()); }
|
||||
[[nodiscard]] virtual MemoryMapping mapping(uint16_t address) = 0;
|
||||
[[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()); }
|
||||
|
||||
static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);
|
||||
[[nodiscard]] static std::map<uint16_t, std::vector<uint8_t>> parseHexFile(std::string path);
|
||||
void loadHexFile(std::string path);
|
||||
|
||||
private:
|
||||
|
@ -77,9 +77,9 @@ namespace EightBit {
|
||||
|
||||
virtual ~Chip() {};
|
||||
|
||||
auto& POWER() noexcept { return m_powerLine; }
|
||||
[[nodiscard]] auto& POWER() noexcept { return m_powerLine; }
|
||||
|
||||
auto powered() noexcept { return raised(POWER()); }
|
||||
[[nodiscard]] auto powered() noexcept { return raised(POWER()); }
|
||||
virtual void powerOn();
|
||||
void powerOff() noexcept { lower(POWER()); }
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
||||
#endif
|
||||
|
||||
namespace EightBit {
|
||||
int countBits(uint8_t value) noexcept ;
|
||||
bool oddParity(uint8_t value) noexcept ;
|
||||
int findFirstSet(int value) noexcept ;
|
||||
[[nodiscard]] int countBits(uint8_t value) noexcept ;
|
||||
[[nodiscard]] bool oddParity(uint8_t value) noexcept ;
|
||||
[[nodiscard]] int findFirstSet(int value) noexcept ;
|
||||
constexpr void assume(int expression);
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,6 @@ namespace EightBit {
|
||||
static EventArgs m_empty;
|
||||
|
||||
public:
|
||||
static auto& empty() noexcept { return m_empty; }
|
||||
[[nodiscard]] static auto& empty() noexcept { return m_empty; }
|
||||
};
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ namespace EightBit {
|
||||
public:
|
||||
InputOutput() = default;
|
||||
|
||||
auto read(const uint8_t port) { return readInputPort(port); }
|
||||
[[nodiscard]] auto read(const uint8_t port) { return readInputPort(port); }
|
||||
void write(const uint8_t port, const uint8_t value) { return writeOutputPort(port, value); }
|
||||
|
||||
uint8_t readInputPort(uint8_t port);
|
||||
[[nodiscard]] uint8_t readInputPort(uint8_t port);
|
||||
void writeInputPort(const uint8_t port, const uint8_t value) noexcept { m_input[port] = value; }
|
||||
|
||||
auto readOutputPort(const uint8_t port) noexcept { return m_output[port]; }
|
||||
[[nodiscard]] auto readOutputPort(const uint8_t port) noexcept { return m_output[port]; }
|
||||
void writeOutputPort(uint8_t port, uint8_t value);
|
||||
|
||||
Signal<uint8_t> ReadingPort;
|
||||
|
@ -33,29 +33,29 @@ namespace EightBit {
|
||||
|
||||
~IntelProcessor() = default;
|
||||
|
||||
const auto& getDecodedOpcode(const size_t i) const noexcept {
|
||||
[[nodiscard]] const auto& getDecodedOpcode(const size_t i) const noexcept {
|
||||
return m_decodedOpcodes[i];
|
||||
}
|
||||
|
||||
auto& MEMPTR() noexcept { return m_memptr; }
|
||||
[[nodiscard]] auto& MEMPTR() noexcept { return m_memptr; }
|
||||
|
||||
auto& SP() noexcept { return m_sp; }
|
||||
[[nodiscard]] auto& SP() noexcept { return m_sp; }
|
||||
|
||||
virtual register16_t& AF() = 0;
|
||||
auto& A() { return AF().high; }
|
||||
auto& F() { return AF().low; }
|
||||
[[nodiscard]] virtual register16_t& AF() = 0;
|
||||
[[nodiscard]] auto& A() { return AF().high; }
|
||||
[[nodiscard]] auto& F() { return AF().low; }
|
||||
|
||||
virtual register16_t& BC() = 0;
|
||||
auto& B() { return BC().high; }
|
||||
auto& C() { return BC().low; }
|
||||
[[nodiscard]] virtual register16_t& BC() = 0;
|
||||
[[nodiscard]] auto& B() { return BC().high; }
|
||||
[[nodiscard]] auto& C() { return BC().low; }
|
||||
|
||||
virtual register16_t& DE() = 0;
|
||||
auto& D() { return DE().high; }
|
||||
auto& E() { return DE().low; }
|
||||
[[nodiscard]] virtual register16_t& DE() = 0;
|
||||
[[nodiscard]] auto& D() { return DE().high; }
|
||||
[[nodiscard]] auto& E() { return DE().low; }
|
||||
|
||||
virtual register16_t& HL() = 0;
|
||||
auto& H() { return HL().high; }
|
||||
auto& L() { return HL().low; }
|
||||
[[nodiscard]] virtual register16_t& HL() = 0;
|
||||
[[nodiscard]] auto& H() { return HL().high; }
|
||||
[[nodiscard]] auto& L() { return HL().low; }
|
||||
|
||||
void powerOn() override;
|
||||
|
||||
@ -105,24 +105,24 @@ namespace EightBit {
|
||||
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
||||
}
|
||||
|
||||
static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
[[nodiscard]] static auto calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
static std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
|
||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||
return m_halfCarryTableAdd[index & Mask3];
|
||||
}
|
||||
|
||||
static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
[[nodiscard]] static auto calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
|
||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||
return m_halfCarryTableSub[index & Mask3];
|
||||
}
|
||||
|
||||
void push(uint8_t value) final;
|
||||
uint8_t pop() final;
|
||||
[[nodiscard]] uint8_t pop() final;
|
||||
|
||||
//
|
||||
|
||||
register16_t getWord() final;
|
||||
[[nodiscard]] register16_t getWord() final;
|
||||
void setWord(register16_t value) final;
|
||||
|
||||
//
|
||||
|
@ -16,10 +16,10 @@ namespace EightBit {
|
||||
public:
|
||||
virtual ~Memory() = default;
|
||||
|
||||
virtual size_t size() const = 0;
|
||||
virtual uint8_t peek(uint16_t address) const = 0;
|
||||
[[nodiscard]] virtual size_t size() const = 0;
|
||||
[[nodiscard]] virtual uint8_t peek(uint16_t address) const = 0;
|
||||
|
||||
virtual uint8_t& reference(uint16_t);
|
||||
[[nodiscard]] virtual uint8_t& reference(uint16_t);
|
||||
|
||||
virtual int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0;
|
||||
virtual int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) = 0;
|
||||
|
@ -13,16 +13,16 @@ namespace EightBit {
|
||||
public:
|
||||
// b: number of bits representing the number in x
|
||||
// x: sign extend this b-bit number to r
|
||||
static int8_t signExtend(int b, uint8_t x);
|
||||
[[nodiscard]] static int8_t signExtend(int b, uint8_t x);
|
||||
|
||||
~Processor() {};
|
||||
|
||||
auto& PC() noexcept { return m_pc; }
|
||||
[[nodiscard]] auto& PC() noexcept { return m_pc; }
|
||||
|
||||
auto& RESET() noexcept { return m_resetLine; }
|
||||
auto& HALT() noexcept { return m_haltLine; }
|
||||
auto& INT() noexcept { return m_intLine; }
|
||||
auto& IRQ() noexcept { return INT(); } // Synonym
|
||||
[[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()); }
|
||||
@ -31,25 +31,25 @@ namespace EightBit {
|
||||
virtual int step() = 0;
|
||||
virtual int execute(uint8_t opcode) = 0;
|
||||
|
||||
auto cycles() const noexcept { return m_cycles; }
|
||||
[[nodiscard]] auto cycles() const noexcept { return m_cycles; }
|
||||
|
||||
virtual register16_t peekWord(register16_t address) = 0;
|
||||
[[nodiscard]] virtual register16_t peekWord(register16_t address) = 0;
|
||||
virtual void pokeWord(register16_t address, register16_t value) = 0;
|
||||
|
||||
protected:
|
||||
Processor(Bus& memory);
|
||||
|
||||
auto& BUS() noexcept { return m_bus; }
|
||||
[[nodiscard]] auto& BUS() noexcept { return m_bus; }
|
||||
|
||||
auto halted() noexcept { return lowered(HALT()); }
|
||||
auto halt() noexcept { --PC(); lower(HALT()); }
|
||||
auto proceed() noexcept { ++PC(); raise(HALT()); }
|
||||
[[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();
|
||||
|
||||
auto getBytePaged(const uint8_t page, const uint8_t offset) {
|
||||
[[nodiscard]] auto getBytePaged(const uint8_t page, const uint8_t offset) {
|
||||
return BUS().read(register16_t(offset, page));
|
||||
}
|
||||
|
||||
@ -57,25 +57,25 @@ namespace EightBit {
|
||||
BUS().write(register16_t(offset, page), value);
|
||||
}
|
||||
|
||||
auto fetchByte() {
|
||||
[[nodiscard]] auto fetchByte() {
|
||||
return BUS().read(PC()++);
|
||||
}
|
||||
|
||||
virtual register16_t getWord() = 0;
|
||||
[[nodiscard]] virtual register16_t getWord() = 0;
|
||||
virtual void setWord(register16_t value) = 0;
|
||||
|
||||
virtual register16_t getWordPaged(uint8_t page, uint8_t offset) = 0;
|
||||
[[nodiscard]] virtual register16_t getWordPaged(uint8_t page, uint8_t offset) = 0;
|
||||
virtual void setWordPaged(uint8_t page, uint8_t offset, register16_t value) = 0;
|
||||
|
||||
virtual register16_t fetchWord() = 0;
|
||||
[[nodiscard]] virtual register16_t fetchWord() = 0;
|
||||
|
||||
virtual void push(uint8_t value) = 0;
|
||||
virtual uint8_t pop() = 0;
|
||||
[[nodiscard]] virtual uint8_t pop() = 0;
|
||||
|
||||
virtual void pushWord(register16_t value) = 0;
|
||||
virtual register16_t popWord() = 0;
|
||||
[[nodiscard]] virtual register16_t popWord() = 0;
|
||||
|
||||
auto getWord(const register16_t address) {
|
||||
[[nodiscard]] auto getWord(const register16_t address) {
|
||||
BUS().ADDRESS() = address;
|
||||
return getWord();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ namespace EightBit {
|
||||
public:
|
||||
Ram(size_t size = 0) noexcept;
|
||||
|
||||
uint8_t& reference(uint16_t address) final;
|
||||
[[nodiscard]] uint8_t& reference(uint16_t address) final;
|
||||
void poke(uint16_t address, uint8_t value) final;
|
||||
};
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ namespace EightBit {
|
||||
std::vector<uint8_t> m_bytes;
|
||||
|
||||
protected:
|
||||
const auto& BYTES() const noexcept { return m_bytes; }
|
||||
auto& BYTES() noexcept { return m_bytes; }
|
||||
[[nodiscard]] const auto& BYTES() const noexcept { return m_bytes; }
|
||||
[[nodiscard]] auto& BYTES() noexcept { return m_bytes; }
|
||||
|
||||
void poke(uint16_t address, uint8_t value) override;
|
||||
|
||||
@ -27,12 +27,12 @@ namespace EightBit {
|
||||
|
||||
Rom(size_t size = 0);
|
||||
|
||||
size_t size() const final;
|
||||
[[nodiscard]] size_t size() const final;
|
||||
|
||||
int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
|
||||
int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
|
||||
int load(const std::vector<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
|
||||
|
||||
uint8_t peek(uint16_t address) const final;
|
||||
[[nodiscard]] uint8_t peek(uint16_t address) const final;
|
||||
};
|
||||
}
|
||||
|
@ -38,19 +38,19 @@ namespace EightBit {
|
||||
std::cout << "Efficiency = " << efficiency << std::endl;
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::duration getElapsedTime() const {
|
||||
[[nodiscard]] std::chrono::steady_clock::duration getElapsedTime() const {
|
||||
return m_finishTime - m_startTime;
|
||||
}
|
||||
|
||||
auto getElapsedSeconds() const {
|
||||
[[nodiscard]] auto getElapsedSeconds() const {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(getElapsedTime()).count();
|
||||
}
|
||||
|
||||
auto getCyclesPerSecond() const {
|
||||
[[nodiscard]] auto getCyclesPerSecond() const {
|
||||
return (m_totalCycles / 1000000 ) / getElapsedSeconds();
|
||||
}
|
||||
|
||||
auto getInstructionsPerSecond() {
|
||||
[[nodiscard]] auto getInstructionsPerSecond() {
|
||||
auto floating = m_instructions / getElapsedSeconds();
|
||||
return (long long)floating;
|
||||
}
|
||||
@ -82,11 +82,11 @@ namespace EightBit {
|
||||
uint64_t m_startHostCycles = 0;
|
||||
uint64_t m_finishHostCycles = 0;
|
||||
|
||||
static auto now() {
|
||||
static [[nodiscard]] auto now() {
|
||||
return std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
static uint64_t currentHostCycles() {
|
||||
static [[nodiscard]] uint64_t currentHostCycles() {
|
||||
return __rdtsc();
|
||||
}
|
||||
};
|
||||
|
@ -16,8 +16,8 @@ namespace EightBit {
|
||||
UnusedMemory(size_t size, uint8_t value);
|
||||
~UnusedMemory() {};
|
||||
|
||||
size_t size() const final;
|
||||
uint8_t peek(uint16_t address) const final;
|
||||
[[nodiscard]] size_t size() const final;
|
||||
[[nodiscard]] uint8_t peek(uint16_t address) const final;
|
||||
|
||||
int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
|
||||
int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) final;
|
||||
|
Loading…
x
Reference in New Issue
Block a user