cpu - best effort implementation of haltbug
This commit is contained in:
parent
c1ba944fc9
commit
57f029bc6e
3 changed files with 26 additions and 7 deletions
26
cpu/cpu.cpp
26
cpu/cpu.cpp
|
@ -84,20 +84,35 @@ void Cpu::reset()
|
||||||
state.IF = 0;
|
state.IF = 0;
|
||||||
|
|
||||||
state.halted = false;
|
state.halted = false;
|
||||||
|
state.haltbug = false;
|
||||||
state.stopped = false;
|
state.stopped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 Cpu::readPC8()
|
u8 Cpu::readPC8()
|
||||||
{
|
{
|
||||||
u8 data = bus->read8(state.PC);
|
u8 data = bus->read8(state.PC);
|
||||||
state.PC++;
|
if(!state.haltbug)
|
||||||
|
state.PC++;
|
||||||
|
else
|
||||||
|
state.haltbug = false;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 Cpu::readPC16()
|
u16 Cpu::readPC16()
|
||||||
{
|
{
|
||||||
u16 data = bus->read16(state.PC);
|
u16 data;
|
||||||
state.PC+=2;
|
if(state.haltbug)
|
||||||
|
{
|
||||||
|
data = bus->read8(state.PC);
|
||||||
|
data |= data << 8; // Same byte twice
|
||||||
|
state.PC++;
|
||||||
|
state.haltbug = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = bus->read16(state.PC);
|
||||||
|
state.PC+=2;
|
||||||
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,11 +245,8 @@ void Cpu::aluop8(AluOp op, u8 lhs, u8 rhs, u8& out, bool update_carry)
|
||||||
|
|
||||||
bool Cpu::handleInterrupts()
|
bool Cpu::handleInterrupts()
|
||||||
{
|
{
|
||||||
// servicable interrupts (assuming IME is on)
|
|
||||||
u8 si = state.IE & state.IF & INT_MASK;
|
|
||||||
|
|
||||||
// Once there's an interrupt we exit halt mode
|
// Once there's an interrupt we exit halt mode
|
||||||
if (si)
|
if (state.SI())
|
||||||
state.halted = false;
|
state.halted = false;
|
||||||
|
|
||||||
if (state.IME == IME_SCHEDULED)
|
if (state.IME == IME_SCHEDULED)
|
||||||
|
|
|
@ -116,7 +116,12 @@ struct Cpu_state {
|
||||||
u8 IE;
|
u8 IE;
|
||||||
u8 IF;
|
u8 IF;
|
||||||
|
|
||||||
|
// servicable interrupts
|
||||||
|
inline u8 SI() const
|
||||||
|
{ return INT_MASK & IE & IF; }
|
||||||
|
|
||||||
bool halted;
|
bool halted;
|
||||||
|
bool haltbug;
|
||||||
bool stopped;
|
bool stopped;
|
||||||
|
|
||||||
void setAF(u16 v);
|
void setAF(u16 v);
|
||||||
|
|
|
@ -443,6 +443,8 @@ void Cpu::executeInstruction()
|
||||||
break;
|
break;
|
||||||
case 0x76: // HALT
|
case 0x76: // HALT
|
||||||
state.halted = true;
|
state.halted = true;
|
||||||
|
if(state.IME != IME_ON && state.SI())
|
||||||
|
state.haltbug = true;
|
||||||
break;
|
break;
|
||||||
case 0x10: // STOP n8
|
case 0x10: // STOP n8
|
||||||
(void)readPC8();
|
(void)readPC8();
|
||||||
|
|
Loading…
Reference in a new issue