mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-04-20 06:16:43 +00:00
Make Register16 a class, rather than struct. Tricky, but a bit faster than before.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -33,7 +33,7 @@ namespace EightBit
|
||||
protected override Register16 GetWord()
|
||||
{
|
||||
var high = this.BusRead();
|
||||
++this.Bus.Address();
|
||||
++this.Bus.Address.Word;
|
||||
var low = this.BusRead();
|
||||
return new Register16(low, high);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ namespace EightBit
|
||||
protected override void SetWord(Register16 value)
|
||||
{
|
||||
this.BusWrite(value.High);
|
||||
++this.Bus.Address();
|
||||
++this.Bus.Address.Word;
|
||||
this.BusWrite(value.Low);
|
||||
}
|
||||
|
||||
|
||||
+8
-9
@@ -8,7 +8,6 @@ namespace EightBit
|
||||
|
||||
public abstract class Bus : IMapper
|
||||
{
|
||||
private Register16 address;
|
||||
private byte data;
|
||||
|
||||
public event EventHandler<EventArgs> WritingByte;
|
||||
@@ -21,7 +20,7 @@ namespace EightBit
|
||||
|
||||
public byte Data { get => this.data; set => this.data = value; }
|
||||
|
||||
public ref Register16 Address() => ref this.address;
|
||||
public Register16 Address { get; } = new Register16();
|
||||
|
||||
public abstract MemoryMapping Mapping(ushort absolute);
|
||||
|
||||
@@ -51,7 +50,7 @@ namespace EightBit
|
||||
|
||||
public byte Read(ushort absolute)
|
||||
{
|
||||
this.Address().Word = absolute;
|
||||
this.Address.Word = absolute;
|
||||
return this.Read();
|
||||
}
|
||||
|
||||
@@ -59,8 +58,8 @@ namespace EightBit
|
||||
|
||||
public byte Read(byte low, byte high)
|
||||
{
|
||||
this.Address().Low = low;
|
||||
this.Address().High = high;
|
||||
this.Address.Low = low;
|
||||
this.Address.High = high;
|
||||
return this.Read();
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ namespace EightBit
|
||||
|
||||
public void Write(ushort absolute, byte value)
|
||||
{
|
||||
this.Address().Word = absolute;
|
||||
this.Address.Word = absolute;
|
||||
this.Write(value);
|
||||
}
|
||||
|
||||
@@ -87,8 +86,8 @@ namespace EightBit
|
||||
|
||||
public void Write(byte low, byte high, byte value)
|
||||
{
|
||||
this.Address().Low = low;
|
||||
this.Address().High = high;
|
||||
this.Address.Low = low;
|
||||
this.Address.High = high;
|
||||
this.Write(value);
|
||||
}
|
||||
|
||||
@@ -125,7 +124,7 @@ namespace EightBit
|
||||
|
||||
protected ref byte Reference(Register16 absolute) => ref this.Reference(absolute.Word);
|
||||
|
||||
protected ref byte Reference() => ref this.Reference(this.Address());
|
||||
protected ref byte Reference() => ref this.Reference(this.Address);
|
||||
|
||||
protected ref byte Reference(byte low, byte high) => ref this.Reference(new Register16(low, high).Word);
|
||||
|
||||
|
||||
+45
-49
@@ -13,10 +13,6 @@ namespace EightBit
|
||||
|
||||
private readonly IntelOpCodeDecoded[] decodedOpCodes = new IntelOpCodeDecoded[0x100];
|
||||
|
||||
private Register16 sp = new Register16((ushort)Mask.Mask16);
|
||||
|
||||
private Register16 memptr = new Register16((ushort)Mask.Mask16);
|
||||
|
||||
private PinLevel haltLine;
|
||||
|
||||
protected IntelProcessor(Bus bus)
|
||||
@@ -36,36 +32,36 @@ namespace EightBit
|
||||
|
||||
public event EventHandler<EventArgs> LoweredHALT;
|
||||
|
||||
public Register16 SP { get; } = new Register16((ushort)Mask.Mask16);
|
||||
|
||||
public Register16 MEMPTR { get; } = new Register16((ushort)Mask.Mask16);
|
||||
|
||||
public abstract Register16 AF { get; }
|
||||
|
||||
public byte A { get => this.AF.High; set => this.AF.High = value; }
|
||||
|
||||
public byte F { get => this.AF.Low; set => this.AF.Low = value; }
|
||||
|
||||
public abstract Register16 BC { get; }
|
||||
|
||||
public byte B { get => this.BC.High; set => this.BC.High = value; }
|
||||
|
||||
public byte C { get => this.BC.Low; set => this.BC.Low = value; }
|
||||
|
||||
public abstract Register16 DE { get; }
|
||||
|
||||
public byte D { get => this.DE.High; set => this.DE.High = value; }
|
||||
|
||||
public byte E { get => this.DE.Low; set => this.DE.Low = value; }
|
||||
|
||||
public abstract Register16 HL { get; }
|
||||
|
||||
public byte H { get => this.HL.High; set => this.HL.High = value; }
|
||||
|
||||
public byte L { get => this.HL.Low; set => this.HL.Low = value; }
|
||||
|
||||
protected bool Halted => this.HALT().Lowered();
|
||||
|
||||
public ref Register16 SP() => ref this.sp;
|
||||
|
||||
public ref Register16 MEMPTR() => ref this.memptr;
|
||||
|
||||
public abstract ref Register16 AF();
|
||||
|
||||
public ref byte A() => ref this.AF().High;
|
||||
|
||||
public ref byte F() => ref this.AF().Low;
|
||||
|
||||
public abstract ref Register16 BC();
|
||||
|
||||
public ref byte B() => ref this.BC().High;
|
||||
|
||||
public ref byte C() => ref this.BC().Low;
|
||||
|
||||
public abstract ref Register16 DE();
|
||||
|
||||
public ref byte D() => ref this.DE().High;
|
||||
|
||||
public ref byte E() => ref this.DE().Low;
|
||||
|
||||
public abstract ref Register16 HL();
|
||||
|
||||
public ref byte H() => ref this.HL().High;
|
||||
|
||||
public ref byte L() => ref this.HL().Low;
|
||||
|
||||
public ref PinLevel HALT() => ref this.haltLine;
|
||||
|
||||
public IntelOpCodeDecoded GetDecodedOpCode(byte opCode) => this.decodedOpCodes[opCode];
|
||||
@@ -74,7 +70,7 @@ namespace EightBit
|
||||
{
|
||||
base.RaisePOWER();
|
||||
this.RaiseHALT();
|
||||
this.SP().Word = this.AF().Word = this.BC().Word = this.DE().Word = this.HL().Word = (ushort)Mask.Mask16;
|
||||
this.SP.Word = this.AF.Word = this.BC.Word = this.DE.Word = this.HL.Word = (ushort)Mask.Mask16;
|
||||
}
|
||||
|
||||
public virtual void RaiseHALT()
|
||||
@@ -122,38 +118,38 @@ namespace EightBit
|
||||
this.Jump(0);
|
||||
}
|
||||
|
||||
protected sealed override void Push(byte value) => this.Bus.Write(--this.SP(), value);
|
||||
protected sealed override void Push(byte value) => this.Bus.Write(--this.SP.Word, value);
|
||||
|
||||
protected sealed override byte Pop() => this.Bus.Read(this.SP()++);
|
||||
protected sealed override byte Pop() => this.Bus.Read(this.SP.Word++);
|
||||
|
||||
protected sealed override Register16 GetWord()
|
||||
{
|
||||
var returned = base.GetWord();
|
||||
this.MEMPTR().Word = this.Bus.Address().Word;
|
||||
this.MEMPTR.Word = this.Bus.Address.Word;
|
||||
return returned;
|
||||
}
|
||||
|
||||
protected sealed override void SetWord(Register16 value)
|
||||
{
|
||||
base.SetWord(value);
|
||||
this.MEMPTR().Word = this.Bus.Address().Word;
|
||||
this.MEMPTR.Word = this.Bus.Address.Word;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
protected void Restart(byte address)
|
||||
{
|
||||
this.MEMPTR().Low = address;
|
||||
this.MEMPTR().High = 0;
|
||||
this.Call(this.MEMPTR());
|
||||
this.MEMPTR.Low = address;
|
||||
this.MEMPTR.High = 0;
|
||||
this.Call(this.MEMPTR);
|
||||
}
|
||||
|
||||
protected bool CallConditional(bool condition)
|
||||
{
|
||||
this.MEMPTR().Word = this.FetchWord().Word;
|
||||
this.MEMPTR.Word = this.FetchWord().Word;
|
||||
if (condition)
|
||||
{
|
||||
this.Call(this.MEMPTR());
|
||||
this.Call(this.MEMPTR);
|
||||
}
|
||||
|
||||
return condition;
|
||||
@@ -161,10 +157,10 @@ namespace EightBit
|
||||
|
||||
protected bool JumpConditional(bool condition)
|
||||
{
|
||||
this.MEMPTR().Word = this.FetchWord().Word;
|
||||
this.MEMPTR.Word = this.FetchWord().Word;
|
||||
if (condition)
|
||||
{
|
||||
this.Jump(this.MEMPTR());
|
||||
this.Jump(this.MEMPTR);
|
||||
}
|
||||
|
||||
return condition;
|
||||
@@ -182,8 +178,8 @@ namespace EightBit
|
||||
|
||||
protected void JumpRelative(sbyte offset)
|
||||
{
|
||||
this.MEMPTR().Word = (ushort)(this.PC().Word + offset);
|
||||
this.Jump(this.MEMPTR());
|
||||
this.MEMPTR.Word = (ushort)(this.PC.Word + offset);
|
||||
this.Jump(this.MEMPTR);
|
||||
}
|
||||
|
||||
protected bool JumpRelativeConditional(bool condition)
|
||||
@@ -200,18 +196,18 @@ namespace EightBit
|
||||
protected override sealed void Return()
|
||||
{
|
||||
base.Return();
|
||||
this.MEMPTR().Word = this.PC().Word;
|
||||
this.MEMPTR.Word = this.PC.Word;
|
||||
}
|
||||
|
||||
protected void Halt()
|
||||
{
|
||||
--this.PC();
|
||||
--this.PC.Word;
|
||||
this.LowerHALT();
|
||||
}
|
||||
|
||||
protected void Proceed()
|
||||
{
|
||||
++this.PC();
|
||||
++this.PC.Word;
|
||||
this.RaiseHALT();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace EightBit
|
||||
protected override Register16 GetWord()
|
||||
{
|
||||
var low = this.BusRead();
|
||||
++this.Bus.Address();
|
||||
++this.Bus.Address.Word;
|
||||
var high = this.BusRead();
|
||||
return new Register16(low, high);
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace EightBit
|
||||
protected override void SetWord(Register16 value)
|
||||
{
|
||||
this.BusWrite(value.Low);
|
||||
++this.Bus.Address();
|
||||
++this.Bus.Address.Word;
|
||||
this.BusWrite(value.High);
|
||||
}
|
||||
|
||||
|
||||
+13
-14
@@ -10,7 +10,6 @@ namespace EightBit
|
||||
{
|
||||
private PinLevel resetLine;
|
||||
private PinLevel intLine;
|
||||
private Register16 pc;
|
||||
|
||||
protected Processor(Bus memory)
|
||||
{
|
||||
@@ -35,9 +34,9 @@ namespace EightBit
|
||||
|
||||
public Bus Bus { get; }
|
||||
|
||||
protected byte OpCode { get; set; }
|
||||
public Register16 PC { get; } = new Register16();
|
||||
|
||||
public ref Register16 PC() => ref this.pc;
|
||||
protected byte OpCode { get; set; }
|
||||
|
||||
public ref PinLevel RESET() => ref this.resetLine;
|
||||
|
||||
@@ -118,14 +117,14 @@ namespace EightBit
|
||||
|
||||
protected void BusWrite(byte low, byte high, byte data)
|
||||
{
|
||||
this.Bus.Address().Low = low;
|
||||
this.Bus.Address().High = high;
|
||||
this.Bus.Address.Low = low;
|
||||
this.Bus.Address.High = high;
|
||||
this.BusWrite(data);
|
||||
}
|
||||
|
||||
protected void BusWrite(ushort address, byte data)
|
||||
{
|
||||
this.Bus.Address().Word = address;
|
||||
this.Bus.Address.Word = address;
|
||||
this.BusWrite(data);
|
||||
}
|
||||
|
||||
@@ -141,14 +140,14 @@ namespace EightBit
|
||||
|
||||
protected byte BusRead(byte low, byte high)
|
||||
{
|
||||
this.Bus.Address().Low = low;
|
||||
this.Bus.Address().High = high;
|
||||
this.Bus.Address.Low = low;
|
||||
this.Bus.Address.High = high;
|
||||
return this.BusRead();
|
||||
}
|
||||
|
||||
protected byte BusRead(ushort address)
|
||||
{
|
||||
this.Bus.Address().Word = address;
|
||||
this.Bus.Address.Word = address;
|
||||
return this.BusRead();
|
||||
}
|
||||
|
||||
@@ -156,7 +155,7 @@ namespace EightBit
|
||||
|
||||
protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
|
||||
|
||||
protected byte FetchByte() => this.BusRead(this.PC()++);
|
||||
protected byte FetchByte() => this.BusRead(this.PC.Word++);
|
||||
|
||||
protected abstract Register16 GetWord();
|
||||
|
||||
@@ -178,23 +177,23 @@ namespace EightBit
|
||||
|
||||
protected Register16 GetWord(ushort address)
|
||||
{
|
||||
this.Bus.Address().Word = address;
|
||||
this.Bus.Address.Word = address;
|
||||
return this.GetWord();
|
||||
}
|
||||
|
||||
protected void SetWord(ushort address, Register16 value)
|
||||
{
|
||||
this.Bus.Address().Word = address;
|
||||
this.Bus.Address.Word = address;
|
||||
this.SetWord(value);
|
||||
}
|
||||
|
||||
protected void Jump(ushort destination) => this.PC().Word = destination;
|
||||
protected void Jump(ushort destination) => this.PC.Word = destination;
|
||||
|
||||
protected void Jump(Register16 destination) => this.Jump(destination.Word);
|
||||
|
||||
protected void Call(ushort destination)
|
||||
{
|
||||
this.PushWord(this.PC());
|
||||
this.PushWord(this.PC);
|
||||
this.Jump(destination);
|
||||
}
|
||||
|
||||
|
||||
+6
-1
@@ -6,11 +6,16 @@ namespace EightBit
|
||||
{
|
||||
public class Ram : Rom
|
||||
{
|
||||
public Ram(int size = 0)
|
||||
public Ram(int size)
|
||||
: base(size)
|
||||
{
|
||||
}
|
||||
|
||||
public Ram()
|
||||
: this(0)
|
||||
{
|
||||
}
|
||||
|
||||
public override sealed ref byte Reference(ushort address) => ref this.Bytes()[address];
|
||||
|
||||
public new void Poke(ushort address, byte value) => base.Poke(address, value);
|
||||
|
||||
+12
-6
@@ -8,11 +8,8 @@ namespace EightBit
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[DebuggerDisplay("Word = {Word}")]
|
||||
public struct Register16
|
||||
public class Register16
|
||||
{
|
||||
public byte Low;
|
||||
public byte High;
|
||||
|
||||
public Register16(byte low, byte high)
|
||||
{
|
||||
this.Low = low;
|
||||
@@ -25,6 +22,11 @@ namespace EightBit
|
||||
this.High = Chip.HighByte(value);
|
||||
}
|
||||
|
||||
public Register16()
|
||||
: this((ushort)0)
|
||||
{
|
||||
}
|
||||
|
||||
public Register16(int value)
|
||||
: this((ushort)value)
|
||||
{
|
||||
@@ -55,6 +57,10 @@ namespace EightBit
|
||||
}
|
||||
}
|
||||
|
||||
public byte Low { get; set; }
|
||||
|
||||
public byte High { get; set; }
|
||||
|
||||
public static Register16 operator ++(Register16 value) => Increment(value);
|
||||
|
||||
public static Register16 operator --(Register16 value) => Decrement(value);
|
||||
@@ -77,12 +83,12 @@ namespace EightBit
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is Register16))
|
||||
var rhs = obj as Register16;
|
||||
if (rhs == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var rhs = (Register16)obj;
|
||||
return rhs.Low == this.Low && rhs.High == this.High;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user