mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2026-03-15 16:16:36 +00:00
A step closer to the .net implementation
This commit is contained in:
@@ -76,7 +76,7 @@ namespace EightBit {
|
||||
bool operator==(const Z80& rhs) const;
|
||||
|
||||
void execute() noexcept final;
|
||||
int step() noexcept final;
|
||||
void poweredStep() noexcept final;
|
||||
|
||||
[[nodiscard]] const register16_t& AF() const noexcept final;
|
||||
[[nodiscard]] auto& AF() noexcept { return IntelProcessor::AF(); }
|
||||
@@ -147,6 +147,10 @@ namespace EightBit {
|
||||
int jrConditional(int condition) noexcept final;
|
||||
|
||||
private:
|
||||
bool m_interruptPending = false;
|
||||
bool m_nonMaskableInterruptPending = false;
|
||||
bool m_resetPending = false;
|
||||
|
||||
InputOutput& m_ports;
|
||||
|
||||
enum { BC_IDX, DE_IDX, HL_IDX };
|
||||
@@ -193,7 +197,7 @@ namespace EightBit {
|
||||
}
|
||||
|
||||
void fetchDisplacement() noexcept;
|
||||
[[nodiscard]] uint8_t fetchOpCode() noexcept;
|
||||
[[nodiscard]] uint8_t fetchInstruction() noexcept;
|
||||
|
||||
uint8_t readBusDataM1() noexcept;
|
||||
|
||||
|
||||
@@ -26,13 +26,23 @@ EightBit::Z80::Z80(Bus& bus, InputOutput& ports)
|
||||
|
||||
IX() = IY() = Mask16;
|
||||
resetWorkingRegisters();
|
||||
|
||||
resetPrefixes();
|
||||
});
|
||||
|
||||
RaisedM1.connect([this](EventArgs) {
|
||||
++REFRESH();
|
||||
});
|
||||
|
||||
LoweredRESET.connect([this](EventArgs) {
|
||||
m_resetPending = true;
|
||||
});
|
||||
|
||||
LoweredNMI.connect([this](EventArgs) {
|
||||
m_nonMaskableInterruptPending = true;
|
||||
});
|
||||
|
||||
LoweredINT.connect([this](EventArgs) {
|
||||
m_interruptPending = true;
|
||||
});
|
||||
}
|
||||
|
||||
EightBit::Z80::Z80(const Z80& rhs)
|
||||
@@ -660,7 +670,7 @@ uint8_t EightBit::Z80::readBusDataM1() noexcept {
|
||||
// received from the memory is ignored and an NOP instruction is forced internally to the
|
||||
// CPU.The HALT acknowledge signal is active during this time indicating that the processor
|
||||
// is in the HALT state
|
||||
uint8_t EightBit::Z80::fetchOpCode() noexcept {
|
||||
uint8_t EightBit::Z80::fetchInstruction() noexcept {
|
||||
uint8_t returned;
|
||||
{
|
||||
_ActivateM1 m1(*this);
|
||||
@@ -820,32 +830,30 @@ void EightBit::Z80::R2(const int r, const uint8_t value) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
int EightBit::Z80::step() noexcept {
|
||||
resetCycles();
|
||||
ExecutingInstruction.fire();
|
||||
if (LIKELY(powered())) {
|
||||
resetPrefixes();
|
||||
bool handled = false;
|
||||
if (lowered(RESET())) {
|
||||
handleRESET();
|
||||
handled = true;
|
||||
} else if (lowered(NMI())) {
|
||||
handleNMI();
|
||||
handled = true;
|
||||
} else if (lowered(INT())) {
|
||||
raiseINT();
|
||||
raiseHALT();
|
||||
if (IFF1()) {
|
||||
handleINT();
|
||||
handled = true;
|
||||
}
|
||||
void EightBit::Z80::poweredStep() noexcept {
|
||||
|
||||
m_modifiedF = 0;
|
||||
m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
||||
|
||||
if (m_resetPending) {
|
||||
m_resetPending = false;
|
||||
handleRESET();
|
||||
return;
|
||||
} else if (m_nonMaskableInterruptPending) {
|
||||
m_nonMaskableInterruptPending = false;
|
||||
handleNMI();
|
||||
return;
|
||||
} else if (m_interruptPending) {
|
||||
m_interruptPending = false;
|
||||
if (IFF1()) {
|
||||
handleINT();
|
||||
return;
|
||||
}
|
||||
if (!handled)
|
||||
IntelProcessor::execute(fetchOpCode());
|
||||
}
|
||||
ExecutedInstruction.fire();
|
||||
ASSUME(cycles() > 0);
|
||||
return cycles();
|
||||
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
|
||||
Q() = m_modifiedF;
|
||||
}
|
||||
|
||||
void EightBit::Z80::execute() noexcept {
|
||||
@@ -1419,7 +1427,7 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
fetchDisplacement();
|
||||
IntelProcessor::execute(fetchByte());
|
||||
} else {
|
||||
IntelProcessor::execute(fetchOpCode());
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
}
|
||||
break;
|
||||
case 2: // OUT (n),A
|
||||
@@ -1460,15 +1468,15 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
break;
|
||||
case 1: // DD prefix
|
||||
m_prefixDD = true;
|
||||
IntelProcessor::execute(fetchOpCode());
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
break;
|
||||
case 2: // ED prefix
|
||||
m_prefixED = true;
|
||||
IntelProcessor::execute(fetchOpCode());
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
break;
|
||||
case 3: // FD prefix
|
||||
m_prefixFD = true;
|
||||
IntelProcessor::execute(fetchOpCode());
|
||||
IntelProcessor::execute(fetchInstruction());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
|
||||
@@ -40,7 +40,8 @@ namespace EightBit {
|
||||
[[nodiscard]] constexpr const auto& intermediate() const noexcept { return m_intermediate; }
|
||||
|
||||
int run(int limit) noexcept;
|
||||
virtual int step() noexcept = 0;
|
||||
virtual int step() noexcept;
|
||||
virtual void poweredStep() noexcept = 0;
|
||||
virtual void execute() noexcept = 0;
|
||||
void execute(uint8_t value) noexcept;
|
||||
|
||||
|
||||
@@ -94,6 +94,16 @@ void EightBit::Processor::setWord(const register16_t address, const register16_t
|
||||
setWord(value);
|
||||
}
|
||||
|
||||
int EightBit::Processor::step() noexcept {
|
||||
resetCycles();
|
||||
ExecutingInstruction.fire();
|
||||
if (LIKELY(powered()))
|
||||
poweredStep();
|
||||
ExecutedInstruction.fire();
|
||||
ASSUME(cycles() > 0);
|
||||
return cycles();
|
||||
}
|
||||
|
||||
int EightBit::Processor::run(const int limit) noexcept {
|
||||
int current = 0;
|
||||
while (LIKELY(powered() && (current < limit)))
|
||||
|
||||
Reference in New Issue
Block a user