mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-11 17:29:57 +00:00
Further 8080/Z80 interrupt rewrite
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
4f5e231dc4
commit
23f7a88480
@ -26,7 +26,7 @@ namespace EightBit {
|
||||
|
||||
Signal<Intel8080> ExecutingInstruction;
|
||||
|
||||
bool& INT() { return m_interruptLine; }
|
||||
bool& INT() { return m_intLine; }
|
||||
|
||||
virtual int execute(uint8_t opcode);
|
||||
int step();
|
||||
@ -38,7 +38,8 @@ namespace EightBit {
|
||||
|
||||
private:
|
||||
bool m_interruptEnable = false;
|
||||
bool m_interruptLine = false;
|
||||
bool m_intLine = false;
|
||||
|
||||
InputOutput& m_ports;
|
||||
|
||||
register16_t af;
|
||||
|
@ -276,6 +276,7 @@ int EightBit::Intel8080::step() {
|
||||
}
|
||||
return execute(instruction);
|
||||
}
|
||||
return cycles();
|
||||
}
|
||||
|
||||
int EightBit::Intel8080::execute(uint8_t opcode) {
|
||||
|
@ -327,7 +327,7 @@ int EightBit::GameBoy::LR35902::step() {
|
||||
ExecutingInstruction.fire(*this);
|
||||
m_prefixCB = false;
|
||||
resetCycles();
|
||||
const auto ran = fetchExecute();
|
||||
const auto ran = execute(fetchByte());
|
||||
ExecutedInstruction.fire(*this);
|
||||
return ran;
|
||||
}
|
||||
@ -748,7 +748,7 @@ void EightBit::GameBoy::LR35902::executeOther(int x, int y, int z, int p, int q)
|
||||
break;
|
||||
case 1: // CB prefix
|
||||
m_prefixCB = true;
|
||||
fetchExecute();
|
||||
execute(fetchByte());
|
||||
break;
|
||||
case 6: // DI
|
||||
di();
|
||||
|
@ -41,7 +41,7 @@ void EightBit::MOS6502::initialise() {
|
||||
int EightBit::MOS6502::step() {
|
||||
ExecutingInstruction.fire(*this);
|
||||
resetCycles();
|
||||
auto returned = fetchExecute();
|
||||
auto returned = execute(fetchByte());
|
||||
ExecutedInstruction.fire(*this);
|
||||
return returned;
|
||||
}
|
||||
|
@ -50,11 +50,10 @@ namespace EightBit {
|
||||
|
||||
Signal<Z80> ExecutingInstruction;
|
||||
|
||||
int interruptMaskable(uint8_t value) { return interrupt(true, value); }
|
||||
int interruptMaskable() { return interruptMaskable(0); }
|
||||
int interruptNonMaskable() { return interrupt(false, 0); }
|
||||
bool& INT() { return m_intLine; }
|
||||
bool& NMI() { return m_nmiLine; }
|
||||
|
||||
int interrupt(bool maskable, uint8_t value);
|
||||
//int interrupt(bool maskable, uint8_t value);
|
||||
|
||||
virtual int execute(uint8_t opcode) final;
|
||||
virtual int step() final;
|
||||
@ -90,10 +89,10 @@ namespace EightBit {
|
||||
|
||||
virtual void reset() override;
|
||||
|
||||
protected:
|
||||
virtual int fetchExecute() override;
|
||||
|
||||
private:
|
||||
bool m_intLine = false;
|
||||
bool m_nmiLine = false;
|
||||
|
||||
InputOutput& m_ports;
|
||||
|
||||
enum { BC_IDX, DE_IDX, HL_IDX };
|
||||
|
@ -24,11 +24,6 @@ EightBit::register16_t& EightBit::Z80::HL() {
|
||||
return m_registers[m_registerSet][HL_IDX];
|
||||
}
|
||||
|
||||
int EightBit::Z80::fetchExecute() {
|
||||
M1() = true;
|
||||
return IntelProcessor::fetchExecute();
|
||||
}
|
||||
|
||||
void EightBit::Z80::reset() {
|
||||
|
||||
IntelProcessor::reset();
|
||||
@ -62,37 +57,6 @@ void EightBit::Z80::ei() {
|
||||
IFF1() = IFF2() = true;
|
||||
}
|
||||
|
||||
int EightBit::Z80::interrupt(const bool maskable, const uint8_t value) {
|
||||
resetCycles();
|
||||
if (!maskable || (maskable && IFF1())) {
|
||||
if (maskable) {
|
||||
di();
|
||||
switch (IM()) {
|
||||
case 0:
|
||||
M1() = true;
|
||||
addCycles(execute(value));
|
||||
break;
|
||||
case 1:
|
||||
restart(7 << 3);
|
||||
addCycles(13);
|
||||
break;
|
||||
case 2:
|
||||
pushWord(PC());
|
||||
PC().low = value;
|
||||
PC().high = IV();
|
||||
addCycles(19);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
IFF1() = false;
|
||||
restart(0x66);
|
||||
addCycles(13);
|
||||
}
|
||||
}
|
||||
// Could be zero for a masked interrupt...
|
||||
return cycles();
|
||||
}
|
||||
|
||||
void EightBit::Z80::increment(uint8_t& f, uint8_t& operand) {
|
||||
clearFlag(f, NF);
|
||||
adjustSZXY<Z80>(f, ++operand);
|
||||
@ -685,7 +649,40 @@ int EightBit::Z80::step() {
|
||||
ExecutingInstruction.fire(*this);
|
||||
m_displaced = m_prefixCB = m_prefixDD = m_prefixED = m_prefixFD = false;
|
||||
resetCycles();
|
||||
return fetchExecute();
|
||||
if (LIKELY(powered())) {
|
||||
M1() = true;
|
||||
uint8_t instruction;
|
||||
if (UNLIKELY(NMI())) {
|
||||
NMI() = IFF1() = false;
|
||||
restart(0x66);
|
||||
addCycles(13);
|
||||
return cycles();
|
||||
} else if (UNLIKELY(INT() && IFF1())) {
|
||||
di();
|
||||
switch (IM()) {
|
||||
case 0:
|
||||
instruction = BUS().DATA();
|
||||
break;
|
||||
case 1:
|
||||
restart(7 << 3);
|
||||
addCycles(13);
|
||||
return cycles();
|
||||
case 2:
|
||||
pushWord(PC());
|
||||
PC().low = BUS().DATA();
|
||||
PC().high = IV();
|
||||
addCycles(19);
|
||||
return cycles();
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
} else {
|
||||
instruction = fetchByte();
|
||||
}
|
||||
M1() = true;
|
||||
return execute(instruction);
|
||||
}
|
||||
return cycles();
|
||||
}
|
||||
|
||||
int EightBit::Z80::execute(const uint8_t opcode) {
|
||||
@ -1374,7 +1371,8 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
m_prefixCB = true;
|
||||
if (UNLIKELY(m_displaced))
|
||||
fetchDisplacement();
|
||||
fetchExecute();
|
||||
M1() = true;
|
||||
execute(fetchByte());
|
||||
break;
|
||||
case 2: // OUT (n),A
|
||||
writePort(fetchByte(), a);
|
||||
@ -1424,15 +1422,18 @@ void EightBit::Z80::executeOther(const int x, const int y, const int z, const in
|
||||
break;
|
||||
case 1: // DD prefix
|
||||
m_displaced = m_prefixDD = true;
|
||||
fetchExecute();
|
||||
M1() = true;
|
||||
execute(fetchByte());
|
||||
break;
|
||||
case 2: // ED prefix
|
||||
m_prefixED = true;
|
||||
fetchExecute();
|
||||
M1() = true;
|
||||
execute(fetchByte());
|
||||
break;
|
||||
case 3: // FD prefix
|
||||
m_displaced = m_prefixFD = true;
|
||||
fetchExecute();
|
||||
M1() = true;
|
||||
execute(fetchByte());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user