Further 8080/Z80 interrupt rewrite

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2017-12-03 00:57:47 +00:00
parent 4f5e231dc4
commit 23f7a88480
6 changed files with 55 additions and 53 deletions

View File

@ -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;

View File

@ -276,6 +276,7 @@ int EightBit::Intel8080::step() {
}
return execute(instruction);
}
return cycles();
}
int EightBit::Intel8080::execute(uint8_t opcode) {

View File

@ -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();

View File

@ -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;
}

View File

@ -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 };

View File

@ -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;