Correct INT handling. Should continually fire until INT is raised.

This commit is contained in:
Adrian Conlon committed 2026-09-19 11:08:06 +01:00
1 parent b3999c4959
commit adca33f189
2 files changed
+16 -16

No files matched your search

+8 -6
View File
@@ -68,19 +68,21 @@ namespace Z80.UnitTests
this.cpu.IFF1 = false;
this.cpu.IM = 1;
this.cpu.LowerINT(); // pending=true, but IFF1=false
this.cpu.Step(); // pending cleared (IFF1=false), EI runs → IFF1=true
this.cpu.LowerINT(); // but IFF1=false
this.cpu.Step(); // IFF1=false, no interrupt, EI runs → IFF1=true
Assert.IsTrue(this.cpu.IFF1, "IFF1 must be true after EI");
Assert.AreEqual(0x0001, this.cpu.PC.Joined, "No interrupt must fire during EI step");
Assert.AreEqual(0x0001, this.cpu.PC.Joined, "Normal execution, no interrupt");
this.cpu.Step(); // NOP at 0x0001 — still no interrupt (pending was cleared)
Assert.AreEqual(0x0002, this.cpu.PC.Joined, "No interrupt must fire on instruction after EI");
this.cpu.Step(); // IFF1 true, INT still low
Assert.AreEqual(0x0038, this.cpu.PC.Joined, "INT fires if INT is low");
// Produce a new falling edge on INT (raise then lower) to retrigger
this.cpu.RaiseINT();
this.cpu.LowerINT();
Assert.IsFalse(this.cpu.IFF1, "IFF1 has been disabled by the INT handler");
this.cpu.Step();
Assert.AreEqual(0x0038, this.cpu.PC.Joined, "INT must fire after new falling edge post-EI");
Assert.AreEqual(0x0038, this.cpu.PC.Joined - 1, "Inside INT handled at 0x38");
}
[TestMethod]
+8 -10
View File
@@ -17,12 +17,8 @@ namespace Z80
this.UpdateRegisterBank();
this.UpdateAFBank();
this.RaisedPOWER += this.Z80_RaisedPOWER;
this.LoweredNMI += this.Z80_LoweredNMI;
this.LoweredINT += this.Z80_LoweredINT;
}
private bool _interruptPending;
private bool _nonMaskableInterruptPending;
private readonly InputOutput _ports;
@@ -185,15 +181,14 @@ namespace Z80
this.HandleRESET();
return;
}
else if (this._nonMaskableInterruptPending)
else if (this._nonMaskableInterruptTriggered)
{
this._nonMaskableInterruptPending = false;
this._nonMaskableInterruptTriggered = false;
this.HandleNMI();
return;
}
else if (this._interruptPending)
else if (this.INT.Lowered())
{
this._interruptPending = false;
if (this.IFF1)
{
this.HandleINT();
@@ -247,14 +242,16 @@ namespace Z80
this.ResetRegisterSet();
}
private void Z80_LoweredINT(object? sender, EventArgs e) => this._interruptPending = true;
//private void Z80_LoweredINT(object? sender, EventArgs e) => this._interruptPending = true;
private void Z80_LoweredNMI(object? sender, EventArgs e) => this._nonMaskableInterruptPending = true;
//private void Z80_LoweredNMI(object? sender, EventArgs e) => this._nonMaskableInterruptPending = true;
#region Z80 specific pins
#region NMI pin
private bool _nonMaskableInterruptTriggered;
public event EventHandler<EventArgs>? RaisingNMI;
public event EventHandler<EventArgs>? RaisedNMI;
@@ -284,6 +281,7 @@ namespace Z80
{
LoweringNMI?.Invoke(this, EventArgs.Empty);
this.NMI.Lower();
this._nonMaskableInterruptTriggered = true;
LoweredNMI?.Invoke(this, EventArgs.Empty);
}
}