Performance change: avoid dropping Bus.Data return values

This commit is contained in:
Adrian Conlon committed 2026-05-18 17:28:41 +01:00
1 parent bc39c230d1
commit 741feb4342
14 files changed
+173 -108

No files matched your search

+12 -6
View File
@@ -22,24 +22,30 @@ namespace EightBit
protected override void FetchInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.High = this.FetchByte();
into.Low = this.FetchByte();
this.FetchByte();
into.High = this.Bus.Data;
this.FetchByte();
into.Low = this.Bus.Data;
}
protected override void GetInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.High = this.MemoryRead();
this.MemoryRead();
into.High = this.Bus.Data;
this.Bus.Address.Increment();
into.Low = this.MemoryRead();
this.MemoryRead();
into.Low = this.Bus.Data;
}
protected override void GetPagedInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.High = this.MemoryRead();
this.MemoryRead();
into.High = this.Bus.Data;
++this.Bus.Address.Low;
into.Low = this.MemoryRead();
this.MemoryRead();
into.Low = this.Bus.Data;
}
protected override void PopInto(Register16 into)
+1 -2
View File
@@ -45,7 +45,7 @@ namespace EightBit
this.Poke(absolute.Joined, value);
}
public byte Read()
public void Read()
{
Debug.Assert(!this._writing, "Writing flag is in an invalid state");
Debug.Assert(!this._reading, "Reading flag is in an invalid state");
@@ -56,7 +56,6 @@ namespace EightBit
ReadByte?.Invoke(this, EventArgs.Empty);
Debug.Assert(!this._writing, "Writing flag is in an invalid state");
Debug.Assert(!this._reading, "Reading flag is in an invalid state");
return this.Data;
}
public void Write()
+6 -6
View File
@@ -169,17 +169,17 @@ namespace EightBit
////
protected byte ReadMemoryIndirect(Register16 via)
protected void ReadMemoryIndirect(Register16 via)
{
this.MEMPTR.Assign(via);
return this.ReadMemoryIndirect();
this.ReadMemoryIndirect();
}
protected byte ReadMemoryIndirect()
protected void ReadMemoryIndirect()
{
this.Bus.Address.Assign(this.MEMPTR);
this.MEMPTR.Increment();
return this.MemoryRead();
this.MemoryRead();
}
protected void WriteMemoryIndirect(Register16 via, byte data)
@@ -224,10 +224,10 @@ namespace EightBit
protected virtual void JumpRelativeConditional(bool condition)
{
var offset = this.FetchByte();
this.FetchByte();
if (condition)
{
this.JumpRelative(offset);
this.JumpRelative(this.Bus.Data);
}
}
+12 -6
View File
@@ -23,24 +23,30 @@ namespace EightBit
protected override void FetchInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.Low = this.FetchByte();
into.High = this.FetchByte();
this.FetchByte();
into.Low = this.Bus.Data;
this.FetchByte();
into.High = this.Bus.Data;
}
protected override void GetInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.Low = this.MemoryRead();
this.MemoryRead();
into.Low = this.Bus.Data;
this.Bus.Address.Increment();
into.High = this.MemoryRead();
this.MemoryRead();
into.High = this.Bus.Data;
}
protected override void GetPagedInto(Register16 into)
{
//ArgumentNullException.ThrowIfNull(into);
into.Low = this.MemoryRead();
this.MemoryRead();
into.Low = this.Bus.Data;
++this.Bus.Address.Low;
into.High = this.MemoryRead();
this.MemoryRead();
into.High = this.Bus.Data;
}
protected override void PopInto(Register16 into)
+13 -9
View File
@@ -92,7 +92,11 @@ namespace EightBit
return current;
}
protected virtual byte FetchInstruction() => this.FetchByte();
protected virtual byte FetchInstruction()
{
this.FetchByte();
return this.Bus.Data;
}
public void Execute(byte value)
{
@@ -182,21 +186,21 @@ namespace EightBit
protected virtual void BusWrite() => this.Bus.Write(); // N.B. Should be the only real call into the "Bus.Write" code.
protected byte MemoryRead(byte low, byte high)
protected void MemoryRead(byte low, byte high)
{
this.Bus.Address.Assign(low, high);
return this.MemoryRead();
this.MemoryRead();
}
protected byte MemoryRead(Register16 address)
protected void MemoryRead(Register16 address)
{
this.Bus.Address.Assign(address);
return this.MemoryRead();
this.MemoryRead();
}
protected virtual byte MemoryRead() => this.BusRead();
protected virtual void MemoryRead() => this.BusRead();
protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
protected virtual void BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
protected virtual void IncrementPC() => this.PC.Increment();
@@ -208,10 +212,10 @@ namespace EightBit
this.IncrementPC();
}
protected virtual byte FetchByte()
protected virtual void FetchByte()
{
this.ImmediateAddress();
return this.MemoryRead();
this.MemoryRead();
}
protected abstract void GetInto(Register16 into);
+15 -9
View File
@@ -112,7 +112,7 @@ namespace Intel8080
this.MemoryUpdate();
}
protected override byte MemoryRead()
protected override void MemoryRead()
{
this.OnReadingMemory();
this.Tick(2);
@@ -120,7 +120,6 @@ namespace Intel8080
this.Tick();
this.OnReadMemory();
this.Tick();
return this.Bus.Data;
}
protected override void HandleRESET()
@@ -356,10 +355,12 @@ namespace Intel8080
switch (p)
{
case 0: // LD A,(BC)
this.A = this.ReadMemoryIndirect(this.BC);
this.ReadMemoryIndirect(this.BC);
this.A = this.Bus.Data;
break;
case 1: // LD A,(DE)
this.A = this.ReadMemoryIndirect(this.DE);
this.ReadMemoryIndirect(this.DE);
this.A = this.Bus.Data;
break;
case 2: // LD HL,(nn)
this.FetchShortAddress();
@@ -367,7 +368,8 @@ namespace Intel8080
break;
case 3: // LD A,(nn)
this.FetchInto(this.MEMPTR);
this.A = this.ReadMemoryIndirect();
this.ReadMemoryIndirect();
this.A = this.Bus.Data;
break;
default:
throw new NotSupportedException("Invalid operation mode");
@@ -404,7 +406,8 @@ namespace Intel8080
this.Tick();
break;
case 6: // 8-bit load immediate
this.R(y, this.FetchByte(), 2);// LD r,n
this.FetchByte();// LD r,n
this.R(y, this.Bus.Data, 2);
break;
case 7: // Assorted operations on accumulator/flags
switch (y)
@@ -533,10 +536,12 @@ namespace Intel8080
this.JumpIndirect();
break;
case 2: // OUT (n),A
this.WritePort(this.FetchByte());
this.FetchByte();
this.WritePort(this.Bus.Data);
break;
case 3: // IN A,(n)
this.ReadPort(this.FetchByte());
this.FetchByte();
this.ReadPort(this.Bus.Data);
this.A = this.Bus.Data;
break;
case 4: // EX (SP),HL
@@ -586,7 +591,8 @@ namespace Intel8080
break;
case 6:
{ // Operate on accumulator and immediate operand: alu[y] n
var operand = this.FetchByte();
this.FetchByte();
var operand = this.Bus.Data;
switch (y)
{
case 0: // ADD A,n
+29 -16
View File
@@ -355,7 +355,7 @@ namespace LR35902
this.MemoryUpdate();
}
protected override byte MemoryRead()
protected override void MemoryRead()
{
this.OnReadingMemory();
this.LowerMWR();
@@ -365,7 +365,6 @@ namespace LR35902
this.RaiseRD();
this.RaiseMWR();
this.OnReadMemory();
return this.Bus.Data;
}
protected override void PushShort(Register16 value)
@@ -542,7 +541,8 @@ namespace LR35902
this.TickMachine(2);
break;
case 3: // JR d
this.JumpRelative(this.FetchByte());
this.FetchByte();
this.JumpRelative(this.Bus.Data);
break;
case 4: // JR cc,d
case 5:
@@ -609,20 +609,24 @@ namespace LR35902
switch(p)
{
case 0: // LD A,(BC)
this.A = this.ReadMemoryIndirect(this.BC);
this.ReadMemoryIndirect(this.BC);
this.A = this.Bus.Data;
break;
case 1: // LD A,(DE)
this.A = this.ReadMemoryIndirect(this.DE);
this.ReadMemoryIndirect(this.DE);
this.A = this.Bus.Data;
break;
case 2: // GB: LDI A,(HL)
this.Bus.Address.Assign(this.HL);
this.HL.Increment();
this.A = this.MemoryRead();
this.MemoryRead();
this.A = this.Bus.Data;
break;
case 3: // GB: LDD A,(HL)
this.Bus.Address.Assign(this.HL);
this.HL.Decrement();
this.A = this.MemoryRead();
this.MemoryRead();
this.A = this.Bus.Data;
break;
default:
throw new InvalidOperationException("Invalid operation mode");
@@ -660,7 +664,8 @@ namespace LR35902
break;
case 6: // 8-bit load immediate
this.R(y, this.FetchByte());
this.FetchByte();
this.R(y, this.Bus.Data);
break;
case 7: // Assorted operations on accumulator/flags
@@ -761,13 +766,15 @@ namespace LR35902
break;
case 4: // GB: LD (FF00 + n),A
this.MemoryWrite(this.FetchByte(), IoRegisters.BasePage, this.A);
this.FetchByte();
this.MemoryWrite(this.Bus.Data, IoRegisters.BasePage, this.A);
break;
case 5:
{ // GB: ADD SP,dd
var before = this.SP.Joined;
var value = (sbyte)this.FetchByte();
this.FetchByte();
var value = (sbyte)this.Bus.Data;
this.TickMachine(2);
var result = before + value;
this.SP.Joined = (ushort)result;
@@ -779,13 +786,16 @@ namespace LR35902
break;
case 6: // GB: LD A,(FF00 + n)
this.A = this.MemoryRead(this.FetchByte(), IoRegisters.BasePage);
this.FetchByte();
this.MemoryRead(this.Bus.Data, IoRegisters.BasePage);
this.A = this.Bus.Data;
break;
case 7:
{ // GB: LD HL,SP + dd
var before = this.SP.Joined;
var value = (sbyte)this.FetchByte();
this.FetchByte();
var value = (sbyte)this.Bus.Data;
this.TickMachine();
var result = before + value;
this.HL.Joined = (ushort)result;
@@ -851,11 +861,13 @@ namespace LR35902
this.MemoryWrite(this.MEMPTR, this.A);
break;
case 6: // GB: LD A,(FF00 + C)
this.A = this.MemoryRead(this.C, IoRegisters.BasePage);
this.MemoryRead(this.C, IoRegisters.BasePage);
this.A = this.Bus.Data;
break;
case 7: // GB: LD A,(nn)
this.FetchInto(this.MEMPTR);
this.A = this.MemoryRead(this.MEMPTR);
this.FetchInto(this.MEMPTR);
this.MemoryRead(this.MEMPTR);
this.A = this.Bus.Data;
break;
default:
throw new InvalidOperationException("Invalid operation mode");
@@ -915,7 +927,8 @@ namespace LR35902
case 6:
{ // Operate on accumulator and immediate operand: alu[y] n
var operand = this.FetchByte();
this.FetchByte();
var operand = this.Bus.Data;
switch (y)
{
case 0: // ADD A,n
+18 -12
View File
@@ -560,19 +560,18 @@ namespace M6502
this.OnWrittenMemory();
}
protected sealed override byte BusRead()
protected sealed override void BusRead()
{
this.OnReadingMemory();
this.Tick();
this.ReadFromBus();
this.OnReadMemory();
return this.Bus.Data;
}
private byte ReadFromBus()
private void ReadFromBus()
{
this.RaiseRW();
return base.BusRead();
base.BusRead();
}
private void WriteToBus()
@@ -590,7 +589,8 @@ namespace M6502
protected override byte Pop()
{
this.RaiseStack();
return this.MemoryRead();
this.MemoryRead();
return this.Bus.Data;
}
protected override void Push(byte value)
@@ -633,16 +633,16 @@ namespace M6502
protected abstract void Fixup();
protected byte MaybeFixupRead()
protected void MaybeFixupRead()
{
this.MaybeFixup();
return this.MemoryRead();
this.MemoryRead();
}
protected byte FixupRead()
protected void FixupRead()
{
this.Fixup();
return this.MemoryRead();
this.MemoryRead();
}
#endregion
@@ -667,7 +667,11 @@ namespace M6502
protected void AbsoluteAddress() => this.FetchShortAddress();
protected void ZeroPageAddress() => this.Bus.Address.Assign(this.FetchByte());
protected void ZeroPageAddress()
{
this.FetchByte();
this.Bus.Address.Assign(this.Bus.Data);
}
protected void ZeroPageIndirectAddress()
{
@@ -1087,10 +1091,12 @@ namespace M6502
private void JSR()
{
var low = this.FetchByte();
this.FetchByte();
var low = this.Bus.Data;
this.SwallowPop();
this.PushShort(this.PC);
var high = this.FetchByte();
this.FetchByte();
var high = this.Bus.Data;
this.PC.Assign(low, high);
}
+2 -2
View File
@@ -8,8 +8,8 @@ namespace M6502.HarteTest
{
public static async Task Main(string[] _)
{
var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\6502\v1";
//var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\wdc65c02\v1";
//var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\6502\v1";
var directory = @"C:\github\spectrum\libraries\EightBit\modules\65x02\wdc65c02\v1";
await ProcessTestSuiteAsync(directory).ConfigureAwait(false);
}
+2 -2
View File
@@ -109,7 +109,7 @@ namespace M6502
case 0xb2: this.SwallowRead(); this.JAM(); break; // *JAM
case 0xb3: this.IndirectIndexedY(); this.LAX(); break; // *LAX (indirect indexed Y)
case 0xb7: this.ZeroPageY(); this.LAX(); break; // *LAX (zero page, Y)
case 0xbb: this.AbsoluteYAddress(); this.MaybeFixup(); this.LAS(); break; // *LAS (absolute, Y)
case 0xbb: this.AbsoluteYAddress(); this.MaybeFixupRead(); this.LAS(); break; // *LAS (absolute, Y)
case 0xbf: this.AbsoluteY(); this.LAX(); break; // *LAX (absolute, Y)
case 0xc3: this.IndexedIndirectX(); this.DCP(); break; // *DCP (indexed indirect X)
@@ -289,7 +289,7 @@ namespace M6502
this.SHA();
}
private void LAS() => this.A = this.X = this.S = this.Through(this.MemoryRead() & this.S);
private void LAS() => this.A = this.X = this.S = this.Through(this.Bus.Data & this.S);
private void ANE() => this.A = this.Through((this.A | 0xee) & this.X & this.Bus.Data);
+6 -5
View File
@@ -204,10 +204,10 @@ namespace M6502
private readonly Register16 lastFetchAddress = new();
protected override byte FetchByte()
protected override void FetchByte()
{
this.lastFetchAddress.Assign(this.PC);
return base.FetchByte();
base.FetchByte();
}
protected override void Fixup()
@@ -238,7 +238,8 @@ namespace M6502
this.Bus.Address.High++;
}
this.Bus.Address.Assign(this.Intermediate.Low, this.MemoryRead());
this.MemoryRead();
this.Bus.Address.Assign(this.Intermediate.Low, this.Bus.Data);
}
protected override void IndirectAddress()
@@ -262,10 +263,10 @@ namespace M6502
#region Address and read
private byte ZeroPageIndirect()
private void ZeroPageIndirect()
{
this.ZeroPageIndirectAddress();
return this.MemoryRead();
this.MemoryRead();
}
#endregion
+24 -12
View File
@@ -287,70 +287,80 @@ namespace MC6809
private void OIM_Direct()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.DirectByte();
this.MemoryWrite(this.EA, this.Or(mask));
}
private void OIM_Indexed()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.IndexedByte();
this.MemoryWrite(this.EA, this.Or(mask));
}
private void OIM_Extended()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.ExtendedByte();
this.MemoryWrite(this.EA, this.Or(mask));
}
private void AIM_Direct()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.DirectByte();
this.MemoryWrite(this.EA, this.And(mask));
}
private void AIM_Indexed()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.IndexedByte();
this.MemoryWrite(this.EA, this.And(mask));
}
private void AIM_Extended()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.ExtendedByte();
this.MemoryWrite(this.EA, this.And(mask));
}
private void EIM_Direct()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.DirectByte();
this.MemoryWrite(this.EA, this.ExclusiveOr(mask));
}
private void EIM_Indexed()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.IndexedByte();
this.MemoryWrite(this.EA, this.ExclusiveOr(mask));
}
private void EIM_Extended()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.ExtendedByte();
this.MemoryWrite(this.EA, this.ExclusiveOr(mask));
}
private void TIM_Direct()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.DirectByte();
this.And(mask);
this.SwallowRead(2);
@@ -358,7 +368,8 @@ namespace MC6809
private void TIM_Indexed()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.IndexedByte();
this.And(mask);
this.SwallowRead(2);
@@ -366,7 +377,8 @@ namespace MC6809
private void TIM_Extended()
{
var mask = this.FetchByte();
this.FetchByte();
var mask = this.Bus.Data;
this.ExtendedByte();
this.And(mask);
this.SwallowRead(2);
+8 -7
View File
@@ -580,14 +580,13 @@ namespace MC6809
this.OnWrittenMemory();
}
protected override byte BusRead()
protected override void BusRead()
{
this.OnReadingMemory();
this.Tick();
this.RaiseRW();
base.BusRead();
this.OnReadMemory();
return this.Bus.Data;
}
#endregion
@@ -640,7 +639,8 @@ namespace MC6809
protected void RelativeByteAddress()
{
var offset = (sbyte)this.FetchByte();
this.FetchByte();
var offset = (sbyte)this.Bus.Data;
this.EA.Joined = (ushort)(this.PC.Joined + offset);
}
@@ -653,7 +653,8 @@ namespace MC6809
protected void DirectAddress()
{
this.EA.Assign(this.FetchByte(), this.DP);
this.FetchByte();
this.EA.Assign(this.Bus.Data, this.DP);
this.SwallowRead();
}
@@ -678,7 +679,8 @@ namespace MC6809
protected void IndexedAddress()
{
var type = this.FetchByte();
this.FetchByte();
var type = this.Bus.Data;
var r = this.RR((type & (byte)(Bits.Bit6 | Bits.Bit5)) >> 5);
if ((type & (byte)Bits.Bit7) != 0)
@@ -781,10 +783,9 @@ namespace MC6809
this.MemoryRead(this.EA);
}
protected override byte FetchByte()
protected override void FetchByte()
{
this.ImmediateByte();
return this.Bus.Data;
}
protected void DirectByte()
+25 -14
View File
@@ -508,7 +508,7 @@ namespace Z80
this.RaiseRFSH();
}
protected override byte MemoryRead()
protected override void MemoryRead()
{
this.OnReadingMemory();
this.Tick();
@@ -524,7 +524,6 @@ namespace Z80
}
this.Tick();
this.OnReadMemory();
return this.Bus.Data;
}
// From Zilog Z80 manual
@@ -861,7 +860,8 @@ namespace Z80
{
this.Tick(2);
this.DisplaceAddress();
operand = this.MemoryRead();
this.MemoryRead();
operand = this.Bus.Data;
}
else
{
@@ -1151,7 +1151,8 @@ namespace Z80
this.JumpRelativeConditional(--this.B != 0);
break;
case 3: // JR d
this.JumpRelative(this.FetchByte());
this.FetchByte();
this.JumpRelative(this.Bus.Data);
break;
case 4: // JR cc,d
case 5:
@@ -1208,10 +1209,12 @@ namespace Z80
switch (p)
{
case 0: // LD A,(BC)
this.A = this.ReadMemoryIndirect(this.BC);
this.ReadMemoryIndirect(this.BC);
this.A = this.Bus.Data;
break;
case 1: // LD A,(DE)
this.A = this.ReadMemoryIndirect(this.DE);
this.ReadMemoryIndirect(this.DE);
this.A = this.Bus.Data;
break;
case 2: // LD HL,(nn)
this.FetchShortAddress();
@@ -1220,7 +1223,8 @@ namespace Z80
break;
case 3: // LD A,(nn)
this.FetchInto(this.MEMPTR);
this.A = this.ReadMemoryIndirect();
this.ReadMemoryIndirect();
this.A = this.Bus.Data;
break;
default:
throw new NotSupportedException("Invalid operation mode");
@@ -1399,10 +1403,12 @@ namespace Z80
this.PrefixCB();
break;
case 2: // OUT (n),A
this.WritePort(this.FetchByte());
this.FetchByte();
this.WritePort(this.Bus.Data);
break;
case 3: // IN A,(n)
this.ReadPort(this.FetchByte());
this.FetchByte();
this.ReadPort(this.Bus.Data);
this.A = this.Bus.Data;
break;
case 4: // EX (SP),HL
@@ -1459,7 +1465,8 @@ namespace Z80
break;
case 6:
{ // Operate on accumulator and immediate operand: alu[y] n
var operand = this.FetchByte();
this.FetchByte();
var operand = this.Bus.Data;
switch (y)
{
case 0: // ADD A,n
@@ -1608,7 +1615,8 @@ namespace Z80
if (this._displaced)
{
this.FetchDisplacement();
this.Execute(this.FetchByte());
this.FetchByte();
this.Execute(this.Bus.Data);
}
else
{
@@ -1649,7 +1657,8 @@ namespace Z80
private void FetchDisplacement()
{
Debug.Assert(this.M1.Raised(), "Displacement cannot be fetched during an M1 cycle");
this._displacement = (sbyte)this.FetchByte();
this.FetchByte();
this._displacement = (sbyte)this.Bus.Data;
}
// ** From the Z80 CPU User Manual
@@ -2317,7 +2326,8 @@ namespace Z80
private void RRD()
{
var memory = ReadMemoryIndirect(this.HL);
ReadMemoryIndirect(this.HL);
var memory = this.Bus.Data;
this.Bus.Data = (byte)(PromoteNibble(this.A) | HighNibble(memory));
this.MemoryUpdate(5);
this.A = (byte)(HigherNibble(this.A) | LowerNibble(memory));
@@ -2327,7 +2337,8 @@ namespace Z80
private void RLD()
{
var memory = ReadMemoryIndirect(this.HL);
ReadMemoryIndirect(this.HL);
var memory = this.Bus.Data;
this.Bus.Data = (byte)(PromoteNibble(memory) | LowNibble(this.A));
this.MemoryUpdate(5);
this.A = (byte)(HigherNibble(this.A) | HighNibble(memory));