mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-07-23 13:24:35 +00:00
Remove some "tricksy" code from the Z80 emulator chain.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -19,7 +19,7 @@ namespace EightBit {
|
|||||||
bool high : 1;
|
bool high : 1;
|
||||||
uint8_t variable : 7;
|
uint8_t variable : 7;
|
||||||
|
|
||||||
refresh_t(uint8_t value)
|
refresh_t(const uint8_t value)
|
||||||
: high((value & Bit7) != 0),
|
: high((value & Bit7) != 0),
|
||||||
variable(value & Mask7)
|
variable(value & Mask7)
|
||||||
{ }
|
{ }
|
||||||
@@ -125,7 +125,7 @@ namespace EightBit {
|
|||||||
m_displacement = fetchByte();
|
m_displacement = fetchByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R(int r, uint8_t a) {
|
uint8_t R(const int r, const uint8_t a) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@@ -142,7 +142,7 @@ namespace EightBit {
|
|||||||
case 5:
|
case 5:
|
||||||
return HL2().low;
|
return HL2().low;
|
||||||
case 6:
|
case 6:
|
||||||
return BUS().read(LIKELY(!m_displaced) ? HL().word : displacedAddress());
|
return BUS().read(UNLIKELY(m_displaced) ? displacedAddress() : HL().word);
|
||||||
case 7:
|
case 7:
|
||||||
return a;
|
return a;
|
||||||
default:
|
default:
|
||||||
@@ -150,7 +150,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void R(int r, uint8_t& a, uint8_t value) {
|
void R(const int r, uint8_t& a, const uint8_t value) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@@ -173,7 +173,7 @@ namespace EightBit {
|
|||||||
HL2().low = value;
|
HL2().low = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
BUS().write(LIKELY(!m_displaced) ? HL().word : displacedAddress(), value);
|
BUS().write(UNLIKELY(m_displaced) ? displacedAddress() : HL().word, value);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
a = value;
|
a = value;
|
||||||
@@ -183,7 +183,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t R2(int r, uint8_t a) {
|
uint8_t R2(const int r, const uint8_t a) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@@ -208,7 +208,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void R2(int r, uint8_t& a, uint8_t value) {
|
void R2(const int r, uint8_t& a, const uint8_t value) {
|
||||||
ASSUME(r >= 0);
|
ASSUME(r >= 0);
|
||||||
ASSUME(r <= 7);
|
ASSUME(r <= 7);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
@@ -241,7 +241,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t& RP(int rp) {
|
register16_t& RP(const int rp) {
|
||||||
ASSUME(rp >= 0);
|
ASSUME(rp >= 0);
|
||||||
ASSUME(rp <= 3);
|
ASSUME(rp <= 3);
|
||||||
switch (rp) {
|
switch (rp) {
|
||||||
@@ -267,7 +267,7 @@ namespace EightBit {
|
|||||||
return IY();
|
return IY();
|
||||||
}
|
}
|
||||||
|
|
||||||
register16_t& RP2(int rp) {
|
register16_t& RP2(const int rp) {
|
||||||
ASSUME(rp >= 0);
|
ASSUME(rp >= 0);
|
||||||
ASSUME(rp <= 3);
|
ASSUME(rp <= 3);
|
||||||
switch (rp) {
|
switch (rp) {
|
||||||
@@ -284,28 +284,28 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustHalfCarryAdd(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
static void adjustHalfCarryAdd(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
setFlag(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustHalfCarrySub(uint8_t& f, uint8_t before, uint8_t value, int calculation) {
|
static void adjustHalfCarrySub(uint8_t& f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
|
setFlag(f, HC, calculateHalfCarrySub(before, value, calculation));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowAdd(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
|
static void adjustOverflowAdd(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
||||||
adjustOverflowAdd(f, before & SF, value & SF, calculation & SF);
|
adjustOverflowAdd(f, before & SF, value & SF, calculation & SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowAdd(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
|
static void adjustOverflowAdd(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
||||||
auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
|
auto overflow = (beforeNegative == valueNegative) && (beforeNegative != afterNegative);
|
||||||
setFlag(f, VF, overflow);
|
setFlag(f, VF, overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowSub(uint8_t& f, uint8_t before, uint8_t value, uint8_t calculation) {
|
static void adjustOverflowSub(uint8_t& f, const uint8_t before, const uint8_t value, const uint8_t calculation) {
|
||||||
adjustOverflowSub(f, before & SF, value & SF, calculation & SF);
|
adjustOverflowSub(f, before & SF, value & SF, calculation & SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adjustOverflowSub(uint8_t& f, int beforeNegative, int valueNegative, int afterNegative) {
|
static void adjustOverflowSub(uint8_t& f, const int beforeNegative, const int valueNegative, const int afterNegative) {
|
||||||
auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
|
auto overflow = (beforeNegative != valueNegative) && (beforeNegative != afterNegative);
|
||||||
setFlag(f, VF, overflow);
|
setFlag(f, VF, overflow);
|
||||||
}
|
}
|
||||||
|
@@ -73,7 +73,7 @@ void EightBit::Z80::decrement(uint8_t& f, uint8_t& operand) {
|
|||||||
setFlag(f, VF, operand == Mask7);
|
setFlag(f, VF, operand == Mask7);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::jrConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::jrConditionalFlag(const uint8_t f, const int flag) {
|
||||||
ASSUME(flag >= 0);
|
ASSUME(flag >= 0);
|
||||||
ASSUME(flag <= 3);
|
ASSUME(flag <= 3);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
@@ -90,7 +90,7 @@ bool EightBit::Z80::jrConditionalFlag(uint8_t f, const int flag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::jumpConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::jumpConditionalFlag(const uint8_t f, const int flag) {
|
||||||
ASSUME(flag >= 0);
|
ASSUME(flag >= 0);
|
||||||
ASSUME(flag <= 7);
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
@@ -125,7 +125,7 @@ void EightBit::Z80::reti() {
|
|||||||
retn();
|
retn();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::returnConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::returnConditionalFlag(const uint8_t f, const int flag) {
|
||||||
ASSUME(flag >= 0);
|
ASSUME(flag >= 0);
|
||||||
ASSUME(flag <= 7);
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
@@ -150,7 +150,7 @@ bool EightBit::Z80::returnConditionalFlag(uint8_t f, const int flag) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EightBit::Z80::callConditionalFlag(uint8_t f, const int flag) {
|
bool EightBit::Z80::callConditionalFlag(const uint8_t f, const int flag) {
|
||||||
ASSUME(flag >= 0);
|
ASSUME(flag >= 0);
|
||||||
ASSUME(flag <= 7);
|
ASSUME(flag <= 7);
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
@@ -372,7 +372,7 @@ uint8_t EightBit::Z80::srl(uint8_t& f, uint8_t operand) {
|
|||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::bit(uint8_t& f, int n, uint8_t operand) {
|
uint8_t EightBit::Z80::bit(uint8_t& f, const int n, const uint8_t operand) {
|
||||||
ASSUME(n >= 0);
|
ASSUME(n >= 0);
|
||||||
ASSUME(n <= 7);
|
ASSUME(n <= 7);
|
||||||
setFlag(f, HC);
|
setFlag(f, HC);
|
||||||
@@ -383,13 +383,13 @@ uint8_t EightBit::Z80::bit(uint8_t& f, int n, uint8_t operand) {
|
|||||||
return operand;
|
return operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::res(int n, const uint8_t operand) {
|
uint8_t EightBit::Z80::res(const int n, const uint8_t operand) {
|
||||||
ASSUME(n >= 0);
|
ASSUME(n >= 0);
|
||||||
ASSUME(n <= 7);
|
ASSUME(n <= 7);
|
||||||
return operand & ~(1 << n);
|
return operand & ~(1 << n);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Z80::set(int n, const uint8_t operand) {
|
uint8_t EightBit::Z80::set(const int n, const uint8_t operand) {
|
||||||
ASSUME(n >= 0);
|
ASSUME(n >= 0);
|
||||||
ASSUME(n <= 7);
|
ASSUME(n <= 7);
|
||||||
return operand | (1 << n);
|
return operand | (1 << n);
|
||||||
@@ -710,15 +710,15 @@ int EightBit::Z80::execute(const uint8_t opcode) {
|
|||||||
auto& f = af.low;
|
auto& f = af.low;
|
||||||
|
|
||||||
auto prefixed = m_prefixCB || m_prefixED;
|
auto prefixed = m_prefixCB || m_prefixED;
|
||||||
if (LIKELY(!prefixed)) {
|
if (UNLIKELY(prefixed)) {
|
||||||
executeOther(a, f, x, y, z, p, q);
|
|
||||||
} else {
|
|
||||||
if (m_prefixCB)
|
if (m_prefixCB)
|
||||||
executeCB(a, f, x, y, z);
|
executeCB(a, f, x, y, z);
|
||||||
else if (m_prefixED)
|
else if (m_prefixED)
|
||||||
executeED(a, f, x, y, z, p, q);
|
executeED(a, f, x, y, z, p, q);
|
||||||
else
|
else
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
|
} else {
|
||||||
|
executeOther(a, f, x, y, z, p, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSUME(cycles() > 0);
|
ASSUME(cycles() > 0);
|
||||||
@@ -764,21 +764,25 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
adjustSZP<Z80>(f, operand);
|
adjustSZP<Z80>(f, operand);
|
||||||
if (LIKELY(!m_displaced)) {
|
if (UNLIKELY(m_displaced)) {
|
||||||
R(z, a, operand);
|
|
||||||
if (UNLIKELY(z == 6))
|
|
||||||
addCycles(7);
|
|
||||||
} else {
|
|
||||||
if (LIKELY(z != 6))
|
if (LIKELY(z != 6))
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
BUS().write(operand);
|
BUS().write(operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
|
} else {
|
||||||
|
R(z, a, operand);
|
||||||
|
if (UNLIKELY(z == 6))
|
||||||
|
addCycles(7);
|
||||||
}
|
}
|
||||||
addCycles(8);
|
addCycles(8);
|
||||||
break;
|
break;
|
||||||
} case 1: // BIT y, r[z]
|
} case 1: // BIT y, r[z]
|
||||||
addCycles(8);
|
addCycles(8);
|
||||||
if (LIKELY(!m_displaced)) {
|
if (UNLIKELY(m_displaced)) {
|
||||||
|
bit(f, y, BUS().read(displacedAddress()));
|
||||||
|
adjustXY<Z80>(f, MEMPTR().high);
|
||||||
|
addCycles(12);
|
||||||
|
} else {
|
||||||
const auto operand = bit(f, y, R(z, a));
|
const auto operand = bit(f, y, R(z, a));
|
||||||
if (UNLIKELY(z == 6)) {
|
if (UNLIKELY(z == 6)) {
|
||||||
adjustXY<Z80>(f, MEMPTR().high);
|
adjustXY<Z80>(f, MEMPTR().high);
|
||||||
@@ -786,38 +790,34 @@ void EightBit::Z80::executeCB(uint8_t& a, uint8_t& f, const int x, const int y,
|
|||||||
} else {
|
} else {
|
||||||
adjustXY<Z80>(f, operand);
|
adjustXY<Z80>(f, operand);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
bit(f, y, BUS().read(displacedAddress()));
|
|
||||||
adjustXY<Z80>(f, MEMPTR().high);
|
|
||||||
addCycles(12);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // RES y, r[z]
|
case 2: // RES y, r[z]
|
||||||
addCycles(8);
|
addCycles(8);
|
||||||
if (LIKELY(!m_displaced)) {
|
if (UNLIKELY(m_displaced)) {
|
||||||
R(z, a, res(y, R(z, a)));
|
|
||||||
if (UNLIKELY(z == 6))
|
|
||||||
addCycles(7);
|
|
||||||
} else {
|
|
||||||
auto operand = BUS().read(displacedAddress());
|
auto operand = BUS().read(displacedAddress());
|
||||||
operand = res(y, operand);
|
operand = res(y, operand);
|
||||||
BUS().write(operand);
|
BUS().write(operand);
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
|
} else {
|
||||||
|
R(z, a, res(y, R(z, a)));
|
||||||
|
if (UNLIKELY(z == 6))
|
||||||
|
addCycles(7);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // SET y, r[z]
|
case 3: // SET y, r[z]
|
||||||
addCycles(8);
|
addCycles(8);
|
||||||
if (LIKELY(!m_displaced)) {
|
if (UNLIKELY(m_displaced)) {
|
||||||
R(z, a, set(y, R(z, a)));
|
|
||||||
if (UNLIKELY(z == 6))
|
|
||||||
addCycles(7);
|
|
||||||
} else {
|
|
||||||
auto operand = BUS().read(displacedAddress());
|
auto operand = BUS().read(displacedAddress());
|
||||||
operand = set(y, operand);
|
operand = set(y, operand);
|
||||||
BUS().write(operand);
|
BUS().write(operand);
|
||||||
R2(z, a, operand);
|
R2(z, a, operand);
|
||||||
addCycles(15);
|
addCycles(15);
|
||||||
|
} else {
|
||||||
|
R(z, a, set(y, R(z, a)));
|
||||||
|
if (UNLIKELY(z == 6))
|
||||||
|
addCycles(7);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1222,22 +1222,24 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
addCycles(4);
|
addCycles(4);
|
||||||
break;
|
break;
|
||||||
} case 5: { // 8-bit DEC
|
} case 5: { // 8-bit DEC
|
||||||
if (UNLIKELY(m_displaced && (y == 6)))
|
if (UNLIKELY(y == 6)) {
|
||||||
|
addCycles(7);
|
||||||
|
if (UNLIKELY(m_displaced))
|
||||||
fetchDisplacement();
|
fetchDisplacement();
|
||||||
|
}
|
||||||
auto operand = R(y, a);
|
auto operand = R(y, a);
|
||||||
decrement(f, operand);
|
decrement(f, operand);
|
||||||
R(y, a, operand);
|
R(y, a, operand);
|
||||||
addCycles(4);
|
addCycles(4);
|
||||||
if (UNLIKELY(y == 6))
|
|
||||||
addCycles(7);
|
|
||||||
break;
|
break;
|
||||||
} case 6: // 8-bit load immediate
|
} case 6: // 8-bit load immediate
|
||||||
if (UNLIKELY(m_displaced && (y == 6)))
|
if (UNLIKELY(y == 6)) {
|
||||||
|
addCycles(3);
|
||||||
|
if (UNLIKELY(m_displaced))
|
||||||
fetchDisplacement();
|
fetchDisplacement();
|
||||||
|
}
|
||||||
R(y, a, fetchByte()); // LD r,n
|
R(y, a, fetchByte()); // LD r,n
|
||||||
addCycles(7);
|
addCycles(7);
|
||||||
if (UNLIKELY(y == 6))
|
|
||||||
addCycles(3);
|
|
||||||
break;
|
break;
|
||||||
case 7: // Assorted operations on accumulator/flags
|
case 7: // Assorted operations on accumulator/flags
|
||||||
switch (y) {
|
switch (y) {
|
||||||
@@ -1315,8 +1317,11 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
addCycles(4);
|
addCycles(4);
|
||||||
break;
|
break;
|
||||||
case 2: // Operate on accumulator and register/memory location
|
case 2: // Operate on accumulator and register/memory location
|
||||||
if (UNLIKELY(m_displaced && (z == 6)))
|
if (UNLIKELY(z == 6)) {
|
||||||
|
addCycles(3);
|
||||||
|
if (UNLIKELY(m_displaced))
|
||||||
fetchDisplacement();
|
fetchDisplacement();
|
||||||
|
}
|
||||||
switch (y) {
|
switch (y) {
|
||||||
case 0: // ADD A,r
|
case 0: // ADD A,r
|
||||||
add(f, a, R(z, a));
|
add(f, a, R(z, a));
|
||||||
@@ -1346,8 +1351,6 @@ void EightBit::Z80::executeOther(uint8_t& a, uint8_t& f, const int x, const int
|
|||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
addCycles(4);
|
addCycles(4);
|
||||||
if (UNLIKELY(z == 6))
|
|
||||||
addCycles(3);
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
switch (z) {
|
switch (z) {
|
||||||
|
@@ -6,17 +6,17 @@
|
|||||||
#include "Signal.h"
|
#include "Signal.h"
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class InputOutput {
|
class InputOutput final {
|
||||||
public:
|
public:
|
||||||
InputOutput() = default;
|
InputOutput() = default;
|
||||||
|
|
||||||
uint8_t read(uint8_t port) { return readInputPort(port); }
|
uint8_t read(const uint8_t port) { return readInputPort(port); }
|
||||||
void write(uint8_t port, uint8_t value) { return writeOutputPort(port, value); }
|
void write(const uint8_t port, const uint8_t value) { return writeOutputPort(port, value); }
|
||||||
|
|
||||||
uint8_t readInputPort(uint8_t port);
|
uint8_t readInputPort(uint8_t port);
|
||||||
void writeInputPort(uint8_t port, uint8_t value) { m_input[port] = value; }
|
void writeInputPort(const uint8_t port, const uint8_t value) { m_input[port] = value; }
|
||||||
|
|
||||||
uint8_t readOutputPort(uint8_t port) { return m_output[port]; }
|
uint8_t readOutputPort(const uint8_t port) { return m_output[port]; }
|
||||||
void writeOutputPort(uint8_t port, uint8_t value);
|
void writeOutputPort(uint8_t port, uint8_t value);
|
||||||
|
|
||||||
Signal<uint8_t> ReadingPort;
|
Signal<uint8_t> ReadingPort;
|
||||||
|
@@ -23,7 +23,7 @@ namespace EightBit {
|
|||||||
|
|
||||||
opcode_decoded_t() {}
|
opcode_decoded_t() {}
|
||||||
|
|
||||||
opcode_decoded_t(uint8_t opcode) {
|
opcode_decoded_t(const uint8_t opcode) {
|
||||||
x = (opcode & 0b11000000) >> 6; // 0 - 3
|
x = (opcode & 0b11000000) >> 6; // 0 - 3
|
||||||
y = (opcode & 0b00111000) >> 3; // 0 - 7
|
y = (opcode & 0b00111000) >> 3; // 0 - 7
|
||||||
z = (opcode & 0b00000111); // 0 - 7
|
z = (opcode & 0b00000111); // 0 - 7
|
||||||
@@ -62,56 +62,56 @@ namespace EightBit {
|
|||||||
|
|
||||||
virtual void reset() override;
|
virtual void reset() override;
|
||||||
|
|
||||||
template<class T> static void adjustSign(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustSign(uint8_t& f, const uint8_t value) {
|
||||||
setFlag(f, T::SF, value & T::SF);
|
setFlag(f, T::SF, value & T::SF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustZero(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustZero(uint8_t& f, const uint8_t value) {
|
||||||
clearFlag(f, T::ZF, value);
|
clearFlag(f, T::ZF, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustParity(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustParity(uint8_t& f, const uint8_t value) {
|
||||||
clearFlag(f, T::PF, PARITY(value));
|
clearFlag(f, T::PF, PARITY(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZ(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustSZ(uint8_t& f, const uint8_t value) {
|
||||||
adjustSign<T>(f, value);
|
adjustSign<T>(f, value);
|
||||||
adjustZero<T>(f, value);
|
adjustZero<T>(f, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZP(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustSZP(uint8_t& f, const uint8_t value) {
|
||||||
adjustSZ<T>(f, value);
|
adjustSZ<T>(f, value);
|
||||||
adjustParity<T>(f, value);
|
adjustParity<T>(f, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustXY(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustXY(uint8_t& f, const uint8_t value) {
|
||||||
setFlag(f, T::XF, value & T::XF);
|
setFlag(f, T::XF, value & T::XF);
|
||||||
setFlag(f, T::YF, value & T::YF);
|
setFlag(f, T::YF, value & T::YF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZPXY(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustSZPXY(uint8_t& f, const uint8_t value) {
|
||||||
adjustSZP<T>(f, value);
|
adjustSZP<T>(f, value);
|
||||||
adjustXY<T>(f, value);
|
adjustXY<T>(f, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static void adjustSZXY(uint8_t& f, uint8_t value) {
|
template<class T> static void adjustSZXY(uint8_t& f, const uint8_t value) {
|
||||||
adjustSZ<T>(f, value);
|
adjustSZ<T>(f, value);
|
||||||
adjustXY<T>(f, value);
|
adjustXY<T>(f, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
static int buildHalfCarryIndex(uint8_t before, uint8_t value, int calculation) {
|
static int buildHalfCarryIndex(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool calculateHalfCarryAdd(uint8_t before, uint8_t value, int calculation) {
|
static bool calculateHalfCarryAdd(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
static std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
|
static std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
|
||||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||||
return m_halfCarryTableAdd[index & Mask3];
|
return m_halfCarryTableAdd[index & Mask3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool calculateHalfCarrySub(uint8_t before, uint8_t value, int calculation) {
|
static bool calculateHalfCarrySub(const uint8_t before, const uint8_t value, const int calculation) {
|
||||||
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
|
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
|
||||||
const auto index = buildHalfCarryIndex(before, value, calculation);
|
const auto index = buildHalfCarryIndex(before, value, calculation);
|
||||||
return m_halfCarryTableSub[index & Mask3];
|
return m_halfCarryTableSub[index & Mask3];
|
||||||
@@ -127,27 +127,27 @@ namespace EightBit {
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
void restart(uint8_t address) {
|
void restart(const uint8_t address) {
|
||||||
MEMPTR().low = address;
|
MEMPTR().low = address;
|
||||||
MEMPTR().high = 0;
|
MEMPTR().high = 0;
|
||||||
call(MEMPTR());
|
call(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callConditional(int condition) {
|
bool callConditional(const int condition) {
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = fetchWord();
|
||||||
if (condition)
|
if (condition)
|
||||||
call(MEMPTR());
|
call(MEMPTR());
|
||||||
return condition != 0;
|
return condition != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool jumpConditional(int conditional) {
|
bool jumpConditional(const int conditional) {
|
||||||
MEMPTR() = fetchWord();
|
MEMPTR() = fetchWord();
|
||||||
if (conditional)
|
if (conditional)
|
||||||
jump(MEMPTR());
|
jump(MEMPTR());
|
||||||
return conditional != 0;
|
return conditional != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool returnConditional(int condition) {
|
bool returnConditional(const int condition) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
ret();
|
ret();
|
||||||
MEMPTR() = PC();
|
MEMPTR() = PC();
|
||||||
@@ -155,12 +155,12 @@ namespace EightBit {
|
|||||||
return condition != 0;
|
return condition != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jr(int8_t offset) {
|
void jr(const int8_t offset) {
|
||||||
MEMPTR().word = PC().word + offset;
|
MEMPTR().word = PC().word + offset;
|
||||||
jump(MEMPTR());
|
jump(MEMPTR());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool jrConditional(int conditional) {
|
bool jrConditional(const int conditional) {
|
||||||
const auto offset = fetchByte();
|
const auto offset = fetchByte();
|
||||||
if (conditional)
|
if (conditional)
|
||||||
jr(offset);
|
jr(offset);
|
||||||
|
12
inc/Memory.h
12
inc/Memory.h
@@ -11,23 +11,23 @@ namespace EightBit {
|
|||||||
static int load(std::ifstream& file, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
|
static int load(std::ifstream& file, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
|
||||||
static int load(const std::string& path, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
|
static int load(const std::string& path, std::vector<uint8_t>& output, int writeOffset = 0, int readOffset = 0, int limit = -1, int maximumSize = -1);
|
||||||
|
|
||||||
Memory(size_t size = 0)
|
Memory(const size_t size = 0)
|
||||||
: m_bytes(size) {
|
: m_bytes(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const { return m_bytes.size(); }
|
size_t size() const { return m_bytes.size(); }
|
||||||
|
|
||||||
int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) {
|
int load(std::ifstream& file, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
|
||||||
const auto maximumSize = (int)m_bytes.size() - writeOffset;
|
const auto maximumSize = (int)m_bytes.size() - writeOffset;
|
||||||
return load(file, m_bytes, writeOffset, readOffset, limit, maximumSize);
|
return load(file, m_bytes, writeOffset, readOffset, limit, maximumSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load(const std::string& path, int writeOffset = 0, int readOffset = 0, int limit = -1) {
|
int load(const std::string& path, const int writeOffset = 0, const int readOffset = 0, const int limit = -1) {
|
||||||
const auto maximumSize = (int)m_bytes.size() - writeOffset;
|
const auto maximumSize = (int)m_bytes.size() - writeOffset;
|
||||||
return load(path, m_bytes, writeOffset, readOffset, limit, maximumSize);
|
return load(path, m_bytes, writeOffset, readOffset, limit, maximumSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int load(const std::vector<uint8_t>& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) {
|
int load(const std::vector<uint8_t>& bytes, const int writeOffset = 0, const int readOffset = 0, int limit = -1) {
|
||||||
if (limit < 0)
|
if (limit < 0)
|
||||||
limit = (int)bytes.size() - readOffset;
|
limit = (int)bytes.size() - readOffset;
|
||||||
std::copy(bytes.cbegin() + readOffset, bytes.cbegin() + limit, m_bytes.begin() + writeOffset);
|
std::copy(bytes.cbegin() + readOffset, bytes.cbegin() + limit, m_bytes.begin() + writeOffset);
|
||||||
@@ -37,11 +37,11 @@ namespace EightBit {
|
|||||||
protected:
|
protected:
|
||||||
std::vector<uint8_t>& BYTES() { return m_bytes; }
|
std::vector<uint8_t>& BYTES() { return m_bytes; }
|
||||||
|
|
||||||
uint8_t read(uint16_t address) const {
|
uint8_t read(const uint16_t address) const {
|
||||||
return m_bytes[address];
|
return m_bytes[address];
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(uint16_t address, uint8_t value) {
|
void write(const uint16_t address, const uint8_t value) {
|
||||||
m_bytes[address] = value;
|
m_bytes[address] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,16 +53,16 @@ namespace EightBit {
|
|||||||
Low, High
|
Low, High
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool raised(PinLevel line) { return line == High; }
|
static bool raised(const PinLevel line) { return line == High; }
|
||||||
static void raise(PinLevel& line) { line = High; }
|
static void raise(PinLevel& line) { line = High; }
|
||||||
static bool lowered(PinLevel line) { return line == Low; }
|
static bool lowered(const PinLevel line) { return line == Low; }
|
||||||
static void lower(PinLevel& line) { line = Low; }
|
static void lower(PinLevel& line) { line = Low; }
|
||||||
|
|
||||||
static int highNibble(int value) { return value >> 4; }
|
static int highNibble(const int value) { return value >> 4; }
|
||||||
static int lowNibble(int value) { return value & Mask4; }
|
static int lowNibble(const int value) { return value & Mask4; }
|
||||||
|
|
||||||
static int promoteNibble(int value) { return value << 4; }
|
static int promoteNibble(const int value) { return value << 4; }
|
||||||
static int demoteNibble(int value) { return highNibble(value); }
|
static int demoteNibble(const int value) { return highNibble(value); }
|
||||||
|
|
||||||
Bus& BUS() { return m_bus; }
|
Bus& BUS() { return m_bus; }
|
||||||
|
|
||||||
@@ -85,16 +85,16 @@ namespace EightBit {
|
|||||||
virtual int execute(uint8_t opcode) = 0;
|
virtual int execute(uint8_t opcode) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void clearFlag(uint8_t& f, int flag) { f &= ~flag; }
|
static void clearFlag(uint8_t& f, const int flag) { f &= ~flag; }
|
||||||
static void setFlag(uint8_t& f, int flag) { f |= flag; }
|
static void setFlag(uint8_t& f, const int flag) { f |= flag; }
|
||||||
|
|
||||||
static void setFlag(uint8_t& f, int flag, int condition) { setFlag(f, flag, condition != 0); }
|
static void setFlag(uint8_t& f, const int flag, const int condition) { setFlag(f, flag, condition != 0); }
|
||||||
static void setFlag(uint8_t& f, int flag, uint32_t condition) { setFlag(f, flag, condition != 0); }
|
static void setFlag(uint8_t& f, const int flag, const uint32_t condition) { setFlag(f, flag, condition != 0); }
|
||||||
static void setFlag(uint8_t& f, int flag, bool condition) { condition ? setFlag(f, flag) : clearFlag(f, flag); }
|
static void setFlag(uint8_t& f, const int flag, const bool condition) { condition ? setFlag(f, flag) : clearFlag(f, flag); }
|
||||||
|
|
||||||
static void clearFlag(uint8_t& f, int flag, int condition) { clearFlag(f, flag, condition != 0); }
|
static void clearFlag(uint8_t& f, const int flag, const int condition) { clearFlag(f, flag, condition != 0); }
|
||||||
static void clearFlag(uint8_t& f, int flag, uint32_t condition) { clearFlag(f, flag, condition != 0); }
|
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) { clearFlag(f, flag, condition != 0); }
|
||||||
static void clearFlag(uint8_t& f, int flag, bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
|
static void clearFlag(uint8_t& f, const int flag, const bool condition) { condition ? clearFlag(f, flag) : setFlag(f, flag); }
|
||||||
|
|
||||||
Processor(Bus& memory);
|
Processor(Bus& memory);
|
||||||
virtual ~Processor() = default;
|
virtual ~Processor() = default;
|
||||||
@@ -119,7 +119,7 @@ namespace EightBit {
|
|||||||
virtual void push(uint8_t value) = 0;
|
virtual void push(uint8_t value) = 0;
|
||||||
virtual uint8_t pop() = 0;
|
virtual uint8_t pop() = 0;
|
||||||
|
|
||||||
void pushWord(register16_t value) {
|
void pushWord(const register16_t value) {
|
||||||
push(value.high);
|
push(value.high);
|
||||||
push(value.low);
|
push(value.low);
|
||||||
}
|
}
|
||||||
@@ -131,11 +131,11 @@ namespace EightBit {
|
|||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void jump(register16_t destination) {
|
void jump(const register16_t destination) {
|
||||||
PC() = destination;
|
PC() = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
void call(register16_t destination) {
|
void call(const register16_t destination) {
|
||||||
pushWord(PC());
|
pushWord(PC());
|
||||||
jump(destination);
|
jump(destination);
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ namespace EightBit {
|
|||||||
|
|
||||||
int cycles() const { return m_cycles; }
|
int cycles() const { return m_cycles; }
|
||||||
void resetCycles() { m_cycles = 0; }
|
void resetCycles() { m_cycles = 0; }
|
||||||
void addCycles(int extra) { m_cycles += extra; }
|
void addCycles(const int extra) { m_cycles += extra; }
|
||||||
void addCycle() { ++m_cycles; }
|
void addCycle() { ++m_cycles; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -6,19 +6,19 @@
|
|||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class Ram : public Memory {
|
class Ram : public Memory {
|
||||||
public:
|
public:
|
||||||
Ram(size_t size = 0)
|
Ram(const size_t size = 0)
|
||||||
: Memory(size) {
|
: Memory(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t peek(uint16_t address) const {
|
uint8_t peek(const uint16_t address) const {
|
||||||
return read(address);
|
return read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void poke(uint16_t address, uint8_t value) {
|
void poke(const uint16_t address, const uint8_t value) {
|
||||||
write(address, value);
|
write(address, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t& reference(uint16_t address) {
|
uint8_t& reference(const uint16_t address) {
|
||||||
return BYTES()[address];
|
return BYTES()[address];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -6,15 +6,15 @@
|
|||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
class Rom : public Memory {
|
class Rom : public Memory {
|
||||||
public:
|
public:
|
||||||
Rom(size_t size = 0)
|
Rom(const size_t size = 0)
|
||||||
: Memory(size) {
|
: Memory(size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t peek(uint16_t address) const {
|
uint8_t peek(const uint16_t address) const {
|
||||||
return read(address);
|
return read(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t& reference(uint16_t address) {
|
uint8_t& reference(const uint16_t address) {
|
||||||
return BYTES()[address];
|
return BYTES()[address];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace EightBit {
|
namespace EightBit {
|
||||||
template<class T> class Signal {
|
template<class T> class Signal final {
|
||||||
private:
|
private:
|
||||||
typedef std::function<void(const T&)> delegate_t;
|
typedef std::function<void(const T&)> delegate_t;
|
||||||
typedef std::vector<delegate_t> delegates_t;
|
typedef std::vector<delegate_t> delegates_t;
|
||||||
@@ -12,7 +12,7 @@ namespace EightBit {
|
|||||||
delegates_t m_delegates;
|
delegates_t m_delegates;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void connect(delegate_t functor) {
|
void connect(const delegate_t functor) {
|
||||||
m_delegates.push_back(functor);
|
m_delegates.push_back(functor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,11 +18,7 @@ namespace EightBit {
|
|||||||
template<class ConfigurationT, class BoardT> class TestHarness {
|
template<class ConfigurationT, class BoardT> class TestHarness {
|
||||||
public:
|
public:
|
||||||
TestHarness(const ConfigurationT& configuration)
|
TestHarness(const ConfigurationT& configuration)
|
||||||
: m_board(configuration),
|
: m_board(configuration) {
|
||||||
m_totalCycles(0),
|
|
||||||
m_instructions(0),
|
|
||||||
m_startHostCycles(0),
|
|
||||||
m_finishHostCycles(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~TestHarness() {
|
~TestHarness() {
|
||||||
@@ -81,12 +77,12 @@ namespace EightBit {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BoardT m_board;
|
BoardT m_board;
|
||||||
long long m_totalCycles;
|
long long m_totalCycles = 0;
|
||||||
long long m_instructions;
|
long long m_instructions = 0;
|
||||||
std::chrono::steady_clock::time_point m_startTime;
|
std::chrono::steady_clock::time_point m_startTime;
|
||||||
std::chrono::steady_clock::time_point m_finishTime;
|
std::chrono::steady_clock::time_point m_finishTime;
|
||||||
uint64_t m_startHostCycles;
|
uint64_t m_startHostCycles = 0;
|
||||||
uint64_t m_finishHostCycles;
|
uint64_t m_finishHostCycles = 0;
|
||||||
|
|
||||||
static std::chrono::steady_clock::time_point now() {
|
static std::chrono::steady_clock::time_point now() {
|
||||||
return std::chrono::steady_clock::now();
|
return std::chrono::steady_clock::now();
|
||||||
|
20
src/Bus.cpp
20
src/Bus.cpp
@@ -11,7 +11,7 @@ uint8_t& EightBit::Bus::DATA() {
|
|||||||
return *m_data;
|
return *m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t& EightBit::Bus::placeDATA(uint8_t value) {
|
uint8_t& EightBit::Bus::placeDATA(const uint8_t value) {
|
||||||
m_temporary = value;
|
m_temporary = value;
|
||||||
m_data = &m_temporary;
|
m_data = &m_temporary;
|
||||||
return DATA();
|
return DATA();
|
||||||
@@ -22,17 +22,17 @@ uint8_t& EightBit::Bus::referenceDATA(uint8_t& value) {
|
|||||||
return DATA();
|
return DATA();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Bus::peek(uint16_t address) {
|
uint8_t EightBit::Bus::peek(const uint16_t address) {
|
||||||
bool rom;
|
bool rom;
|
||||||
return reference(address, rom);
|
return reference(address, rom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::poke(uint16_t address, uint8_t value) {
|
void EightBit::Bus::poke(const uint16_t address, const uint8_t value) {
|
||||||
bool rom;
|
bool rom;
|
||||||
reference(address, rom) = value;
|
reference(address, rom) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t EightBit::Bus::peekWord(uint16_t address) {
|
uint16_t EightBit::Bus::peekWord(const uint16_t address) {
|
||||||
register16_t returned;
|
register16_t returned;
|
||||||
returned.low = peek(address);
|
returned.low = peek(address);
|
||||||
returned.high = peek(address + 1);
|
returned.high = peek(address + 1);
|
||||||
@@ -46,28 +46,28 @@ uint8_t EightBit::Bus::read() {
|
|||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Bus::read(uint16_t offset) {
|
uint8_t EightBit::Bus::read(const uint16_t offset) {
|
||||||
ADDRESS().word = offset;
|
ADDRESS().word = offset;
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t EightBit::Bus::read(register16_t address) {
|
uint8_t EightBit::Bus::read(const register16_t address) {
|
||||||
ADDRESS() = address;
|
ADDRESS() = address;
|
||||||
return read();
|
return read();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::write(uint8_t value) {
|
void EightBit::Bus::write(const uint8_t value) {
|
||||||
WritingByte.fire(ADDRESS().word);
|
WritingByte.fire(ADDRESS().word);
|
||||||
reference() = value;
|
reference() = value;
|
||||||
WrittenByte.fire(ADDRESS().word);
|
WrittenByte.fire(ADDRESS().word);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::write(uint16_t offset, uint8_t value) {
|
void EightBit::Bus::write(const uint16_t offset, const uint8_t value) {
|
||||||
ADDRESS().word = offset;
|
ADDRESS().word = offset;
|
||||||
write(value);
|
write(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::write(register16_t address, uint8_t value) {
|
void EightBit::Bus::write(const register16_t address, const uint8_t value) {
|
||||||
ADDRESS() = address;
|
ADDRESS() = address;
|
||||||
write(value);
|
write(value);
|
||||||
}
|
}
|
||||||
@@ -75,5 +75,5 @@ void EightBit::Bus::write(register16_t address, uint8_t value) {
|
|||||||
uint8_t& EightBit::Bus::reference() {
|
uint8_t& EightBit::Bus::reference() {
|
||||||
bool rom;
|
bool rom;
|
||||||
auto& value = reference(ADDRESS().word, rom);
|
auto& value = reference(ADDRESS().word, rom);
|
||||||
return LIKELY(!rom) ? referenceDATA(value) : placeDATA(value);
|
return rom ? placeDATA(value) : referenceDATA(value);
|
||||||
}
|
}
|
||||||
|
@@ -1,31 +1,31 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "InputOutput.h"
|
#include "InputOutput.h"
|
||||||
|
|
||||||
uint8_t EightBit::InputOutput::readInputPort(uint8_t port) {
|
uint8_t EightBit::InputOutput::readInputPort(const uint8_t port) {
|
||||||
OnReadingPort(port);
|
OnReadingPort(port);
|
||||||
const auto value = m_input[port];
|
const auto value = m_input[port];
|
||||||
OnReadPort(port);
|
OnReadPort(port);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::InputOutput::writeOutputPort(uint8_t port, uint8_t value) {
|
void EightBit::InputOutput::writeOutputPort(const uint8_t port, const uint8_t value) {
|
||||||
OnWritingPort(port);
|
OnWritingPort(port);
|
||||||
m_output[port] = value;
|
m_output[port] = value;
|
||||||
OnWrittenPort(port);
|
OnWrittenPort(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::InputOutput::OnReadingPort(uint8_t port) {
|
void EightBit::InputOutput::OnReadingPort(const uint8_t port) {
|
||||||
ReadingPort.fire(port);
|
ReadingPort.fire(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::InputOutput::OnReadPort(uint8_t port) {
|
void EightBit::InputOutput::OnReadPort(const uint8_t port) {
|
||||||
ReadPort.fire(port);
|
ReadPort.fire(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::InputOutput::OnWritingPort(uint8_t port) {
|
void EightBit::InputOutput::OnWritingPort(const uint8_t port) {
|
||||||
WritingPort.fire(port);
|
WritingPort.fire(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::InputOutput::OnWrittenPort(uint8_t port) {
|
void EightBit::InputOutput::OnWrittenPort(const uint8_t port) {
|
||||||
WrittenPort.fire(port);
|
WrittenPort.fire(port);
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ void EightBit::IntelProcessor::reset() {
|
|||||||
SP().word = AF().word = BC().word = DE().word = HL().word = Mask16;
|
SP().word = AF().word = BC().word = DE().word = HL().word = Mask16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::push(uint8_t value) {
|
void EightBit::IntelProcessor::push(const uint8_t value) {
|
||||||
BUS().write(--SP().word, value);
|
BUS().write(--SP().word, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ EightBit::register16_t EightBit::IntelProcessor::getWord() {
|
|||||||
return returned;
|
return returned;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::IntelProcessor::setWord(register16_t value) {
|
void EightBit::IntelProcessor::setWord(const register16_t value) {
|
||||||
BUS().write(MEMPTR().word++, value.low);
|
BUS().write(MEMPTR().word++, value.low);
|
||||||
BUS().write(++BUS().ADDRESS().word, value.high);
|
BUS().write(++BUS().ADDRESS().word, value.high);
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@ void EightBit::Processor::reset() {
|
|||||||
PC().word = 0;
|
PC().word = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EightBit::Processor::run(int limit) {
|
int EightBit::Processor::run(const int limit) {
|
||||||
int current = 0;
|
int current = 0;
|
||||||
while (LIKELY(powered()) && current < limit) {
|
while (LIKELY(powered()) && current < limit) {
|
||||||
current += singleStep();
|
current += singleStep();
|
||||||
|
Reference in New Issue
Block a user