From 93e09c192f209bbb45d988675d5246bb068fcd21 Mon Sep 17 00:00:00 2001 From: Adrian Conlon <98398945+AdrianConlon@users.noreply.github.com> Date: Sun, 4 May 2025 11:41:28 +0100 Subject: [PATCH] Share instruction fetch and halt implementations --- EightBit/IntelProcessor.cs | 7 +++++++ EightBit/Processor.cs | 5 +++++ Intel8080/Intel8080.cs | 7 +------ LR35902/LR35902.cs | 7 +------ M6502/Core.cs | 8 +++++--- Z80/Z80.cs | 24 +++++++++--------------- 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index c3c2fd0..c130972 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -96,6 +96,13 @@ namespace EightBit } } + protected override byte FetchInstruction() + { + var read = this.FetchByte(); + return this.HALT.Lowered() ? (byte)0 : read; + } + + protected void ResetWorkingRegisters() { this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Sixteen; diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index 9305944..e2cab64 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -92,6 +92,11 @@ namespace EightBit return current; } + protected virtual byte FetchInstruction() + { + return this.FetchByte(); + } + public void Execute(byte value) { this.OpCode = value; diff --git a/Intel8080/Intel8080.cs b/Intel8080/Intel8080.cs index 1113996..c3493b6 100644 --- a/Intel8080/Intel8080.cs +++ b/Intel8080/Intel8080.cs @@ -54,14 +54,9 @@ namespace Intel8080 { this.HandleINT(); } - else if (this.HALT.Lowered()) - { - _ = this.FetchByte(); - this.Execute(0); // NOP - } else { - this.Execute(this.FetchByte()); + this.Execute(this.FetchInstruction()); } } diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index d4969fa..e638fc0 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -224,14 +224,9 @@ namespace LR35902 { this.HandleINT(); } - else if (this.HALT.Lowered()) - { - _ = this.FetchByte(); - this.Execute(0); // NOP - } else { - this.Execute(this.FetchByte()); + this.Execute(this.FetchInstruction()); } } diff --git a/M6502/Core.cs b/M6502/Core.cs index c815ac3..de52092 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -516,7 +516,7 @@ namespace M6502 if (this.RDY.Raised()) { - this.FetchInstruction(); + this.OpCode = this.FetchInstruction(); if (this.RESET.Lowered()) { this.HandleRESET(); @@ -536,17 +536,19 @@ namespace M6502 } } - private void FetchInstruction() + protected override byte FetchInstruction() { 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. this.ImmediateAddress(); - this.OpCode = this.ReadFromBus(); + var returned = this.ReadFromBus(); System.Diagnostics.Debug.Assert(this.Cycles == 1, "BUS read has introduced stray cycles"); this.RaiseSYNC(); + + return returned; } #endregion diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 0384c96..faf9ef3 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -142,7 +142,8 @@ namespace Z80 handled = true; } } - else if (this.HALT.Lowered()) + + if (!handled) { // ** From the Z80 CPU User Manual // When a software HALT instruction is executed, the CPU executes NOPs until an interrupt @@ -158,14 +159,7 @@ namespace Z80 // received from the memory is ignored and an NOP instruction is forced internally to the // CPU.The HALT acknowledge signal is active during this time indicating that the processor // is in the HALT state. - _ = this.FetchInitialOpCode(); - this.Execute(0); // NOP - handled = true; - } - - if (!handled) - { - this.Execute(this.FetchInitialOpCode()); + this.Execute(this.FetchInstruction()); } } @@ -1535,7 +1529,7 @@ namespace Z80 } else { - this.Execute(this.FetchInitialOpCode()); + this.Execute(this.FetchInstruction()); } break; @@ -1585,15 +1579,15 @@ namespace Z80 break; case 1: // DD prefix this._displaced = this._prefixDD = true; - this.Execute(this.FetchInitialOpCode()); + this.Execute(this.FetchInstruction()); break; case 2: // ED prefix this._prefixED = true; - this.Execute(this.FetchInitialOpCode()); + this.Execute(this.FetchInstruction()); break; case 3: // FD prefix this._displaced = this._prefixFD = true; - this.Execute(this.FetchInitialOpCode()); + this.Execute(this.FetchInstruction()); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -1680,10 +1674,10 @@ namespace Z80 // before the RD signal becomes inactive. Clock states T3 and T4 of a fetch cycle are used to // _refresh dynamic memories. The CPU uses this time to decode and execute the fetched // instruction so that no other concurrent operation can be performed. - private byte FetchInitialOpCode() + protected override byte FetchInstruction() { this.LowerM1(); - var returned = this.FetchByte(); + var returned = base.FetchInstruction(); this.RaiseM1(); return returned; }