mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-10-24 14:05:42 +00:00
Some performance improvements. About 50Mhz for Z80 emulator. 275Mhz to 325Mhz. Interesting.
This commit is contained in:
1 parent
b5f646c641
commit
e0fffdaa5e
9 files changed
+77
-58
No files matched your search
@@ -14,21 +14,21 @@ namespace EightBit
|
||||
|
||||
public override void PokeWord(ushort address, Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.Bus.Poke(address, value.High);
|
||||
this.Bus.Poke(++address, value.Low);
|
||||
}
|
||||
|
||||
protected override void FetchInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.High = this.FetchByte();
|
||||
into.Low = this.FetchByte();
|
||||
}
|
||||
|
||||
protected override void GetInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.High = this.MemoryRead();
|
||||
this.Bus.Address.Increment();
|
||||
into.Low = this.MemoryRead();
|
||||
@@ -36,7 +36,7 @@ namespace EightBit
|
||||
|
||||
protected override void GetPagedInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.High = this.MemoryRead();
|
||||
++this.Bus.Address.Low;
|
||||
into.Low = this.MemoryRead();
|
||||
@@ -44,21 +44,21 @@ namespace EightBit
|
||||
|
||||
protected override void PopInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.High = this.Pop();
|
||||
into.Low = this.Pop();
|
||||
}
|
||||
|
||||
protected override void PushWord(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.Push(value.Low);
|
||||
this.Push(value.High);
|
||||
}
|
||||
|
||||
protected override void SetWord(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.MemoryWrite(value.High);
|
||||
this.Bus.Address.Increment();
|
||||
this.MemoryWrite(value.Low);
|
||||
@@ -66,7 +66,7 @@ namespace EightBit
|
||||
|
||||
protected override void SetPaged(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.MemoryWrite(value.High);
|
||||
++this.Bus.Address.Low;
|
||||
this.MemoryWrite(value.Low);
|
||||
|
||||
@@ -4,58 +4,86 @@
|
||||
|
||||
namespace EightBit
|
||||
{
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
public class Chip : Device
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte Bit(int which) => (byte)(1 << which);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte Bit(byte which) => Bit((int)which);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte SetBit(byte input, byte which) => (byte)(input | which);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte SetBit(byte input, byte which, int condition) => SetBit(input, which, condition != 0);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte SetBit(byte input, byte which, bool condition) => condition ? SetBit(input, which) : ClearBit(input, which);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ClearBit(byte input, byte which) => (byte)(input & (byte)~which);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ClearBit(byte input, byte which, int condition) => ClearBit(input, which, condition != 0);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte ClearBit(byte input, byte which, bool condition) => SetBit(input, which, !condition);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte HighByte(int value) => (byte)(value >> 8);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte HighByte(ushort value) => HighByte((int)value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte LowByte(int value) => (byte)(value & (int)Mask.Eight);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte LowByte(ushort value) => LowByte((int)value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort PromoteByte(byte value) => (ushort)(value << 8);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte DemoteByte(ushort value) => HighByte(value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort HigherPart(ushort value) => (ushort)(value & 0xff00);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static byte LowerPart(ushort value) => LowByte(value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ushort MakeWord(byte low, byte high) => (ushort)(PromoteByte(high) | low);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int HighNibble(byte value) => value >> 4;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int LowNibble(byte value) => value & 0xf;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int HigherNibble(byte value) => value & 0xf0;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int LowerNibble(byte value) => LowNibble(value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int PromoteNibble(byte value) => LowByte(value << 4);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int DemoteNibble(byte value) => HighNibble(value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int CountBits(uint value) => System.Numerics.BitOperations.PopCount(value);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool EvenParity(uint value) => CountBits(value) % 2 == 0;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int FindFirstSet(uint value) => value == 0 ? 0 : System.Numerics.BitOperations.TrailingZeroCount(value) + 1;
|
||||
}
|
||||
}
|
||||
@@ -88,13 +88,12 @@ namespace EightBit
|
||||
|
||||
protected abstract void EnableInterrupts();
|
||||
|
||||
protected override Register16 IncrementPC()
|
||||
protected override void IncrementPC()
|
||||
{
|
||||
if (this.HALT.Raised())
|
||||
{
|
||||
base.IncrementPC();
|
||||
}
|
||||
return this.PC;
|
||||
}
|
||||
|
||||
protected override byte FetchInstruction()
|
||||
@@ -145,7 +144,8 @@ namespace EightBit
|
||||
|
||||
protected sealed override void Push(byte value)
|
||||
{
|
||||
this.MemoryWrite(this.SP.Decrement(), value);
|
||||
this.SP.Decrement();
|
||||
this.MemoryWrite(this.SP, value);
|
||||
}
|
||||
|
||||
protected sealed override byte Pop()
|
||||
|
||||
@@ -15,21 +15,21 @@ namespace EightBit
|
||||
|
||||
public override void PokeWord(ushort address, Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.Bus.Poke(address, value.Low);
|
||||
this.Bus.Poke(++address, value.High);
|
||||
}
|
||||
|
||||
protected override void FetchInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.Low = this.FetchByte();
|
||||
into.High = this.FetchByte();
|
||||
}
|
||||
|
||||
protected override void GetInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.Low = this.MemoryRead();
|
||||
this.Bus.Address.Increment();
|
||||
into.High = this.MemoryRead();
|
||||
@@ -37,7 +37,7 @@ namespace EightBit
|
||||
|
||||
protected override void GetPagedInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.Low = this.MemoryRead();
|
||||
++this.Bus.Address.Low;
|
||||
into.High = this.MemoryRead();
|
||||
@@ -45,21 +45,21 @@ namespace EightBit
|
||||
|
||||
protected override void PopInto(Register16 into)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(into);
|
||||
//ArgumentNullException.ThrowIfNull(into);
|
||||
into.Low = this.Pop();
|
||||
into.High = this.Pop();
|
||||
}
|
||||
|
||||
protected override void PushWord(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.Push(value.High);
|
||||
this.Push(value.Low);
|
||||
}
|
||||
|
||||
protected override void SetWord(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.MemoryWrite(value.Low);
|
||||
this.Bus.Address.Increment();
|
||||
this.MemoryWrite(value.High);
|
||||
@@ -67,7 +67,7 @@ namespace EightBit
|
||||
|
||||
protected override void SetPaged(Register16 value)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(value);
|
||||
//ArgumentNullException.ThrowIfNull(value);
|
||||
this.MemoryWrite(value.Low);
|
||||
++this.Bus.Address.Low;
|
||||
this.MemoryWrite(value.High);
|
||||
|
||||
@@ -201,9 +201,9 @@ namespace EightBit
|
||||
|
||||
protected virtual byte BusRead() => this.Bus.Read(); // N.B. Should be the only real call into the "Bus.Read" code.
|
||||
|
||||
protected virtual Register16 IncrementPC() => this.PC.Increment();
|
||||
protected virtual void IncrementPC() => this.PC.Increment();
|
||||
|
||||
protected virtual Register16 DecrementPC() => this.PC.Decrement();
|
||||
protected virtual void DecrementPC() => this.PC.Decrement();
|
||||
|
||||
protected virtual void ImmediateAddress()
|
||||
{
|
||||
|
||||
+11
-30
@@ -4,13 +4,10 @@
|
||||
|
||||
namespace EightBit
|
||||
{
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 2)]
|
||||
public sealed class Register16
|
||||
{
|
||||
[FieldOffset(0)] private byte _low;
|
||||
[FieldOffset(1)] private byte _high;
|
||||
private byte _low;
|
||||
private byte _high;
|
||||
|
||||
public Register16(byte low, byte high)
|
||||
{
|
||||
@@ -44,26 +41,18 @@ namespace EightBit
|
||||
|
||||
public Register16(Register16 rhs)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(rhs);
|
||||
//ArgumentNullException.ThrowIfNull(rhs);
|
||||
this.Low = rhs.Low;
|
||||
this.High = rhs.High;
|
||||
}
|
||||
|
||||
public unsafe ushort Word
|
||||
public ushort Word
|
||||
{
|
||||
get
|
||||
{
|
||||
fixed (byte* bytes = &this._low)
|
||||
{
|
||||
return *(ushort*)bytes;
|
||||
}
|
||||
}
|
||||
get => Chip.MakeWord(this._low, this._high);
|
||||
set
|
||||
{
|
||||
fixed (byte* bytes = &this._low)
|
||||
{
|
||||
*(ushort*)bytes = value;
|
||||
}
|
||||
this._low = Chip.LowByte(value);
|
||||
this._high = Chip.HighByte(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +62,7 @@ namespace EightBit
|
||||
|
||||
public static bool operator ==(Register16 left, Register16 right)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(left);
|
||||
//ArgumentNullException.ThrowIfNull(left);
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
@@ -93,21 +82,13 @@ namespace EightBit
|
||||
|
||||
public void Assign(Register16 from)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(from);
|
||||
//ArgumentNullException.ThrowIfNull(from);
|
||||
this.Low = from.Low;
|
||||
this.High = from.High;
|
||||
}
|
||||
|
||||
public Register16 Increment()
|
||||
{
|
||||
++this.Word;
|
||||
return this;
|
||||
}
|
||||
public void Increment() => ++this.Word;
|
||||
|
||||
public Register16 Decrement()
|
||||
{
|
||||
--this.Word;
|
||||
return this;
|
||||
}
|
||||
public void Decrement() => --this.Word;
|
||||
}
|
||||
}
|
||||
+10
-5
@@ -380,14 +380,19 @@ namespace Intel8080
|
||||
|
||||
break;
|
||||
case 3: // 16-bit INC/DEC
|
||||
_ = q switch
|
||||
switch(q)
|
||||
{
|
||||
// INC rp
|
||||
0 => this.RP(p).Increment(),
|
||||
case 0:
|
||||
this.RP(p).Increment();
|
||||
break;
|
||||
// DEC rp
|
||||
1 => this.RP(p).Decrement(),
|
||||
_ => throw new NotSupportedException("Invalid operation mode"),
|
||||
};
|
||||
case 1:
|
||||
this.RP(p).Decrement();
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Invalid operation mode");
|
||||
}
|
||||
this.Tick();
|
||||
break;
|
||||
case 4: // 8-bit INC
|
||||
|
||||
+5
-1
@@ -593,7 +593,11 @@ namespace MC6809
|
||||
|
||||
protected override void Push(byte value) => this.PushS(value);
|
||||
|
||||
private void Push(Register16 stack, byte value) => this.MemoryWrite(stack.Decrement(), value);
|
||||
private void Push(Register16 stack, byte value)
|
||||
{
|
||||
stack.Decrement();
|
||||
this.MemoryWrite(stack, value);
|
||||
}
|
||||
|
||||
private void PushS(byte value) => this.Push(this.S, value);
|
||||
|
||||
|
||||
+2
-1
@@ -2004,7 +2004,8 @@ namespace Z80
|
||||
|
||||
private void RepeatBlockInstruction()
|
||||
{
|
||||
this.MEMPTR.Assign(this.DecrementPC());
|
||||
this.DecrementPC();
|
||||
this.MEMPTR.Assign(this.PC);
|
||||
this.DecrementPC();
|
||||
this.AdjustXY(this.PC.High);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user