From 3bbf300e05846a8ed176586a48e859a9413830c6 Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Sun, 22 Jun 2025 21:07:02 +0100 Subject: [PATCH] Simplify switching processor pin handling --- EightBit/Bus.cs | 21 +- EightBit/Device.cs | 20 +- EightBit/InputOutput.cs | 21 +- EightBit/IntelProcessor.cs | 20 +- EightBit/Processor.cs | 52 +++-- M6502/Core.cs | 100 ++++++++-- Z80/Z80.cs | 388 ++++++++++++++++++++++++++++++------- 7 files changed, 500 insertions(+), 122 deletions(-) diff --git a/EightBit/Bus.cs b/EightBit/Bus.cs index 25c7b16..bca2e04 100644 --- a/EightBit/Bus.cs +++ b/EightBit/Bus.cs @@ -43,9 +43,14 @@ namespace EightBit public byte Read() { this.ReadingByte?.Invoke(this, EventArgs.Empty); - var returned = this.Data = this.Reference(); - ReadByte?.Invoke(this, EventArgs.Empty); - return returned; + try + { + return this.Data = this.Reference(); + } + finally + { + ReadByte?.Invoke(this, EventArgs.Empty); + } } public byte Read(ushort absolute) @@ -68,8 +73,14 @@ namespace EightBit public void Write() { this.WritingByte?.Invoke(this, EventArgs.Empty); - this.Reference() = this.Data; - this.WrittenByte?.Invoke(this, EventArgs.Empty); + try + { + this.Reference() = this.Data; + } + finally + { + this.WrittenByte?.Invoke(this, EventArgs.Empty); + } } public void Write(byte value) diff --git a/EightBit/Device.cs b/EightBit/Device.cs index 0195a91..c390dc2 100644 --- a/EightBit/Device.cs +++ b/EightBit/Device.cs @@ -26,8 +26,14 @@ namespace EightBit if (this.POWER.Lowered()) { RaisingPOWER?.Invoke(this, EventArgs.Empty); - this.POWER.Raise(); - RaisedPOWER?.Invoke(this, EventArgs.Empty); + try + { + this.POWER.Raise(); + } + finally + { + RaisedPOWER?.Invoke(this, EventArgs.Empty); + } } } @@ -36,8 +42,14 @@ namespace EightBit if (this.POWER.Raised()) { LoweringPOWER?.Invoke(this, EventArgs.Empty); - this.POWER.Lower(); - LoweredPOWER?.Invoke(this, EventArgs.Empty); + try + { + this.POWER.Lower(); + } + finally + { + LoweredPOWER?.Invoke(this, EventArgs.Empty); + } } } } diff --git a/EightBit/InputOutput.cs b/EightBit/InputOutput.cs index 2d774be..d19f224 100644 --- a/EightBit/InputOutput.cs +++ b/EightBit/InputOutput.cs @@ -28,9 +28,14 @@ namespace EightBit public byte ReadInputPort(ushort port) { ReadingPort?.Invoke(this, new PortEventArgs(port)); - var value = this._input[port]; - ReadPort?.Invoke(this, new PortEventArgs(port)); - return value; + try + { + return this._input[port]; + } + finally + { + ReadPort?.Invoke(this, new PortEventArgs(port)); + } } public void WriteInputPort(ushort port, byte value) => this._input[port] = value; @@ -40,8 +45,14 @@ namespace EightBit public void WriteOutputPort(ushort port, byte value) { WritingPort?.Invoke(this, new PortEventArgs(port)); - this._output[port] = value; - WrittenPort?.Invoke(this, new PortEventArgs(port)); + try + { + this._output[port] = value; + } + finally + { + WrittenPort?.Invoke(this, new PortEventArgs(port)); + } } } } diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index 2e0499f..7cd84df 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -69,8 +69,14 @@ namespace EightBit if (this.HALT.Lowered()) { RaisingHALT?.Invoke(this, EventArgs.Empty); - this.HALT.Raise(); - RaisedHALT?.Invoke(this, EventArgs.Empty); + try + { + this.HALT.Raise(); + } + finally + { + RaisedHALT?.Invoke(this, EventArgs.Empty); + } } } @@ -79,8 +85,14 @@ namespace EightBit if (this.HALT.Raised()) { LoweringHALT?.Invoke(this, EventArgs.Empty); - this.HALT.Lower(); - LoweredHALT?.Invoke(this, EventArgs.Empty); + try + { + this.HALT.Lower(); + } + finally + { + LoweredHALT?.Invoke(this, EventArgs.Empty); + } } } diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 5a50630..5946cd1 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -69,11 +69,17 @@ namespace EightBit { this.ResetCycles(); ExecutingInstruction?.Invoke(this, EventArgs.Empty); - if (this.Powered) + try { - this.PoweredStep(); + if (this.Powered) + { + this.PoweredStep(); + } + } + finally + { + ExecutedInstruction?.Invoke(this, EventArgs.Empty); } - ExecutedInstruction?.Invoke(this, EventArgs.Empty); return this.Cycles; } @@ -115,8 +121,14 @@ namespace EightBit if (this.RESET.Lowered()) { RaisingRESET?.Invoke(this, EventArgs.Empty); - this.RESET.Raise(); - RaisedRESET?.Invoke(this, EventArgs.Empty); + try + { + this.RESET.Raise(); + } + finally + { + RaisedRESET?.Invoke(this, EventArgs.Empty); + } } } @@ -125,8 +137,14 @@ namespace EightBit if (this.RESET.Raised()) { LoweringRESET?.Invoke(this, EventArgs.Empty); - this.RESET.Lower(); - LoweredRESET?.Invoke(this, EventArgs.Empty); + try + { + this.RESET.Lower(); + } + finally + { + LoweredRESET?.Invoke(this, EventArgs.Empty); + } } } @@ -136,8 +154,14 @@ namespace EightBit if (this.INT.Lowered()) { RaisingINT?.Invoke(this, EventArgs.Empty); - this.INT.Raise(); - RaisedINT?.Invoke(this, EventArgs.Empty); + try + { + this.INT.Raise(); + } + finally + { + RaisedINT?.Invoke(this, EventArgs.Empty); + } } } @@ -146,8 +170,14 @@ namespace EightBit if (this.INT.Raised()) { LoweringINT?.Invoke(this, EventArgs.Empty); - this.INT.Lower(); - LoweredINT?.Invoke(this, EventArgs.Empty); + try + { + this.INT.Lower(); + } + finally + { + LoweredINT?.Invoke(this, EventArgs.Empty); + } } } diff --git a/M6502/Core.cs b/M6502/Core.cs index de52092..6312f3b 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -33,8 +33,14 @@ namespace M6502 if (this.NMI.Lowered()) { RaisingNMI?.Invoke(this, EventArgs.Empty); - this.NMI.Raise(); - RaisedNMI?.Invoke(this, EventArgs.Empty); + try + { + this.NMI.Raise(); + } + finally + { + RaisedNMI?.Invoke(this, EventArgs.Empty); + } } } @@ -43,8 +49,14 @@ namespace M6502 if (this.NMI.Raised()) { LoweringNMI?.Invoke(this, EventArgs.Empty); - this.NMI.Lower(); - LoweredNMI?.Invoke(this, EventArgs.Empty); + try + { + this.NMI.Lower(); + } + finally + { + LoweredNMI?.Invoke(this, EventArgs.Empty); + } } } @@ -65,8 +77,14 @@ namespace M6502 if (this.SO.Lowered()) { RaisingSO?.Invoke(this, EventArgs.Empty); - this.SO.Raise(); - RaisedSO?.Invoke(this, EventArgs.Empty); + try + { + this.SO.Raise(); + } + finally + { + RaisedSO?.Invoke(this, EventArgs.Empty); + } } } @@ -75,8 +93,14 @@ namespace M6502 if (this.SO.Raised()) { LoweringSO?.Invoke(this, EventArgs.Empty); - this.SO.Lower(); - LoweredSO?.Invoke(this, EventArgs.Empty); + try + { + this.SO.Lower(); + } + finally + { + LoweredSO?.Invoke(this, EventArgs.Empty); + } } } @@ -97,8 +121,14 @@ namespace M6502 if (this.SYNC.Lowered()) { RaisingSYNC?.Invoke(this, EventArgs.Empty); - this.SYNC.Raise(); - RaisedSYNC?.Invoke(this, EventArgs.Empty); + try + { + this.SYNC.Raise(); + } + finally + { + RaisedSYNC?.Invoke(this, EventArgs.Empty); + } } } @@ -107,8 +137,14 @@ namespace M6502 if (this.SYNC.Raised()) { LoweringSYNC?.Invoke(this, EventArgs.Empty); - this.SYNC.Lower(); - LoweredSYNC?.Invoke(this, EventArgs.Empty); + try + { + this.SYNC.Lower(); + } + finally + { + LoweredSYNC?.Invoke(this, EventArgs.Empty); + } } } @@ -129,8 +165,14 @@ namespace M6502 if (this.RDY.Lowered()) { RaisingRDY?.Invoke(this, EventArgs.Empty); - this.RDY.Raise(); - RaisedRDY?.Invoke(this, EventArgs.Empty); + try + { + this.RDY.Raise(); + } + finally + { + RaisedRDY?.Invoke(this, EventArgs.Empty); + } } } @@ -139,8 +181,14 @@ namespace M6502 if (this.RDY.Raised()) { LoweringRDY?.Invoke(this, EventArgs.Empty); - this.RDY.Lower(); - LoweredRDY?.Invoke(this, EventArgs.Empty); + try + { + this.RDY.Lower(); + } + finally + { + LoweredRDY?.Invoke(this, EventArgs.Empty); + } } } @@ -161,8 +209,14 @@ namespace M6502 if (this.RW.Lowered()) { RaisingRW?.Invoke(this, EventArgs.Empty); - this.RW.Raise(); - RaisedRW?.Invoke(this, EventArgs.Empty); + try + { + this.RW.Raise(); + } + finally + { + RaisedRW?.Invoke(this, EventArgs.Empty); + } } } @@ -171,8 +225,14 @@ namespace M6502 if (this.RW.Raised()) { LoweringRW?.Invoke(this, EventArgs.Empty); - this.RW.Lower(); - LoweredRW?.Invoke(this, EventArgs.Empty); + try + { + this.RW.Lower(); + } + finally + { + LoweredRW?.Invoke(this, EventArgs.Empty); + } } } diff --git a/Z80/Z80.cs b/Z80/Z80.cs index f4463f2..001f1af 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -205,8 +205,14 @@ namespace Z80 if (this.NMI.Lowered()) { RaisingNMI?.Invoke(this, EventArgs.Empty); - this.NMI.Raise(); - RaisedNMI?.Invoke(this, EventArgs.Empty); + try + { + this.NMI.Raise(); + } + finally + { + RaisedNMI?.Invoke(this, EventArgs.Empty); + } } } @@ -215,8 +221,36 @@ namespace Z80 if (this.NMI.Raised()) { LoweringNMI?.Invoke(this, EventArgs.Empty); - this.NMI.Lower(); - LoweredNMI?.Invoke(this, EventArgs.Empty); + try + { + this.NMI.Lower(); + } + finally + { + LoweredNMI?.Invoke(this, EventArgs.Empty); + } + } + } + + protected sealed class AutoNMI : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoNMI(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerNMI(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseNMI(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -246,8 +280,14 @@ namespace Z80 if (this.M1.Lowered()) { RaisingM1?.Invoke(this, EventArgs.Empty); - this.M1.Raise(); - RaisedM1?.Invoke(this, EventArgs.Empty); + try + { + this.M1.Raise(); + } + finally + { + RaisedM1?.Invoke(this, EventArgs.Empty); + } } } @@ -256,8 +296,35 @@ namespace Z80 if (this.M1.Raised()) { LoweringM1?.Invoke(this, EventArgs.Empty); - this.M1.Lower(); - LoweredM1?.Invoke(this, EventArgs.Empty); + try + { + this.M1.Lower(); + } + finally + { + LoweredM1?.Invoke(this, EventArgs.Empty); + } + } + } + protected sealed class AutoM1 : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoM1(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerM1(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseM1(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -288,9 +355,15 @@ namespace Z80 if (this.RFSH.Lowered()) { RaisingRFSH?.Invoke(this, EventArgs.Empty); - this.RFSH.Raise(); - ++this.REFRESH; - RaisedRFSH?.Invoke(this, EventArgs.Empty); + try + { + this.RFSH.Raise(); + ++this.REFRESH; + } + finally + { + RaisedRFSH?.Invoke(this, EventArgs.Empty); + } } } @@ -299,8 +372,36 @@ namespace Z80 if (this.RFSH.Raised()) { LoweringRFSH?.Invoke(this, EventArgs.Empty); - this.RFSH.Lower(); - LoweredRFSH?.Invoke(this, EventArgs.Empty); + try + { + this.RFSH.Lower(); + } + finally + { + LoweredRFSH?.Invoke(this, EventArgs.Empty); + } + } + } + + protected sealed class AutoRFSH : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoRFSH(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerRFSH(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseRFSH(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -326,8 +427,14 @@ namespace Z80 if (this.MREQ.Lowered()) { RaisingMREQ?.Invoke(this, EventArgs.Empty); - this.MREQ.Raise(); - RaisedMREQ?.Invoke(this, EventArgs.Empty); + try + { + this.MREQ.Raise(); + } + finally + { + RaisedMREQ?.Invoke(this, EventArgs.Empty); + } } } @@ -336,8 +443,36 @@ namespace Z80 if (this.MREQ.Raised()) { LoweringMREQ?.Invoke(this, EventArgs.Empty); - this.MREQ.Lower(); - LoweredMREQ?.Invoke(this, EventArgs.Empty); + try + { + this.MREQ.Lower(); + } + finally + { + LoweredMREQ?.Invoke(this, EventArgs.Empty); + } + } + } + + protected sealed class AutoMREQ : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoMREQ(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerMREQ(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseMREQ(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -363,8 +498,14 @@ namespace Z80 if (this.IORQ.Lowered()) { RaisingIORQ?.Invoke(this, EventArgs.Empty); - this.IORQ.Raise(); - RaisedIORQ?.Invoke(this, EventArgs.Empty); + try + { + this.IORQ.Raise(); + } + finally + { + RaisedIORQ?.Invoke(this, EventArgs.Empty); + } } } @@ -378,6 +519,28 @@ namespace Z80 } } + protected sealed class AutoIORQ : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoIORQ(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerIORQ(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseIORQ(); + _disposed = true; + } + GC.SuppressFinalize(this); + } + } + #endregion #region RD pin @@ -400,8 +563,14 @@ namespace Z80 if (this.RD.Lowered()) { RaisingRD?.Invoke(this, EventArgs.Empty); - this.RD.Raise(); - RaisedRD?.Invoke(this, EventArgs.Empty); + try + { + this.RD.Raise(); + } + finally + { + RaisedRD?.Invoke(this, EventArgs.Empty); + } } } @@ -410,8 +579,36 @@ namespace Z80 if (this.RD.Raised()) { LoweringRD?.Invoke(this, EventArgs.Empty); - this.RD.Lower(); - LoweredRD?.Invoke(this, EventArgs.Empty); + try + { + this.RD.Lower(); + } + finally + { + LoweredRD?.Invoke(this, EventArgs.Empty); + } + } + } + + protected sealed class AutoRD : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoRD(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerRD(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseRD(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -437,8 +634,14 @@ namespace Z80 if (this.WR.Lowered()) { RaisingWR?.Invoke(this, EventArgs.Empty); - this.WR.Raise(); - RaisedWR?.Invoke(this, EventArgs.Empty); + try + { + this.WR.Raise(); + } + finally + { + RaisedWR?.Invoke(this, EventArgs.Empty); + } } } @@ -447,8 +650,36 @@ namespace Z80 if (this.WR.Raised()) { LoweringWR?.Invoke(this, EventArgs.Empty); - this.WR.Lower(); - LoweredWR?.Invoke(this, EventArgs.Empty); + try + { + this.WR.Lower(); + } + finally + { + LoweredWR?.Invoke(this, EventArgs.Empty); + } + } + } + + protected sealed class AutoWR : IDisposable + { + private readonly Z80 _cpu; + private bool _disposed; + + public AutoWR(Z80 cpu) + { + _cpu = cpu; + _cpu.LowerWR(); + } + + public void Dispose() + { + if (!_disposed) + { + _cpu.RaiseWR(); + _disposed = true; + } + GC.SuppressFinalize(this); } } @@ -459,13 +690,17 @@ namespace Z80 protected void MemoryUpdate(int ticks) { this.OnWritingMemory(); - this.LowerMREQ(); - this.LowerWR(); - this.Tick(ticks); - base.MemoryWrite(); - this.RaiseWR(); - this.RaiseMREQ(); - this.OnWroteMemory(); + try + { + using var _ = new AutoMREQ(this); + using var __ = new AutoWR(this); + this.Tick(ticks); + base.MemoryWrite(); + } + finally + { + this.OnWroteMemory(); + } } protected override void MemoryWrite() @@ -476,25 +711,32 @@ namespace Z80 protected override byte MemoryRead() { this.OnReadingMemory(); - this.Tick(); - this.LowerMREQ(); - this.LowerRD(); - this.Tick(); - var returned = base.MemoryRead(); - this.RaiseRD(); - this.RaiseMREQ(); - if (this.M1.Lowered()) + try { - this.Bus.Address.Assign(this.REFRESH, this.IV); - this.LowerRFSH(); this.Tick(); - this.LowerMREQ(); - this.RaiseMREQ(); - this.RaiseRFSH(); + try + { + using var __ = new AutoMREQ(this); + using var _ = new AutoRD(this); + this.Tick(); + return base.MemoryRead(); + } + finally + { + if (this.M1.Lowered()) + { + this.Bus.Address.Assign(this.REFRESH, this.IV); + using var _ = new AutoRFSH(this); + this.Tick(); + using var __ = new AutoMREQ(this); + } + this.Tick(); + } + } + finally + { + this.OnReadMemory(); } - this.Tick(); - this.OnReadMemory(); - return returned; } // From Zilog Z80 manual @@ -516,15 +758,18 @@ namespace Z80 this.Tick(3); } + private byte ReadDataUnderInterrupt() + { + using var _ = new AutoM1(this); + using var __ = new AutoIORQ(this); + return this.Bus.Data; + } + protected override void HandleINT() { base.HandleINT(); - this.LowerM1(); - this.LowerIORQ(); - var data = this.Bus.Data; - this.RaiseIORQ(); - this.RaiseM1(); + var data = this.ReadDataUnderInterrupt(); this.DisableInterrupts(); this.Tick(5); @@ -1560,9 +1805,8 @@ namespace Z80 this.RaiseHALT(); this.IFF2 = this.IFF1; this.IFF1 = false; - this.LowerM1(); + using var __ = new AutoM1(this); _ = this.Bus.Data; - this.RaiseM1(); this.Restart(0x66); } @@ -1582,10 +1826,8 @@ namespace Z80 // instruction so that no other concurrent operation can be performed. protected override byte FetchInstruction() { - this.LowerM1(); - var returned = base.FetchInstruction(); - this.RaiseM1(); - return returned; + using var _ = new AutoM1(this); + return base.FetchInstruction(); } private byte Subtract(byte operand, byte value, int carry = 0) @@ -2321,12 +2563,12 @@ namespace Z80 { this.MEMPTR.Assign(this.Bus.Address); this.Tick(2); - this.LowerIORQ(); - this.LowerWR(); - this.Ports.Write(this.Bus.Address, this.Bus.Data); - this.Tick(); - this.RaiseWR(); - this.RaiseIORQ(); + { + using var _ = new AutoIORQ(this); + using var __ = new AutoWR(this); + this.Ports.Write(this.Bus.Address, this.Bus.Data); + this.Tick(); + } this.Tick(); } @@ -2341,12 +2583,12 @@ namespace Z80 { this.MEMPTR.Assign(this.Bus.Address); this.Tick(2); - this.LowerIORQ(); - this.LowerRD(); - this.Bus.Data = this.Ports.Read(this.Bus.Address); - this.Tick(); - this.RaiseRD(); - this.RaiseIORQ(); + { + using var _ = new AutoIORQ(this); + using var __ = new AutoRD(this); + this.Bus.Data = this.Ports.Read(this.Bus.Address); + this.Tick(); + } this.Tick(); }