mirror of https://github.com/Washi1337/Emux.git
Bugfix: Interrupts now interrupt HALT regardless of value of IME
This commit is contained in:
parent
2c1ac18334
commit
c9442e221b
|
@ -223,8 +223,8 @@ namespace Emux.GameBoy.Cpu
|
|||
|
||||
// Check for interrupts.
|
||||
bool interrupted = false;
|
||||
if (Registers.IME && !Registers.IMESet
|
||||
&& Registers.IE != InterruptFlags.None
|
||||
|
||||
if (Registers.IE != InterruptFlags.None
|
||||
&& Registers.IF != (InterruptFlags) 0xE0)
|
||||
{
|
||||
byte firedAndEnabled = (byte) (Registers.IE & Registers.IF);
|
||||
|
@ -232,11 +232,15 @@ namespace Emux.GameBoy.Cpu
|
|||
{
|
||||
if ((firedAndEnabled & (1 << i)) == (1 << i))
|
||||
{
|
||||
Registers.IF &= (InterruptFlags) ~(1u << i);
|
||||
Registers.IME = false;
|
||||
interrupted = true;
|
||||
Rst((byte) (0x40 + (i << 3)));
|
||||
cycles += 12;
|
||||
if (Registers.IME && !Registers.IMESet)
|
||||
{
|
||||
Registers.IF &= (InterruptFlags) ~(1u << i);
|
||||
Registers.IME = false;
|
||||
interrupted = true;
|
||||
Rst((byte) (0x40 + (i << 3)));
|
||||
cycles += 12;
|
||||
}
|
||||
|
||||
_halt = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -550,7 +550,7 @@ namespace Emux.GameBoy.Cpu
|
|||
new Z80OpCode("res 7, a", 0xCB, 0xBF, 0, 8, (d, i) => d.Cpu.Registers.A = d.Cpu.Alu.Res(d.Cpu.Registers.A, 7)),
|
||||
|
||||
|
||||
// 0x80 .. 0x8F
|
||||
// 0xC0 .. 0xCF
|
||||
new Z80OpCode("set 0, b", 0xCB, 0xC0, 0, 8, (d, i) => d.Cpu.Registers.B = d.Cpu.Alu.Set(d.Cpu.Registers.B, 0)),
|
||||
new Z80OpCode("set 0, c", 0xCB, 0xC1, 0, 8, (d, i) => d.Cpu.Registers.C = d.Cpu.Alu.Set(d.Cpu.Registers.C, 0)),
|
||||
new Z80OpCode("set 0, d", 0xCB, 0xC2, 0, 8, (d, i) => d.Cpu.Registers.D = d.Cpu.Alu.Set(d.Cpu.Registers.D, 0)),
|
||||
|
@ -568,7 +568,7 @@ namespace Emux.GameBoy.Cpu
|
|||
new Z80OpCode("set 1, (hl)", 0xCB, 0xCE, 0, 16, (d, i) => d.Memory.WriteByte(d.Cpu.Registers.HL, d.Cpu.Alu.Set(d.Memory.ReadByte(d.Cpu.Registers.HL), 1))),
|
||||
new Z80OpCode("set 1, a", 0xCB, 0xCF, 0, 8, (d, i) => d.Cpu.Registers.A = d.Cpu.Alu.Set(d.Cpu.Registers.A, 1)),
|
||||
|
||||
// 0x90 .. 0x9F
|
||||
// 0xD0 .. 0xDF
|
||||
new Z80OpCode("set 2, b", 0xCB, 0xD0, 0, 8, (d, i) => d.Cpu.Registers.B = d.Cpu.Alu.Set(d.Cpu.Registers.B, 2)),
|
||||
new Z80OpCode("set 2, c", 0xCB, 0xD1, 0, 8, (d, i) => d.Cpu.Registers.C = d.Cpu.Alu.Set(d.Cpu.Registers.C, 2)),
|
||||
new Z80OpCode("set 2, d", 0xCB, 0xD2, 0, 8, (d, i) => d.Cpu.Registers.D = d.Cpu.Alu.Set(d.Cpu.Registers.D, 2)),
|
||||
|
@ -586,7 +586,7 @@ namespace Emux.GameBoy.Cpu
|
|||
new Z80OpCode("set 3, (hl)", 0xCB, 0xDE, 0, 16, (d, i) => d.Memory.WriteByte(d.Cpu.Registers.HL, d.Cpu.Alu.Set(d.Memory.ReadByte(d.Cpu.Registers.HL), 3))),
|
||||
new Z80OpCode("set 3, a", 0xCB, 0xDF, 0, 8, (d, i) => d.Cpu.Registers.A = d.Cpu.Alu.Set(d.Cpu.Registers.A, 3)),
|
||||
|
||||
// 0xA0 .. 0xAF
|
||||
// 0xE0 .. 0xEF
|
||||
new Z80OpCode("set 4, b", 0xCB, 0xE0, 0, 8, (d, i) => d.Cpu.Registers.B = d.Cpu.Alu.Set(d.Cpu.Registers.B, 4)),
|
||||
new Z80OpCode("set 4, c", 0xCB, 0xE1, 0, 8, (d, i) => d.Cpu.Registers.C = d.Cpu.Alu.Set(d.Cpu.Registers.C, 4)),
|
||||
new Z80OpCode("set 4, d", 0xCB, 0xE2, 0, 8, (d, i) => d.Cpu.Registers.D = d.Cpu.Alu.Set(d.Cpu.Registers.D, 4)),
|
||||
|
@ -604,7 +604,7 @@ namespace Emux.GameBoy.Cpu
|
|||
new Z80OpCode("set 5, (hl)", 0xCB, 0xEE, 0, 16, (d, i) => d.Memory.WriteByte(d.Cpu.Registers.HL, d.Cpu.Alu.Set(d.Memory.ReadByte(d.Cpu.Registers.HL), 5))),
|
||||
new Z80OpCode("set 5, a", 0xCB, 0xEF, 0, 8, (d, i) => d.Cpu.Registers.A = d.Cpu.Alu.Set(d.Cpu.Registers.A, 5)),
|
||||
|
||||
// 0xB0 .. 0xBF
|
||||
// 0xF0 .. 0xFF
|
||||
new Z80OpCode("set 6, b", 0xCB, 0xF0, 0, 8, (d, i) => d.Cpu.Registers.B = d.Cpu.Alu.Set(d.Cpu.Registers.B, 6)),
|
||||
new Z80OpCode("set 6, c", 0xCB, 0xF1, 0, 8, (d, i) => d.Cpu.Registers.C = d.Cpu.Alu.Set(d.Cpu.Registers.C, 6)),
|
||||
new Z80OpCode("set 6, d", 0xCB, 0xF2, 0, 8, (d, i) => d.Cpu.Registers.D = d.Cpu.Alu.Set(d.Cpu.Registers.D, 6)),
|
||||
|
|
|
@ -13,11 +13,19 @@ namespace Emux.GameBoy.Timer
|
|||
private int _timerClock;
|
||||
private TimerControlFlags _tac;
|
||||
private byte _tima;
|
||||
|
||||
private byte _div;
|
||||
private bool _overflowing = false;
|
||||
private int _clocksToReset = 0;
|
||||
|
||||
public byte Div
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get { return _div; }
|
||||
set
|
||||
{
|
||||
_div = value;
|
||||
_timerClock = 0;
|
||||
_divClock = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public byte Tima
|
||||
|
@ -99,10 +107,22 @@ namespace Emux.GameBoy.Timer
|
|||
while (_divClock > DivCycleInterval)
|
||||
{
|
||||
_divClock -= DivCycleInterval;
|
||||
Div = (byte) ((Div + 1) % 0xFF);
|
||||
_div = (byte) ((Div + 1) % 0xFF);
|
||||
}
|
||||
|
||||
if ((Tac & TimerControlFlags.EnableTimer) == TimerControlFlags.EnableTimer)
|
||||
|
||||
if (_overflowing)
|
||||
{
|
||||
_clocksToReset -= cycles;
|
||||
if (_clocksToReset < 0)
|
||||
{
|
||||
_clocksToReset = 0;
|
||||
_overflowing = false;
|
||||
_tima = Tma;
|
||||
_device.Cpu.Registers.IF |= InterruptFlags.Timer;
|
||||
}
|
||||
}
|
||||
|
||||
if ((_tac & TimerControlFlags.EnableTimer) == TimerControlFlags.EnableTimer)
|
||||
{
|
||||
_timerClock += cycles;
|
||||
int timaCycles = GetTimaClockCycles();
|
||||
|
@ -114,8 +134,8 @@ namespace Emux.GameBoy.Timer
|
|||
_tima = (byte) (result & 0xFF);
|
||||
if (result > 0xFF)
|
||||
{
|
||||
_tima = Tma;
|
||||
_device.Cpu.Registers.IF |= InterruptFlags.Timer;
|
||||
_tima = 0;
|
||||
_overflowing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue