mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2026-10-22 07:02:37 +00:00
Synchronise C++ code with C# code. Now Z80 passes HarteTests
This commit is contained in:
1 parent
46f03aa759
commit
e1ed8ea122
7 files changed
+110
-192
No files matched your search
@@ -7,7 +7,7 @@ void checker_t::addActualCycle(const uint16_t address, const uint8_t value, cons
|
||||
}
|
||||
|
||||
void checker_t::addActualCycle(const EightBit::register16_t address, const uint8_t value, const std::string& action) {
|
||||
addActualCycle(address.word, value, action);
|
||||
addActualCycle(address.joined, value, action);
|
||||
}
|
||||
|
||||
void checker_t::dumpCycles(const std::string which, const actual_cycles_t& events) {
|
||||
@@ -226,8 +226,8 @@ bool checker_t::checkState(test_t test) {
|
||||
|
||||
const auto final = test.final();
|
||||
|
||||
const auto pc_good = check("PC", final.pc(), cpu.PC().word);
|
||||
const auto sp_good = check("SP", final.sp(), cpu.SP().word);
|
||||
const auto pc_good = check("PC", final.pc(), cpu.PC().joined);
|
||||
const auto sp_good = check("SP", final.sp(), cpu.SP().joined);
|
||||
|
||||
const auto a_good = check("A", final.a(), cpu.A());
|
||||
const auto f_good = check("F", final.f(), cpu.F());
|
||||
@@ -248,26 +248,29 @@ bool checker_t::checkState(test_t test) {
|
||||
cpu.exxAF();
|
||||
cpu.exx();
|
||||
|
||||
const auto af_alt_good = check("AF'", final.af_(), cpu.AF().word);
|
||||
const auto bc_alt_good = check("BC'", final.bc_(), cpu.BC().word);
|
||||
const auto de_alt_good = check("DE'", final.de_(), cpu.DE().word);
|
||||
const auto hl_alt_good = check("DE'", final.de_(), cpu.DE().word);
|
||||
const auto af_alt_good = check("AF'", final.af_(), cpu.AF().joined);
|
||||
const auto bc_alt_good = check("BC'", final.bc_(), cpu.BC().joined);
|
||||
const auto de_alt_good = check("DE'", final.de_(), cpu.DE().joined);
|
||||
const auto hl_alt_good = check("HL'", final.hl_(), cpu.HL().joined);
|
||||
|
||||
cpu.exx();
|
||||
cpu.exxAF();
|
||||
|
||||
const auto i_good = check("I", final.i(), cpu.IV());
|
||||
const auto r_good = check("R", final.r(), (uint8_t)cpu.REFRESH());
|
||||
|
||||
const auto im_good = check("IM", final.im(), (uint8_t)cpu.IM());
|
||||
|
||||
const auto q_good = check("Q", final.im(), (uint8_t)cpu.IM());
|
||||
const auto q_good = check("Q", final.q(), (uint8_t)cpu.Q());
|
||||
|
||||
const auto iff1_good = check("IFF1", final.iff1(), (uint8_t)cpu.IFF1());
|
||||
const auto iff2_good = check("IFF2", final.iff2(), (uint8_t)cpu.IFF2());
|
||||
const auto iff_good = iff1_good && iff2_good;
|
||||
|
||||
const auto memptr_good = check("MEMPTR", final.wz(), cpu.MEMPTR().word);
|
||||
const auto memptr_good = check("MEMPTR", final.wz(), cpu.MEMPTR().joined);
|
||||
|
||||
const auto ix_good = check("IX", final.ix(), cpu.IX().word);
|
||||
const auto iy_good = check("IY", final.iy(), cpu.IY().word);
|
||||
const auto ix_good = check("IX", final.ix(), cpu.IX().joined);
|
||||
const auto iy_good = check("IY", final.iy(), cpu.IY().joined);
|
||||
|
||||
bool ram_problem = false;
|
||||
for (const auto entry : final.ram()) {
|
||||
@@ -319,7 +322,7 @@ void checker_t::check(test_t test) {
|
||||
|
||||
runner().raisePOWER();
|
||||
initialiseState(test);
|
||||
const auto pc = cpu.PC().word;
|
||||
const auto pc = cpu.PC().joined;
|
||||
|
||||
m_cycles = cpu.step();
|
||||
runner().lowerPOWER();
|
||||
@@ -336,11 +339,11 @@ void checker_t::check(test_t test) {
|
||||
add_disassembly(pc);
|
||||
|
||||
const auto final = test.final();
|
||||
raise("PC", final.pc(), cpu.PC().word);
|
||||
raise("SP", final.sp(), cpu.SP().word);
|
||||
raise("PC", final.pc(), cpu.PC().joined);
|
||||
raise("SP", final.sp(), cpu.SP().joined);
|
||||
|
||||
raise("A", final.a(), cpu.A());
|
||||
raiseFlags("F", final.a(), cpu.A());
|
||||
raiseFlags("F", final.f(), cpu.F());
|
||||
raise("B", final.b(), cpu.B());
|
||||
raise("C", final.c(), cpu.C());
|
||||
raise("D", final.d(), cpu.D());
|
||||
@@ -351,10 +354,10 @@ void checker_t::check(test_t test) {
|
||||
cpu.exx();
|
||||
cpu.exxAF();
|
||||
|
||||
raise("'AF", final.af_(), cpu.AF().word);
|
||||
raise("'BC", final.bc_(), cpu.BC().word);
|
||||
raise("'DE", final.de_(), cpu.DE().word);
|
||||
raise("'HL", final.hl_(), cpu.HL().word);
|
||||
raise("'AF", final.af_(), cpu.AF().joined);
|
||||
raise("'BC", final.bc_(), cpu.BC().joined);
|
||||
raise("'DE", final.de_(), cpu.DE().joined);
|
||||
raise("'HL", final.hl_(), cpu.HL().joined);
|
||||
|
||||
raise("I", final.i(), cpu.IV());
|
||||
raise("R", final.r(), cpu.REFRESH());
|
||||
@@ -366,10 +369,10 @@ void checker_t::check(test_t test) {
|
||||
raise("IFF1", final.iff1(), (uint8_t)cpu.IFF1());
|
||||
raise("IFF2", final.iff2(), (uint8_t)cpu.IFF2());
|
||||
|
||||
raise("WZ", final.wz(), cpu.MEMPTR().word);
|
||||
raise("WZ", final.wz(), cpu.MEMPTR().joined);
|
||||
|
||||
raise("IX", final.ix(), cpu.IX().word);
|
||||
raise("IY", final.iy(), cpu.IY().word);
|
||||
raise("IX", final.ix(), cpu.IX().joined);
|
||||
raise("IY", final.iy(), cpu.IY().joined);
|
||||
|
||||
os()
|
||||
<< std::dec << std::setfill(' ')
|
||||
|
||||
+8
-5
@@ -18,7 +18,7 @@ namespace EightBit {
|
||||
public:
|
||||
// ** From the Z80 CPU User Manual
|
||||
// RFSH.Refresh(output, active Low). RFSH, together with MREQ, indicates that the lower
|
||||
// seven bits of the system’s address bus can be used as a refresh address to the system’s
|
||||
// seven bits of the system’s address bus can be used as a refresh address to the system’s
|
||||
// dynamic memories.
|
||||
DECLARE_PIN_OUTPUT(RFSH)
|
||||
|
||||
@@ -208,8 +208,7 @@ namespace EightBit {
|
||||
[[nodiscard]] constexpr auto subtracting() noexcept { return subtractingTest(F()); }
|
||||
|
||||
void adjustStatusFlags(uint8_t value) noexcept {
|
||||
m_modifiedF = F();
|
||||
F() = value;
|
||||
F() = m_modifiedF = value;
|
||||
}
|
||||
|
||||
void setBit(StatusBits flag) noexcept { return adjustStatusFlags(setBit(F(), flag)); }
|
||||
@@ -386,6 +385,7 @@ namespace EightBit {
|
||||
void lddr() noexcept;
|
||||
|
||||
void repeatBlockInstruction() noexcept;
|
||||
void loadRepeat() noexcept;
|
||||
void adjustBlockRepeatFlagsIO() noexcept;
|
||||
void adjustBlockInputOutputFlags(int basis) noexcept;
|
||||
void adjustBlockInFlagsIncrement() noexcept;
|
||||
@@ -410,8 +410,8 @@ namespace EightBit {
|
||||
|
||||
void neg() noexcept;
|
||||
|
||||
void rrd(register16_t address, uint8_t& update) noexcept;
|
||||
void rld(register16_t address, uint8_t& update) noexcept;
|
||||
void rrd() noexcept;
|
||||
void rld() noexcept;
|
||||
|
||||
void writePort(register16_t port) noexcept;
|
||||
void writePort(uint8_t port) noexcept;
|
||||
@@ -426,5 +426,8 @@ namespace EightBit {
|
||||
void pushRegisterPair(int p);
|
||||
|
||||
void prefixCB();
|
||||
void prefixDD();
|
||||
void prefixED();
|
||||
void prefixFD();
|
||||
};
|
||||
}
|
||||
+73
-62
@@ -21,15 +21,12 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports) noexcept
|
||||
REFRESH() = 0;
|
||||
IV() = Mask8;
|
||||
|
||||
exxAF();
|
||||
exx();
|
||||
|
||||
IX() = IY() = Mask16;
|
||||
resetRegisterSet();
|
||||
});
|
||||
|
||||
RaisedM1.connect([this](EventArgs) {
|
||||
++REFRESH();
|
||||
exx();
|
||||
exxAF();
|
||||
|
||||
resetRegisterSet();
|
||||
});
|
||||
|
||||
LoweredRESET.connect([this](EventArgs) {
|
||||
@@ -114,7 +111,15 @@ bool EightBit::Z80::operator==(const EightBit::Z80& rhs) const noexcept {
|
||||
|
||||
DEFINE_PIN_LEVEL_CHANGERS(NMI, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(M1, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RFSH, Z80);
|
||||
void EightBit::Z80::raiseRFSH() noexcept {
|
||||
if (lowered(RFSH())) {
|
||||
RaisingRFSH.fire();
|
||||
raise(RFSH());
|
||||
++REFRESH();
|
||||
RaisedRFSH.fire();
|
||||
}
|
||||
}
|
||||
DEFINE_PIN_LEVEL_LOWER(RFSH, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(MREQ, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(IORQ, Z80);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(RD, Z80);
|
||||
@@ -195,23 +200,23 @@ void EightBit::Z80::handleNMI() noexcept {
|
||||
IFF2() = IFF1();
|
||||
IFF1() = false;
|
||||
lowerM1();
|
||||
auto _ = BUS().DATA();
|
||||
raiseM1();
|
||||
restart(0x66);
|
||||
}
|
||||
|
||||
uint8_t EightBit::Z80::readDataUnderInterrupt() noexcept {
|
||||
lowerM1();
|
||||
tick(2);
|
||||
tick(3);
|
||||
lowerIORQ();
|
||||
tick();
|
||||
const auto data = BUS().DATA();
|
||||
auto _ = BUS().DATA();
|
||||
raiseIORQ();
|
||||
assert(cycles() == 4);
|
||||
refreshMemory();
|
||||
assert(cycles() == 5);
|
||||
raiseM1();
|
||||
tick();
|
||||
return data;
|
||||
return BUS().DATA();
|
||||
}
|
||||
|
||||
void EightBit::Z80::handleINT() noexcept {
|
||||
@@ -272,10 +277,8 @@ bool EightBit::Z80::convertCondition(int flag) noexcept {
|
||||
}
|
||||
|
||||
void EightBit::Z80::returnConditionalFlag(const int flag) noexcept {
|
||||
const auto condition = convertCondition(flag);
|
||||
tick();
|
||||
if (condition)
|
||||
ret();
|
||||
IntelProcessor::returnConditionalFlag(flag);
|
||||
}
|
||||
|
||||
void EightBit::Z80::retn() noexcept {
|
||||
@@ -473,19 +476,19 @@ uint8_t EightBit::Z80::rrc(uint8_t operand) noexcept {
|
||||
}
|
||||
|
||||
uint8_t EightBit::Z80::rl(uint8_t operand) noexcept {
|
||||
clearBit(NF | HC);
|
||||
const auto carrying = carry();
|
||||
setBit(CF, operand & Bit7);
|
||||
const uint8_t result = (operand << 1) | carrying;
|
||||
clearBit(NF | HC);
|
||||
adjustXY(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::Z80::rr(uint8_t operand) noexcept {
|
||||
clearBit(NF | HC);
|
||||
const auto carrying = carry();
|
||||
setBit(CF, operand & Bit0);
|
||||
const uint8_t result = (operand >> 1) | (carrying << 7);
|
||||
clearBit(NF | HC);
|
||||
adjustXY(result);
|
||||
return result;
|
||||
}
|
||||
@@ -569,8 +572,8 @@ void EightBit::Z80::ccf() noexcept {
|
||||
}
|
||||
|
||||
void EightBit::Z80::cpl() noexcept {
|
||||
setBit(HC | NF);
|
||||
IntelProcessor::cpl();
|
||||
setBit(HC | NF);
|
||||
adjustXY(A());
|
||||
}
|
||||
|
||||
@@ -624,19 +627,18 @@ void EightBit::Z80::cpd() noexcept {
|
||||
|
||||
void EightBit::Z80::cpir() noexcept {
|
||||
cpi();
|
||||
if (parity() != 0 && zero() == 0) {
|
||||
if (parity() != 0 && zero() == 0)
|
||||
repeatBlockInstruction();
|
||||
tick(5);
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::Z80::cpdr() noexcept {
|
||||
cpd();
|
||||
if (parity() != 0 && zero() == 0) {
|
||||
repeatBlockInstruction();
|
||||
tick(5);
|
||||
} else {
|
||||
MEMPTR() = PC().joined - 2;
|
||||
MEMPTR() = PC();
|
||||
--MEMPTR();
|
||||
--MEMPTR();
|
||||
tick(2);
|
||||
}
|
||||
}
|
||||
@@ -664,36 +666,39 @@ void EightBit::Z80::ldi() noexcept {
|
||||
++DE();
|
||||
}
|
||||
|
||||
void EightBit::Z80::ldir() noexcept {
|
||||
ldi();
|
||||
void EightBit::Z80::loadRepeat() noexcept {
|
||||
if (parity() != 0)
|
||||
repeatBlockInstruction();
|
||||
tick(5);
|
||||
else
|
||||
tick(5);
|
||||
}
|
||||
|
||||
void EightBit::Z80::ldir() noexcept {
|
||||
ldi();
|
||||
loadRepeat();
|
||||
}
|
||||
|
||||
void EightBit::Z80::lddr() noexcept {
|
||||
ldd();
|
||||
if (parity() != 0)
|
||||
repeatBlockInstruction();
|
||||
tick(5);
|
||||
loadRepeat();
|
||||
}
|
||||
|
||||
void EightBit::Z80::repeatBlockInstruction() noexcept {
|
||||
MEMPTR() = --PC();
|
||||
--PC();
|
||||
adjustXY(PC().high);
|
||||
tick(5);
|
||||
}
|
||||
|
||||
void EightBit::Z80::adjustBlockRepeatFlagsIO() noexcept {
|
||||
auto direction = B();
|
||||
if (carry() != 0) {
|
||||
const auto negative = signTest(BUS().DATA()) != 0;
|
||||
const uint8_t direction = B() + (negative ? -1 : +1);
|
||||
const auto calculatedParity = (parity() >> 2) ^ (evenParity(direction & Mask::Mask3) ? 1 : 0) ^ 1;
|
||||
setBit(PF, calculatedParity != 0);
|
||||
direction += (negative ? -1 : +1);
|
||||
setBit(HC, (B() & Mask::Mask4) == (negative ? 0 : Mask::Mask4));
|
||||
} else {
|
||||
adjustParity((B() & Mask::Mask3));
|
||||
}
|
||||
const auto calculatedParity = (parity() >> 2) ^ (evenParity(direction & Mask::Mask3) ? 1 : 0) ^ 1;
|
||||
setBit(PF, calculatedParity != 0);
|
||||
}
|
||||
|
||||
void EightBit::Z80::adjustBlockInputOutputFlags(int basis) noexcept {
|
||||
@@ -743,7 +748,6 @@ void EightBit::Z80::inir() noexcept {
|
||||
if (zero() == 0) {
|
||||
repeatBlockInstruction();
|
||||
adjustBlockRepeatFlagsIO();
|
||||
tick(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,7 +756,6 @@ void EightBit::Z80::indr() noexcept {
|
||||
if (zero() == 0) {
|
||||
repeatBlockInstruction();
|
||||
adjustBlockRepeatFlagsIO();
|
||||
tick(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +785,6 @@ void EightBit::Z80::otir() noexcept {
|
||||
if (zero() == 0) {
|
||||
repeatBlockInstruction();
|
||||
adjustBlockRepeatFlagsIO();
|
||||
tick(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,29 +793,26 @@ void EightBit::Z80::otdr() noexcept {
|
||||
if (zero() == 0) {
|
||||
repeatBlockInstruction();
|
||||
adjustBlockRepeatFlagsIO();
|
||||
tick(5);
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::Z80::rrd(register16_t address, uint8_t& update) noexcept {
|
||||
MEMPTR() = BUS().ADDRESS() = address;
|
||||
++MEMPTR();
|
||||
const auto memory = memoryRead();
|
||||
tick(4);
|
||||
IntelProcessor::memoryWrite(promoteNibble(update) | highNibble(memory));
|
||||
update = higherNibble(update) | lowerNibble(memory);
|
||||
adjustSZPXY(update);
|
||||
void EightBit::Z80::rrd() noexcept {
|
||||
readMemoryIndirect(HL());
|
||||
const auto memory = BUS().DATA();
|
||||
BUS().DATA() = promoteNibble(A()) | highNibble(memory);
|
||||
memoryUpdate(5);
|
||||
A() = higherNibble(A()) | lowerNibble(memory);
|
||||
adjustSZPXY(A());
|
||||
clearBit(NF | HC);
|
||||
}
|
||||
|
||||
void EightBit::Z80::rld(register16_t address, uint8_t& update) noexcept {
|
||||
MEMPTR() = BUS().ADDRESS() = address;
|
||||
++MEMPTR();
|
||||
const auto memory = memoryRead();
|
||||
tick(4);
|
||||
IntelProcessor::memoryWrite(promoteNibble(memory) | lowNibble(update));
|
||||
update = higherNibble(update) | highNibble(memory);
|
||||
adjustSZPXY(update);
|
||||
void EightBit::Z80::rld() noexcept {
|
||||
readMemoryIndirect(HL());
|
||||
const auto memory = BUS().DATA();
|
||||
BUS().DATA() = promoteNibble(memory) | lowNibble(A());
|
||||
memoryUpdate(5);
|
||||
A() = higherNibble(A()) | highNibble(memory);
|
||||
adjustSZPXY(A());
|
||||
clearBit(NF | HC);
|
||||
}
|
||||
|
||||
@@ -1255,10 +1254,10 @@ void EightBit::Z80::executeED(const int x, const int y, const int z, const int p
|
||||
readInternalRegister([this]() { return REFRESH(); });
|
||||
break;
|
||||
case 4: // RRD
|
||||
rrd(HL(), A());
|
||||
rrd();
|
||||
break;
|
||||
case 5: // RLD
|
||||
rld(HL(), A());
|
||||
rld();
|
||||
break;
|
||||
case 6: // NOP
|
||||
case 7: // NOP
|
||||
@@ -1665,16 +1664,13 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
callIndirect();
|
||||
break;
|
||||
case 1: // DD prefix
|
||||
m_prefixDD = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
prefixDD();
|
||||
break;
|
||||
case 2: // ED prefix
|
||||
m_prefixED = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
prefixED();
|
||||
break;
|
||||
case 3: // FD prefix
|
||||
m_prefixFD = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
prefixFD();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
@@ -1746,6 +1742,21 @@ void EightBit::Z80::pushRegisterPair(int p) {
|
||||
pushShort(RP2(p));
|
||||
}
|
||||
|
||||
void EightBit::Z80::prefixDD() {
|
||||
m_prefixDD = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
}
|
||||
|
||||
void EightBit::Z80::prefixED() {
|
||||
m_prefixED = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
}
|
||||
|
||||
void EightBit::Z80::prefixFD() {
|
||||
m_prefixFD = true;
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
}
|
||||
|
||||
void EightBit::Z80::prefixCB() {
|
||||
m_prefixCB = true;
|
||||
if (displaced()) {
|
||||
|
||||
@@ -154,6 +154,7 @@ namespace EightBit {
|
||||
virtual void jumpIndirect() noexcept;
|
||||
void jump() noexcept;
|
||||
void callIndirect() noexcept;
|
||||
using Processor::call;
|
||||
void call() noexcept;
|
||||
virtual void jumpRelative(int8_t offset) noexcept;
|
||||
void jumpRelative(uint8_t offset) noexcept { jumpRelative(static_cast<int8_t>(offset)); }
|
||||
|
||||
+2
-2
@@ -64,11 +64,11 @@ namespace EightBit {
|
||||
void memoryWrite(register16_t address) noexcept;
|
||||
void memoryWrite(uint8_t data) noexcept;
|
||||
virtual void memoryWrite() noexcept;
|
||||
virtual void busWrite() noexcept;
|
||||
void busWrite() noexcept;
|
||||
|
||||
uint8_t memoryRead(register16_t address) noexcept;
|
||||
virtual uint8_t memoryRead() noexcept;
|
||||
virtual uint8_t busRead() noexcept;
|
||||
uint8_t busRead() noexcept;
|
||||
|
||||
virtual register16_t& incrementPC() noexcept;
|
||||
|
||||
|
||||
-100
@@ -28,103 +28,3 @@ namespace EightBit {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//#pragma once
|
||||
//
|
||||
//#include <cstring>
|
||||
//#include <type_traits>
|
||||
//#include <vector>
|
||||
//#include "EventArgs.h"
|
||||
//
|
||||
//namespace EightBit {
|
||||
// template<class T> class Signal final {
|
||||
// private:
|
||||
// using fn_t = void(*)(void*, T&);
|
||||
// using dtor_t = void(*)(void*);
|
||||
//
|
||||
// struct Entry {
|
||||
// void* ctx;
|
||||
// fn_t fn;
|
||||
// dtor_t dtor; // null for inline-stored (trivially-destructible) callables
|
||||
// };
|
||||
//
|
||||
// int m_count = 0;
|
||||
// std::vector<Entry> m_delegates;
|
||||
//
|
||||
// void destroy_entries() noexcept {
|
||||
// for (auto& e : m_delegates)
|
||||
// if (e.dtor) e.dtor(e.ctx);
|
||||
// m_delegates.clear();
|
||||
// m_count = 0;
|
||||
// }
|
||||
//
|
||||
// public:
|
||||
// Signal() = default;
|
||||
//
|
||||
// // Copies are connection-less: a copied chip instance starts with no listeners
|
||||
// Signal(const Signal&) noexcept {}
|
||||
// Signal& operator=(const Signal&) noexcept { destroy_entries(); return *this; }
|
||||
//
|
||||
// ~Signal() { destroy_entries(); }
|
||||
//
|
||||
// template<typename Callable>
|
||||
// void connect(Callable&& callable) {
|
||||
// using Decay = std::decay_t<Callable>;
|
||||
//
|
||||
// // [this] lambdas on x64: sizeof == 8 == sizeof(void*), trivially copyable/destructible.
|
||||
// // Pack the captured pointer directly into the void* slot — zero heap overhead,
|
||||
// // and the dispatch function knows the concrete type so c(e) can be inlined.
|
||||
// constexpr bool fits_inline =
|
||||
// sizeof(Decay) <= sizeof(void*) &&
|
||||
// alignof(Decay) <= alignof(void*) &&
|
||||
// std::is_trivially_copyable_v<Decay> &&
|
||||
// std::is_trivially_destructible_v<Decay>;
|
||||
//
|
||||
// if constexpr (fits_inline) {
|
||||
// void* storage = nullptr;
|
||||
// std::memcpy(&storage, &callable, sizeof(Decay));
|
||||
// m_delegates.push_back({
|
||||
// storage,
|
||||
// [](void* raw, T& e) noexcept {
|
||||
// // Reconstruct the callable from the packed pointer bits.
|
||||
// // Trivially-copyable, so memcpy into aligned storage is valid.
|
||||
// alignas(Decay) char buf[sizeof(Decay)];
|
||||
// std::memcpy(buf, &raw, sizeof(Decay));
|
||||
// (*reinterpret_cast<Decay*>(buf))(e);
|
||||
// },
|
||||
// nullptr
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// auto* heap = new Decay(std::forward<Callable>(callable));
|
||||
// m_delegates.push_back({
|
||||
// static_cast<void*>(heap),
|
||||
// [](void* raw, T& e) noexcept {
|
||||
// (*static_cast<Decay*>(raw))(e);
|
||||
// },
|
||||
// [](void* raw) noexcept {
|
||||
// delete static_cast<Decay*>(raw);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// ++m_count;
|
||||
// }
|
||||
//
|
||||
// [[nodiscard]] constexpr auto count() const noexcept { return m_count; }
|
||||
// [[nodiscard]] constexpr auto inactive() const noexcept { return count() == 0; }
|
||||
// [[nodiscard]] constexpr auto singular() const noexcept { return count() == 1; }
|
||||
// [[nodiscard]] constexpr auto active() const noexcept { return count() != 0; }
|
||||
//
|
||||
// void fire(T& e = EventArgs::empty()) const noexcept {
|
||||
// //if (inactive()) return;
|
||||
// //if (singular()) {
|
||||
// // m_delegates[0].fn(m_delegates[0].ctx, e);
|
||||
// // return;
|
||||
// //}
|
||||
// for (const auto& entry : m_delegates)
|
||||
// entry.fn(entry.ctx, e);
|
||||
// }
|
||||
// };
|
||||
//}
|
||||
@@ -123,7 +123,7 @@ void EightBit::IntelProcessor::callIndirect() noexcept {
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::call() noexcept {
|
||||
LittleEndianProcessor::call(MEMPTR());
|
||||
call(MEMPTR());
|
||||
}
|
||||
|
||||
void EightBit::IntelProcessor::jumpConditionalFlag(int flag) noexcept {
|
||||
|
||||
Reference in new issue
Block a user