From 699791f7a4b381b0746930fe1acc7bc577fcabfe Mon Sep 17 00:00:00 2001 From: Adrian Conlon Date: Thu, 16 Apr 2026 13:47:24 +0100 Subject: [PATCH] Simplify intermediate 16-bit register usage --- EightBit/BigEndianProcessor.cs | 10 ++-- EightBit/IntelProcessor.cs | 5 +- EightBit/LittleEndianProcessor.cs | 10 ++-- EightBit/Processor.cs | 46 +++++++++------ Intel8080/Intel8080.cs | 5 +- LR35902/LR35902.cs | 3 +- LR35902/SM83.HarteTest/SM83.HarteTest.csproj | 8 +++ M6502/Core.cs | 5 +- MC6809/MC6809.cs | 60 +++++++++++++++----- Z80/Z80.cs | 15 ++--- 10 files changed, 110 insertions(+), 57 deletions(-) diff --git a/EightBit/BigEndianProcessor.cs b/EightBit/BigEndianProcessor.cs index 242bce3..4cac3d9 100644 --- a/EightBit/BigEndianProcessor.cs +++ b/EightBit/BigEndianProcessor.cs @@ -34,12 +34,12 @@ namespace EightBit into.Low = this.MemoryRead(); } - protected override Register16 GetWordPaged() + protected override void GetPagedInto(Register16 into) { - this.Intermediate.High = this.MemoryRead(); + ArgumentNullException.ThrowIfNull(into); + into.High = this.MemoryRead(); ++this.Bus.Address.Low; - this.Intermediate.Low = this.MemoryRead(); - return this.Intermediate; + into.Low = this.MemoryRead(); } protected override void PopInto(Register16 into) @@ -64,7 +64,7 @@ namespace EightBit this.MemoryWrite(value.Low); } - protected override void SetWordPaged(Register16 value) + protected override void SetPaged(Register16 value) { ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.High); diff --git a/EightBit/IntelProcessor.cs b/EightBit/IntelProcessor.cs index 87f33fd..2c7a494 100644 --- a/EightBit/IntelProcessor.cs +++ b/EightBit/IntelProcessor.cs @@ -155,11 +155,10 @@ namespace EightBit return this.Bus.Data; } - protected sealed override Register16 GetWord() + protected sealed override void GetWord() { - _ = base.GetWord(); + base.GetWord(); this.MEMPTR.Assign(this.Bus.Address); - return this.Intermediate; } protected sealed override void SetWord(Register16 value) diff --git a/EightBit/LittleEndianProcessor.cs b/EightBit/LittleEndianProcessor.cs index f809417..37cf9e7 100644 --- a/EightBit/LittleEndianProcessor.cs +++ b/EightBit/LittleEndianProcessor.cs @@ -35,12 +35,12 @@ namespace EightBit into.High = this.MemoryRead(); } - protected override Register16 GetWordPaged() + protected override void GetPagedInto(Register16 into) { - this.Intermediate.Low = this.MemoryRead(); + ArgumentNullException.ThrowIfNull(into); + into.Low = this.MemoryRead(); ++this.Bus.Address.Low; - this.Intermediate.High = this.MemoryRead(); - return this.Intermediate; + into.High = this.MemoryRead(); } protected override void PopInto(Register16 into) @@ -65,7 +65,7 @@ namespace EightBit this.MemoryWrite(value.High); } - protected override void SetWordPaged(Register16 value) + protected override void SetPaged(Register16 value) { ArgumentNullException.ThrowIfNull(value); this.MemoryWrite(value.Low); diff --git a/EightBit/Processor.cs b/EightBit/Processor.cs index e12a384..c68c114 100644 --- a/EightBit/Processor.cs +++ b/EightBit/Processor.cs @@ -219,45 +219,59 @@ namespace EightBit protected abstract void GetInto(Register16 into); - protected virtual Register16 GetWord() + protected virtual void GetWord() { this.GetInto(this.Intermediate); - return this.Intermediate; } protected abstract void SetWord(Register16 value); - protected abstract Register16 GetWordPaged(); + protected abstract void GetPagedInto(Register16 into); - protected Register16 GetWordPaged(byte page, byte offset) + protected virtual void GetWordPaged() { - this.Bus.Address.Assign(offset, page); - return this.GetWordPaged(); + this.GetPagedInto(this.Intermediate); } - protected abstract void SetWordPaged(Register16 value); + protected void GetWordPaged(byte page, byte offset) + { + this.Bus.Address.Assign(offset, page); + this.GetWordPaged(); + } - protected void SetWordPaged(Register16 address, Register16 value) + protected void GetPagedInto(byte page, byte offset, Register16 into) + { + ArgumentNullException.ThrowIfNull(into); + this.Bus.Address.Assign(offset, page); + this.GetPagedInto(into); + } + + protected abstract void SetPaged(Register16 value); + + protected void SetPaged(Register16 address, Register16 value) { this.Bus.Address.Assign(address); - this.SetWordPaged(value); + this.SetPaged(value); } - protected void SetWordPaged(byte page, byte offset, Register16 value) + protected void SetPaged(byte page, byte offset, Register16 value) { this.Bus.Address.Assign(offset, page); - this.SetWordPaged(value); + this.SetPaged(value); } protected abstract void FetchInto(Register16 into); - protected Register16 FetchWord() + protected void FetchWord() { this.FetchInto(this.Intermediate); - return this.Intermediate; } - protected void FetchWordAddress() => this.Bus.Address.Assign(this.FetchWord()); + protected void FetchWordAddress() + { + this.FetchWord(); + this.Bus.Address.Assign(this.Intermediate); + } protected abstract void Push(byte value); @@ -267,10 +281,10 @@ namespace EightBit protected abstract void PopInto(Register16 into); - protected Register16 GetWord(Register16 address) + protected void GetWord(Register16 address) { this.Bus.Address.Assign(address); - return this.GetWord(); + this.GetWord(); } protected void SetWord(Register16 address, Register16 value) diff --git a/Intel8080/Intel8080.cs b/Intel8080/Intel8080.cs index cb89fc8..ebb8520 100644 --- a/Intel8080/Intel8080.cs +++ b/Intel8080/Intel8080.cs @@ -787,9 +787,8 @@ namespace Intel8080 private void XHTL(Register16 exchange) { - this.MEMPTR.Low = this.MemoryRead(this.SP); - this.Bus.Address.Increment(); - this.MEMPTR.High = this.MemoryRead(); + this.Bus.Address.Assign(this.SP); + this.GetInto(this.MEMPTR); this.Bus.Data = exchange.High; exchange.High = this.MEMPTR.High; this.MemoryUpdate(2); diff --git a/LR35902/LR35902.cs b/LR35902/LR35902.cs index 2fa8aca..8448018 100644 --- a/LR35902/LR35902.cs +++ b/LR35902/LR35902.cs @@ -533,7 +533,8 @@ namespace LR35902 case 0: // NOP break; case 1: // GB: LD (nn),SP - this.Bus.Address.Assign(this.FetchWord()); + this.FetchWord(); + this.Bus.Address.Assign(this.Intermediate); this.SetWord(this.SP); break; case 2: // GB: STOP diff --git a/LR35902/SM83.HarteTest/SM83.HarteTest.csproj b/LR35902/SM83.HarteTest/SM83.HarteTest.csproj index 853d528..3c013e2 100644 --- a/LR35902/SM83.HarteTest/SM83.HarteTest.csproj +++ b/LR35902/SM83.HarteTest/SM83.HarteTest.csproj @@ -9,6 +9,14 @@ latest-all + + 9999 + + + + 9999 + + diff --git a/M6502/Core.cs b/M6502/Core.cs index b05be1a..b4a3019 100644 --- a/M6502/Core.cs +++ b/M6502/Core.cs @@ -215,7 +215,8 @@ namespace M6502 this.Push((byte)(this.P | (source == InterruptSource.hardware ? 0 : (byte)StatusBits.BF))); } this.SetFlag(StatusBits.IF); // Disable IRQ - this.Jump(this.GetWordPaged(0xff, vector)); + this.GetWordPaged(0xff, vector); + this.Jump(this.Intermediate); } #region Interrupt etc. handlers @@ -659,7 +660,7 @@ namespace M6502 protected void GetAddressPaged() { - _ = this.GetWordPaged(); + this.GetWordPaged(); this.Bus.Address.Assign(this.Intermediate); } diff --git a/MC6809/MC6809.cs b/MC6809/MC6809.cs index e75b370..fd237de 100644 --- a/MC6809/MC6809.cs +++ b/MC6809/MC6809.cs @@ -495,7 +495,8 @@ namespace MC6809 this.DP = 0; this.CC = SetBit(this.CC, StatusBits.IF); // Disable IRQ this.CC = SetBit(this.CC, StatusBits.FF); // Disable FIRQ - this.Jump(this.GetWordPaged(0xff, RESET_vector)); + this.GetWordPaged(0xff, RESET_vector); + this.Jump(this.Intermediate); this.Tick(10); } @@ -506,7 +507,8 @@ namespace MC6809 this.RaiseBS(); this.SaveEntireRegisterState(); this.CC = SetBit(this.CC, StatusBits.IF); // Disable IRQ - this.Jump(this.GetWordPaged(0xff, IRQ_vector)); + this.GetWordPaged(0xff, IRQ_vector); + this.Jump(this.Intermediate); this.Tick(12); } @@ -524,7 +526,8 @@ namespace MC6809 this.SaveEntireRegisterState(); this.CC = SetBit(this.CC, StatusBits.IF); // Disable IRQ this.CC = SetBit(this.CC, StatusBits.FF); // Disable FIRQ - this.Jump(this.GetWordPaged(0xff, NMI_vector)); + this.GetWordPaged(0xff, NMI_vector); + this.Jump(this.Intermediate); this.Tick(12); } @@ -536,7 +539,8 @@ namespace MC6809 this.SavePartialRegisterState(); this.CC = SetBit(this.CC, StatusBits.IF); // Disable IRQ this.CC = SetBit(this.CC, StatusBits.FF); // Disable FIRQ - this.Jump(this.GetWordPaged(0xff, FIRQ_vector)); + this.GetWordPaged(0xff, FIRQ_vector); + this.Jump(this.Intermediate); this.Tick(12); } @@ -610,7 +614,8 @@ namespace MC6809 private Register16 Address_relative_word() { - var offset = (short)this.FetchWord().Word; + this.FetchWord(); + var offset = (short)this.Intermediate.Word; this.Intermediate.Word = (ushort)(this.PC.Word + offset); return this.Intermediate; } @@ -622,7 +627,11 @@ namespace MC6809 return this.Intermediate; } - private Register16 Address_extended() => this.FetchWord(); + private Register16 Address_extended() + { + this.FetchWord(); + return this.Intermediate; + } private Register16 RR(int which) { @@ -682,7 +691,8 @@ namespace MC6809 break; case 0b1001: // n,R (sixteen-bit) this.Tick(4); - this.Intermediate.Word = (ushort)(r.Word + (short)this.FetchWord().Word); + this.FetchWord(); + this.Intermediate.Word += r.Word; break; case 0b1011: // D,R this.Tick(4); @@ -708,7 +718,8 @@ namespace MC6809 if (indirect != 0) { this.Tick(3); - this.Intermediate.Word = this.GetWord(this.Intermediate).Word; + var address = this.Intermediate; + this.GetWord(address); } } else @@ -745,13 +756,29 @@ namespace MC6809 return this.Bus.Data; } - private Register16 AM_immediate_word() => this.FetchWord(); + private Register16 AM_immediate_word() + { + this.FetchWord(); + return this.Intermediate; + } - private Register16 AM_direct_word() => this.GetWord(this.Address_direct()); + private Register16 AM_direct_word() + { + this.GetWord(this.Address_direct()); + return this.Intermediate; + } - private Register16 AM_indexed_word() => this.GetWord(this.Address_indexed()); + private Register16 AM_indexed_word() + { + this.GetWord(this.Address_indexed()); + return this.Intermediate; + } - private Register16 AM_extended_word() => this.GetWord(this.Address_extended()); + private Register16 AM_extended_word() + { + this.GetWord(this.Address_extended()); + return this.Intermediate; + } #endregion @@ -1746,19 +1773,22 @@ namespace MC6809 this.SaveEntireRegisterState(); this.CC = SetBit(this.CC, StatusBits.IF); // Disable IRQ this.CC = SetBit(this.CC, StatusBits.FF); // Disable FIRQ - this.Jump(this.GetWordPaged(0xff, SWI_vector)); + this.GetWordPaged(0xff, SWI_vector); + this.Jump(this.Intermediate); } private void SWI2() { this.SaveEntireRegisterState(); - this.Jump(this.GetWordPaged(0xff, SWI2_vector)); + this.GetWordPaged(0xff, SWI2_vector); + this.Jump(this.Intermediate); } private void SWI3() { this.SaveEntireRegisterState(); - this.Jump(this.GetWordPaged(0xff, SWI3_vector)); + this.GetWordPaged(0xff, SWI3_vector); + this.Jump(this.Intermediate); } private void TST(byte data) => this.CMP(data, 0); diff --git a/Z80/Z80.cs b/Z80/Z80.cs index 241e8df..689a968 100644 --- a/Z80/Z80.cs +++ b/Z80/Z80.cs @@ -580,8 +580,8 @@ namespace Z80 break; case 2: this.Tick(); - this.MEMPTR.Assign(this.GetWordPaged(data, this.IV)); - this.Call(this.MEMPTR); + this.GetPagedInto(data, this.IV, this.MEMPTR); + base.Call(); Debug.Assert(this.Cycles == 19); break; default: @@ -963,7 +963,8 @@ namespace Z80 this.SetWord(this.RP(p)); break; case 1: // LD rp[p], (nn) - this.RP(p).Assign(this.GetWord()); + this.GetWord(); + this.RP(p).Assign(this.Intermediate); break; default: throw new NotSupportedException("Invalid operation mode"); @@ -1215,7 +1216,8 @@ namespace Z80 break; case 2: // LD HL,(nn) this.FetchWordAddress(); - this.HL2().Assign(this.GetWord()); + this.GetWord(); + this.HL2().Assign(this.Intermediate); break; case 3: // LD A,(nn) this.FetchInto(this.MEMPTR); @@ -1940,9 +1942,8 @@ namespace Z80 private void XHTL(Register16 exchange) { - this.MEMPTR.Low = this.MemoryRead(this.SP); - this.Bus.Address.Increment(); - this.MEMPTR.High = this.MemoryRead(); + this.Bus.Address.Assign(this.SP); + this.GetInto(this.MEMPTR); this.Bus.Data = exchange.High; exchange.High = this.MEMPTR.High; this.MemoryUpdate(2);