diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index 3d35306..eea2f0a 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -14,7 +14,6 @@ namespace EightBit public override void PokeWord(ushort address, Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.Bus.Poke(address, value.High); this.Bus.Poke(++address, value.Low); } @@ -51,14 +50,12 @@ namespace EightBit protected override void PushWord(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.Push(value.Low); this.Push(value.High); } protected override void SetWord(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.High); ++this.Bus.Address.Word; this.MemoryWrite(value.Low); @@ -66,7 +63,6 @@ namespace EightBit protected override void SetWordPaged(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.High); ++this.Bus.Address.Low; this.MemoryWrite(value.Low); diff --git a/EightBit/Bus.cs b/EightBit/Bus.cs index 4be197c..fce53e8 100644 --- a/EightBit/Bus.cs +++ b/EightBit/Bus.cs @@ -28,7 +28,6 @@ namespace EightBit public byte Peek(Register16 absolute) { - ArgumentNullException.ThrowIfNull(absolute); return this.Peek(absolute.Word); } @@ -38,7 +37,6 @@ namespace EightBit public void Poke(Register16 absolute, byte value) { - ArgumentNullException.ThrowIfNull(absolute); this.Poke(absolute.Word, value); } @@ -58,7 +56,6 @@ namespace EightBit public byte Read(Register16 absolute) { - ArgumentNullException.ThrowIfNull(absolute); return this.Read(absolute.Low, absolute.High); } @@ -89,7 +86,6 @@ namespace EightBit public void Write(Register16 absolute, byte value) { - ArgumentNullException.ThrowIfNull(absolute); this.Write(absolute.Low, absolute.High, value); } @@ -133,7 +129,6 @@ namespace EightBit protected ref byte Reference(Register16 absolute) { - ArgumentNullException.ThrowIfNull(absolute); return ref this.Reference(absolute.Word); } diff --git a/EightBit/Device.cs b/EightBit/Device.cs index 5b83707..0195a91 100644 --- a/EightBit/Device.cs +++ b/EightBit/Device.cs @@ -25,9 +25,9 @@ namespace EightBit { if (this.POWER.Lowered()) { - this.OnRaisingPOWER(); + RaisingPOWER?.Invoke(this, EventArgs.Empty); this.POWER.Raise(); - this.OnRaisedPOWER(); + RaisedPOWER?.Invoke(this, EventArgs.Empty); } } @@ -35,18 +35,10 @@ namespace EightBit { if (this.POWER.Raised()) { - this.OnLoweringPOWER(); + LoweringPOWER?.Invoke(this, EventArgs.Empty); this.POWER.Lower(); - this.OnLoweredPOWER(); + LoweredPOWER?.Invoke(this, EventArgs.Empty); } } - - protected virtual void OnRaisingPOWER() => RaisingPOWER?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedPOWER() => RaisedPOWER?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweringPOWER() => LoweringPOWER?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredPOWER() => LoweredPOWER?.Invoke(this, EventArgs.Empty); } } diff --git a/EightBit/EightBit.csproj b/EightBit/EightBit.csproj index f325e46..17f7efb 100644 --- a/EightBit/EightBit.csproj +++ b/EightBit/EightBit.csproj @@ -7,7 +7,7 @@ False False True - latest-all + latest-recommended diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index f8b25e4..2bb64ba 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -20,6 +20,7 @@ namespace EightBit { this._decodedOpCodes[i] = new((byte)i); } + this.RaisedPOWER += this.IntelProcessor_RaisedPOWER; } public event EventHandler? RaisingHALT; @@ -67,9 +68,10 @@ namespace EightBit { if (this.HALT.Lowered()) { - this.OnRaisingHALT(); + RaisingHALT?.Invoke(this, EventArgs.Empty); this.HALT.Raise(); - this.OnRaisedHALT(); + ++this.PC.Word; // Release the PC from HALT instruction + RaisedHALT?.Invoke(this, EventArgs.Empty); } } @@ -77,9 +79,10 @@ namespace EightBit { if (this.HALT.Raised()) { - this.OnLoweringHALT(); + LoweringHALT?.Invoke(this, EventArgs.Empty); this.HALT.Lower(); - this.OnLoweredHALT(); + --this.PC.Word; // Keep the PC on the HALT instruction (i.e. executing NOP) + LoweredHALT?.Invoke(this, EventArgs.Empty); } } @@ -102,27 +105,10 @@ namespace EightBit return HalfCarryTableSub[index & (int)Mask.Three]; } - protected override void OnRaisedPOWER() + private void IntelProcessor_RaisedPOWER(object? sender, EventArgs e) { this.PC.Word = this.SP.Word = this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Sixteen; this.RaiseHALT(); - base.OnRaisedPOWER(); - } - - protected virtual void OnRaisingHALT() => RaisingHALT?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedHALT() - { - ++this.PC.Word; // Release the PC from HALT instruction - RaisedHALT?.Invoke(this, EventArgs.Empty); - } - - protected virtual void OnLoweringHALT() => LoweringHALT?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredHALT() - { - --this.PC.Word; // Keep the PC on the HALT instruction (i.e. executing NOP) - LoweredHALT?.Invoke(this, EventArgs.Empty); } protected override void HandleRESET() diff --git a/EightBit/LittleEndianProcessor.cs b/EightBit/LittleEndianProcessor.cs index a598f51..a8dcdb3 100644 --- a/EightBit/LittleEndianProcessor.cs +++ b/EightBit/LittleEndianProcessor.cs @@ -15,7 +15,6 @@ namespace EightBit public override void PokeWord(ushort address, Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.Bus.Poke(address, value.Low); this.Bus.Poke(++address, value.High); } @@ -52,14 +51,12 @@ namespace EightBit protected override void PushWord(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.Push(value.High); this.Push(value.Low); } protected override void SetWord(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.Low); ++this.Bus.Address.Word; this.MemoryWrite(value.High); @@ -67,7 +64,6 @@ namespace EightBit protected override void SetWordPaged(Register16 value) { - ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.Low); ++this.Bus.Address.Low; this.MemoryWrite(value.High); diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index f7697c4..255d93e 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -10,57 +10,9 @@ namespace EightBit public event EventHandler? ExecutingInstruction; public event EventHandler? ExecutedInstruction; - protected virtual void OnExecutedInstruction() => ExecutedInstruction?.Invoke(this, EventArgs.Empty); - protected virtual void OnExecutingInstruction() => ExecutingInstruction?.Invoke(this, EventArgs.Empty); #endregion - #region Bus events - - #region Memory events - - #region Memory read events - - public event EventHandler? ReadingMemory; - public event EventHandler? ReadMemory; - protected virtual void OnReadingMemory() => ReadingMemory?.Invoke(this, EventArgs.Empty); - protected virtual void OnReadMemory() => ReadMemory?.Invoke(this, EventArgs.Empty); - - #endregion - - #region Memory write events - - public event EventHandler? WritingMemory; - public event EventHandler? WrittenMemory; - protected virtual void OnWritingMemory() => WritingMemory?.Invoke(this, EventArgs.Empty); - protected virtual void OnWrittenMemory() => WrittenMemory?.Invoke(this, EventArgs.Empty); - - #endregion - - #endregion - - #region IO events - - #region IO read events - - public event EventHandler? ReadingIO; - public event EventHandler? ReadIO; - protected virtual void OnReadingIO() => ReadingIO?.Invoke(this, EventArgs.Empty); - protected virtual void OnReadIO() => ReadIO?.Invoke(this, EventArgs.Empty); - - #endregion - - #region IO write events - - public event EventHandler? WritingIO; - public event EventHandler? WrittenIO; - protected virtual void OnWritingIO() => WritingIO?.Invoke(this, EventArgs.Empty); - protected virtual void OnWrittenIO() => WrittenIO?.Invoke(this, EventArgs.Empty); - #endregion - - #endregion - - #endregion private PinLevel _resetLine; private PinLevel _intLine; @@ -108,12 +60,12 @@ namespace EightBit public virtual int Step() { this.ResetCycles(); - this.OnExecutingInstruction(); + ExecutingInstruction?.Invoke(this, EventArgs.Empty); if (this.Powered) { this.PoweredStep(); } - this.OnExecutedInstruction(); + ExecutedInstruction?.Invoke(this, EventArgs.Empty); return this.Cycles; } @@ -149,9 +101,9 @@ namespace EightBit { if (this.RESET.Lowered()) { - this.OnRaisingRESET(); + RaisingRESET?.Invoke(this, EventArgs.Empty); this.RESET.Raise(); - this.OnRaisedRESET(); + RaisedRESET?.Invoke(this, EventArgs.Empty); } } @@ -159,9 +111,9 @@ namespace EightBit { if (this.RESET.Raised()) { - this.OnLoweringRESET(); + LoweringRESET?.Invoke(this, EventArgs.Empty); this.RESET.Lower(); - this.OnLoweredRESET(); + LoweredRESET?.Invoke(this, EventArgs.Empty); } } @@ -170,9 +122,9 @@ namespace EightBit { if (this.INT.Lowered()) { - this.OnRaisingINT(); + RaisingINT?.Invoke(this, EventArgs.Empty); this.INT.Raise(); - this.OnRaisedINT(); + RaisedINT?.Invoke(this, EventArgs.Empty); } } @@ -180,9 +132,9 @@ namespace EightBit { if (this.INT.Raised()) { - this.OnLoweringINT(); + LoweringINT?.Invoke(this, EventArgs.Empty); this.INT.Lower(); - this.OnLoweredINT(); + LoweredINT?.Invoke(this, EventArgs.Empty); } } @@ -226,13 +178,11 @@ namespace EightBit protected void MemoryWrite(Register16 address, byte data) { - ArgumentNullException.ThrowIfNull(address); this.MemoryWrite(address.Low, address.High, data); } protected void MemoryWrite(Register16 address) { - ArgumentNullException.ThrowIfNull(address); this.MemoryWrite(address.Low, address.High); } @@ -260,7 +210,6 @@ namespace EightBit protected byte MemoryRead(Register16 address) { - ArgumentNullException.ThrowIfNull(address); return this.MemoryRead(address.Low, address.High); } @@ -286,7 +235,6 @@ namespace EightBit protected Register16 GetWordPaged(Register16 address) { - ArgumentNullException.ThrowIfNull(address); return this.GetWordPaged(address.High, address.Low); } @@ -300,7 +248,6 @@ namespace EightBit protected void SetWordPaged(Register16 address, Register16 value) { - ArgumentNullException.ThrowIfNull(address); this.SetWordPaged(address.High, address.Low, value); } @@ -354,7 +301,6 @@ namespace EightBit protected void Jump(Register16 destination) { - ArgumentNullException.ThrowIfNull(destination); this.PC.Assign(destination); } diff --git a/EightBit/Register16.cs b/EightBit/Register16.cs index 8a7e857..b0e3a7e 100644 --- a/EightBit/Register16.cs +++ b/EightBit/Register16.cs @@ -46,7 +46,6 @@ namespace EightBit public Register16(Register16 rhs) { - ArgumentNullException.ThrowIfNull(rhs); this.Low = rhs.Low; this.High = rhs.High; } @@ -68,7 +67,6 @@ namespace EightBit public static bool operator ==(Register16 left, Register16 right) { - ArgumentNullException.ThrowIfNull(left); return left.Equals(right); } @@ -88,7 +86,6 @@ namespace EightBit public void Assign(Register16 from) { - ArgumentNullException.ThrowIfNull(from); this.Assign(from._low, from._high); } } diff --git a/M6502/Core.cs b/M6502/Core.cs index 9d4b8e6..296ebf3 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -8,8 +8,14 @@ namespace M6502 { using EightBit; - public abstract class Core(Bus bus) : LittleEndianProcessor(bus) + public abstract class Core : LittleEndianProcessor { + protected Core(Bus bus) + : base(bus) + { + this.RaisedPOWER += this.Core_RaisedPOWER; + } + #region Pin controls #region NMI pin @@ -104,16 +110,22 @@ namespace M6502 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] protected virtual void RaiseSYNC() { - this.OnRaisingSYNC(); - this.SYNC.Raise(); - this.OnRaisedSYNC(); + if (this.SYNC.Lowered()) + { + RaisingSYNC?.Invoke(this, EventArgs.Empty); + this.SYNC.Raise(); + RaisedSYNC?.Invoke(this, EventArgs.Empty); + } } protected virtual void LowerSYNC() { - this.OnLoweringSYNC(); - this.SYNC.Lower(); - this.OnLoweredSYNC(); + if (this.SYNC.Raised()) + { + LoweringSYNC?.Invoke(this, EventArgs.Empty); + this.SYNC.Lower(); + LoweredSYNC?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -190,7 +202,7 @@ namespace M6502 #endregion - protected override void OnRaisedPOWER() + private void Core_RaisedPOWER(object? sender, EventArgs e) { this.X = (byte)Bits.Bit7; this.Y = 0; @@ -199,7 +211,6 @@ namespace M6502 this.S = (byte)Mask.Eight; this.LowerSYNC(); this.LowerRW(); - base.OnRaisedPOWER(); } #endregion @@ -551,9 +562,7 @@ namespace M6502 private void FetchInstruction() { - // Instruction fetch beginning this.LowerSYNC(); - System.Diagnostics.Debug.Assert(this.Cycles == 1, "An extra cycle has occurred"); // Can't use fetchByte, since that would add an extra tick. @@ -561,8 +570,6 @@ namespace M6502 this.OpCode = this.ReadFromBus(); System.Diagnostics.Debug.Assert(this.Cycles == 1, "BUS read has introduced stray cycles"); - - // Instruction fetch has now completed this.RaiseSYNC(); } diff --git a/M6502/M6502.HarteTest/Checker.cs b/M6502/M6502.HarteTest/Checker.cs index 620f939..7f05e23 100644 --- a/M6502/M6502.HarteTest/Checker.cs +++ b/M6502/M6502.HarteTest/Checker.cs @@ -282,13 +282,9 @@ } } - private void Runner_ReadByte(object? sender, EventArgs e) => this.AddActualReadCycle(this.Runner.Address, this.Runner.Data); + private void Runner_ReadByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "read"); - private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualWriteCycle(this.Runner.Address, this.Runner.Data); - - private void AddActualReadCycle(EightBit.Register16 address, byte value) => this.AddActualCycle(address, value, "read"); - - private void AddActualWriteCycle(EightBit.Register16 address, byte value) => this.AddActualCycle(address, value, "write"); + private void Runner_WrittenByte(object? sender, EventArgs e) => this.AddActualCycle(this.Runner.Address, this.Runner.Data, "write"); private void AddActualCycle(EightBit.Register16 address, byte value, string action) => this.AddActualCycle(address.Word, value, action); diff --git a/Z80/Z80.FuseTest/TestRunner.cs b/Z80/Z80.FuseTest/TestRunner.cs index ede3664..8477d43 100644 --- a/Z80/Z80.FuseTest/TestRunner.cs +++ b/Z80/Z80.FuseTest/TestRunner.cs @@ -98,21 +98,30 @@ namespace Z80.FuseTest public override void Initialize() { + this.ReadByte += this.Event_ReadByte; + this.WrittenByte += this.Event_WrittenByte; this.ports.ReadPort += this.Ports_ReadPort; this.ports.WrittenPort += this.Ports_WrittenPort; this.cpu.ExecutedInstruction += this.Cpu_ExecutedInstruction; } - protected override void OnReadByte() - { - this.actualEvents.Add(new TestEvent(this.totalCycles + this.cpu.Cycles, "MR", this.Address.Word, this.Data)); - base.OnReadByte(); - } + private void Ports_ReadPort(object? sender, EventArgs e) => this.AddActualEvent("PR"); + private void Ports_WrittenPort(object? sender, EventArgs e) => this.AddActualEvent("PW"); + private void Event_ReadByte(object? sender, EventArgs e) => this.AddActualEvent("MR"); + private void Event_WrittenByte(object? sender, EventArgs e) => this.AddActualEvent("MW"); - protected override void OnWrittenByte() + private void AddActualEvent(string specifier) { - this.actualEvents.Add(new TestEvent(this.totalCycles + this.cpu.Cycles, "MW", this.Address.Word, this.Data)); - base.OnWrittenByte(); + var address = this.Address.Word; + var cycles = this.totalCycles + this.cpu.Cycles; + if (specifier.EndsWith('C')) + { + this.actualEvents.Add(new TestEvent(cycles, specifier, address)); + } + else + { + this.actualEvents.Add(new TestEvent(cycles, specifier, address, this.Data)); + } } private static void DumpDifference(string description, byte expected, byte actual) @@ -121,11 +130,12 @@ namespace Z80.FuseTest Console.Error.WriteLine(output); } - private void Ports_WrittenPort(object? sender, EightBit.PortEventArgs e) => this.actualEvents.Add(new TestEvent(this.totalCycles + this.cpu.Cycles, "PW", this.Address.Word, this.Data)); - - private void Ports_ReadPort(object? sender, EightBit.PortEventArgs e) => this.actualEvents.Add(new TestEvent(this.totalCycles + this.cpu.Cycles, "PR", this.Address.Word, this.Data)); - - private void Cpu_ExecutedInstruction(object? sender, EventArgs e) => this.totalCycles += this.cpu.Cycles; + private void Cpu_ExecutedInstruction(object? sender, EventArgs e) + { + var output = $"**** Cycle count: {this.cpu.Cycles}"; + Console.Out.WriteLine(output); + this.totalCycles += this.cpu.Cycles; + } private static void DumpDifference(string highDescription, string lowDescription, EightBit.Register16 expected, EightBit.Register16 actual) { diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 2afae0f..3c75058 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -5,12 +5,17 @@ namespace Z80 { using EightBit; - using System.Diagnostics; - - public class Z80(Bus bus, InputOutput ports) : IntelProcessor(bus) + public class Z80 : IntelProcessor { - private readonly InputOutput _ports = ports; + public Z80(Bus bus, InputOutput ports) + : base(bus) + { + this._ports = ports; + this.RaisedPOWER += this.Z80_RaisedPOWER; + } + + private readonly InputOutput _ports; private readonly Register16[] _accumulatorFlags = [new Register16(), new Register16()]; private readonly Register16[][] _registers = @@ -161,7 +166,7 @@ namespace Z80 } } - protected override void OnRaisedPOWER() + private void Z80_RaisedPOWER(object? sender, EventArgs e) { this.RaiseM1(); this.RaiseRFSH(); @@ -183,8 +188,6 @@ namespace Z80 base.ResetWorkingRegisters(); this.ResetPrefixes(); - - base.OnRaisedPOWER(); } private void ResetPrefixes() @@ -192,34 +195,7 @@ namespace Z80 this._prefixCB = this._prefixDD = this._prefixED = this._prefixFD = false; } - private static void WithPinChange(Func check, Action enter, Action leave, Action task) - { - if (check()) - { - enter(); - try - { - task(); - } - finally - { - leave(); - } - } - } - - private static byte WithPin(Action enter, Action leave, Func task) - { - enter(); - try - { - return task(); - } - finally - { - leave(); - } - } + #region Z80 specific pins #region NMI pin @@ -235,22 +211,14 @@ namespace Z80 public ref PinLevel NMI => ref this._nmiLine; - protected virtual void OnRaisingNMI() => RaisingNMI?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedNMI() => RaisedNMI?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweringNMI() => LoweringNMI?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredNMI() => LoweredNMI?.Invoke(this, EventArgs.Empty); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseNMI() { if (this.NMI.Lowered()) { - this.OnRaisingNMI(); + RaisingNMI?.Invoke(this, EventArgs.Empty); this.NMI.Raise(); - this.OnRaisedNMI(); + RaisedNMI?.Invoke(this, EventArgs.Empty); } } @@ -258,9 +226,9 @@ namespace Z80 { if (this.NMI.Raised()) { - this.OnLoweringNMI(); + LoweringNMI?.Invoke(this, EventArgs.Empty); this.NMI.Lower(); - this.OnLoweredNMI(); + LoweredNMI?.Invoke(this, EventArgs.Empty); } } @@ -280,14 +248,6 @@ namespace Z80 public ref PinLevel M1 => ref this._m1Line; - protected virtual void OnRaisingM1() => RaisingM1?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedM1() - { - ++this.REFRESH; - RaisedM1?.Invoke(this, EventArgs.Empty); - } - protected virtual void OnLoweringM1() => LoweringM1?.Invoke(this, EventArgs.Empty); protected virtual void OnLoweredM1() => LoweredM1?.Invoke(this, EventArgs.Empty); @@ -295,17 +255,23 @@ namespace Z80 [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseM1() { - WithPinChange(() => this.M1.Lowered(), this.OnRaisingM1, this.OnRaisedM1, () => this.M1.Raise()); + if (this.M1.Lowered()) + { + RaisingM1?.Invoke(this, EventArgs.Empty); + this.M1.Raise(); + ++this.REFRESH; + RaisedM1?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerM1() { - WithPinChange(() => this.M1.Raised(), this.OnLoweringM1, this.OnLoweredM1, () => this.M1.Lower()); - } - - private byte WithM1(Func function) - { - return WithPin(this.LowerM1, this.RaiseM1, function); + if (this.M1.Raised()) + { + LoweringM1?.Invoke(this, EventArgs.Empty); + this.M1.Lower(); + LoweredM1?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -329,28 +295,25 @@ namespace Z80 public ref PinLevel RFSH => ref this._rfshLine; - protected virtual void OnRaisingRFSH() => RaisingRFSH?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedRFSH() => RaisedRFSH?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweringRFSH() => LoweringRFSH?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredRFSH() => LoweredRFSH?.Invoke(this, EventArgs.Empty); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseRFSH() { - WithPinChange(() => this.RFSH.Lowered(), this.OnRaisingRFSH, this.OnRaisedRFSH, () => this.RFSH.Raise()); + if (this.RFSH.Lowered()) + { + RaisingRFSH?.Invoke(this, EventArgs.Empty); + this.RFSH.Raise(); + RaisedRFSH?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerRFSH() { - WithPinChange(() => this.RFSH.Raised(), this.OnLoweringRFSH, this.OnLoweredRFSH, () => this.RFSH.Lower()); - } - - private byte WithRFSH(Func function) - { - return WithPin(this.LowerRFSH, this.RaiseRFSH, function); + if (this.RFSH.Raised()) + { + LoweringRFSH?.Invoke(this, EventArgs.Empty); + this.RFSH.Lower(); + LoweredRFSH?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -369,28 +332,25 @@ namespace Z80 public ref PinLevel MREQ => ref this._mreqLine; - protected virtual void OnLoweringMREQ() => LoweringMREQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredMREQ() => LoweredMREQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisingMREQ() => RaisingMREQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedMREQ() => RaisedMREQ?.Invoke(this, EventArgs.Empty); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseMREQ() { - WithPinChange(() => this.MREQ.Lowered(), this.OnRaisingMREQ, this.OnRaisedMREQ, () => this.MREQ.Raise()); + if (this.MREQ.Lowered()) + { + RaisingMREQ?.Invoke(this, EventArgs.Empty); + this.MREQ.Raise(); + RaisedMREQ?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerMREQ() { - WithPinChange(() => this.MREQ.Raised(), this.OnLoweringMREQ, this.OnLoweredMREQ, () => this.MREQ.Lower()); - } - - private byte WithMREQ(Func function) - { - return WithPin(this.LowerMREQ, this.RaiseMREQ, function); + if (this.MREQ.Raised()) + { + LoweringMREQ?.Invoke(this, EventArgs.Empty); + this.MREQ.Lower(); + LoweredMREQ?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -409,29 +369,25 @@ namespace Z80 public ref PinLevel IORQ => ref this._iorqLine; - protected virtual void OnLoweringIORQ() => LoweringIORQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredIORQ() => LoweredIORQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisingIORQ() => RaisingIORQ?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedIORQ() => RaisedIORQ?.Invoke(this, EventArgs.Empty); - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseIORQ() { - WithPinChange(() => this.IORQ.Lowered(), this.OnRaisingIORQ, this.OnRaisedIORQ, () => this.IORQ.Raise()); + if (this.IORQ.Lowered()) + { + RaisingIORQ?.Invoke(this, EventArgs.Empty); + this.IORQ.Raise(); + RaisedIORQ?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerIORQ() { - WithPinChange(() => this.IORQ.Raised(), this.OnLoweringIORQ, this.OnLoweredIORQ, () => this.IORQ.Lower()); - } - - private byte WithIORQ(Func function) - { - return WithPin(this.LowerIORQ, this.RaiseIORQ, function); + if (this.IORQ.Raised()) + { + LoweringIORQ?.Invoke(this, EventArgs.Empty); + this.IORQ.Lower(); + LoweredIORQ?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -450,28 +406,25 @@ namespace Z80 public ref PinLevel RD => ref this._rdLine; - protected virtual void OnLoweringRD() => LoweringRD?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredRD() => LoweredRD?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisingRD() => RaisingRD?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedRD() => RaisedRD?.Invoke(this, EventArgs.Empty); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseRD() { - WithPinChange(() => this.RD.Lowered(), this.OnRaisingRD, this.OnRaisedRD, () => this.RD.Raise()); + if (this.RD.Lowered()) + { + RaisingRD?.Invoke(this, EventArgs.Empty); + this.RD.Raise(); + RaisedRD?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerRD() { - WithPinChange(() => this.RD.Raised(), this.OnLoweringRD, this.OnLoweredRD, () => this.RD.Lower()); - } - - private byte WithRD(Func function) - { - return WithPin(this.LowerRD, this.RaiseRD, function); + if (this.RD.Raised()) + { + LoweringRD?.Invoke(this, EventArgs.Empty); + this.RD.Lower(); + LoweredRD?.Invoke(this, EventArgs.Empty); + } } #endregion @@ -490,63 +443,50 @@ namespace Z80 public ref PinLevel WR => ref this._wrLine; - protected virtual void OnLoweringWR() => LoweringWR?.Invoke(this, EventArgs.Empty); - - protected virtual void OnLoweredWR() => LoweredWR?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisingWR() => RaisingWR?.Invoke(this, EventArgs.Empty); - - protected virtual void OnRaisedWR() => RaisedWR?.Invoke(this, EventArgs.Empty); - [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1030:Use events where appropriate", Justification = "The word 'raise' is used in an electrical sense")] public virtual void RaiseWR() { - WithPinChange(() => this.WR.Lowered(), this.OnRaisingWR, this.OnRaisedWR, () => this.WR.Raise()); + if (this.WR.Lowered()) + { + RaisingWR?.Invoke(this, EventArgs.Empty); + this.WR.Raise(); + RaisedWR?.Invoke(this, EventArgs.Empty); + } } public virtual void LowerWR() { - WithPinChange(() => this.WR.Raised(), this.OnLoweringWR, this.OnLoweredWR, () => this.WR.Lower()); - } - - private byte WithWR(Func function) - { - this.LowerWR(); - try + if (this.WR.Raised()) { - return function(); - } - finally - { - this.RaiseWR(); + LoweringWR?.Invoke(this, EventArgs.Empty); + this.WR.Lower(); + LoweredWR?.Invoke(this, EventArgs.Empty); } } #endregion + #endregion + protected override void MemoryWrite() { - _ = this.WithMREQ(() => - { - return this.WithWR(() => - { - this.Tick(3); - base.MemoryWrite(); - return 0; - }); - }); + this.LowerMREQ(); + this.LowerWR(); + this.Tick(3); + base.MemoryWrite(); + this.RaiseWR(); + this.RaiseMREQ(); } protected override byte MemoryRead() { - return this.WithMREQ(() => - { - return this.WithRD(() => - { - this.Tick(3); - return base.MemoryRead(); - }); - }); + this.LowerMREQ(); + this.LowerRD(); + this.Tick(3); + var returned = base.MemoryRead(); + this.RaiseRD(); + this.RaiseMREQ(); + return returned; } protected override void HandleRESET() @@ -562,13 +502,11 @@ namespace Z80 { base.HandleINT(); - var data = this.WithM1(() => - { - return this.WithIORQ(() => - { - return this.Bus.Data; - }); - }); + this.LowerM1(); + this.LowerIORQ(); + var data = this.Bus.Data; + this.RaiseIORQ(); + this.RaiseM1(); this.DisableInterrupts(); this.Tick(5); @@ -1723,18 +1661,17 @@ namespace Z80 private byte ReadInitialOpCode() { this.Tick(); - var returned = this.WithM1(() => - { - return this.MemoryRead(this.PC); - }); + + this.LowerM1(); + var returned = this.MemoryRead(this.PC); + this.RaiseM1(); + this.Bus.Address.Assign(this.REFRESH, this.IV); - _ = this.WithRFSH(() => - { - return this.WithMREQ(() => - { - return 0; - }); - }); + this.LowerRFSH(); + this.LowerMREQ(); + this.RaiseMREQ(); + this.RaiseRFSH(); + return returned; }