Add Z80 processor (untested, but complete)

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon
2019-02-16 21:32:34 +00:00
parent 3108a373d7
commit ea82c58777
11 changed files with 2213 additions and 14 deletions
+18
View File
@@ -51,5 +51,23 @@ namespace EightBit
public static int PromoteNibble(byte value) => LowByte(value << 4);
public static int DemoteNibble(byte value) => HighNibble(value);
public static int CountBits(int value)
{
int count = 0;
while (value != 0)
{
++count;
value &= value - 1;
}
return count;
}
public static int CountBits(byte value) => CountBits((int)value);
public static bool EvenParity(int value) => CountBits(value) % 2 == 0;
public static bool EvenParity(byte value) => EvenParity((int)value);
}
}
+15 -11
View File
@@ -6,23 +6,27 @@ namespace EightBit
{
public class IntelOpCodeDecoded
{
private readonly int x;
private readonly int y;
private readonly int z;
private readonly int p;
private readonly int q;
public IntelOpCodeDecoded()
{
}
public IntelOpCodeDecoded(byte opCode)
{
this.x = (opCode & 0b11000000) >> 6; // 0 - 3
this.y = (opCode & 0b00111000) >> 3; // 0 - 7
this.z = opCode & 0b00000111; // 0 - 7
this.p = (this.y & 0b110) >> 1; // 0 - 3
this.q = this.y & 1; // 0 - 1
this.X = (opCode & 0b11000000) >> 6; // 0 - 3
this.Y = (opCode & 0b00111000) >> 3; // 0 - 7
this.Z = opCode & 0b00000111; // 0 - 7
this.P = (this.Y & 0b110) >> 1; // 0 - 3
this.Q = this.Y & 1; // 0 - 1
}
public int X { get; }
public int Y { get; }
public int Z { get; }
public int P { get; }
public int Q { get; }
}
}
+22
View File
@@ -8,6 +8,9 @@ namespace EightBit
public abstract class IntelProcessor : LittleEndianProcessor
{
private static readonly int[] HalfCarryTableAdd = new int[8] { 0, 0, 1, 0, 1, 0, 1, 1 };
private static readonly int[] HalfCarryTableSub = new int[8] { 0, 1, 1, 1, 0, 0, 0, 1 };
private readonly IntelOpCodeDecoded[] decodedOpCodes = new IntelOpCodeDecoded[0x100];
private Register16 sp = new Register16((ushort)Mask.Mask16);
@@ -86,6 +89,23 @@ namespace EightBit
this.OnLoweredHALT();
}
protected static int BuildHalfCarryIndex(byte before, byte value, int calculation)
{
return ((before & 0x88) >> 1) | ((value & 0x88) >> 2) | ((calculation & 0x88) >> 3);
}
protected static int CalculateHalfCarryAdd(byte before, byte value, int calculation)
{
var index = BuildHalfCarryIndex(before, value, calculation);
return HalfCarryTableAdd[index & (int)Mask.Mask3];
}
protected static int CalculateHalfCarrySub(byte before, byte value, int calculation)
{
var index = BuildHalfCarryIndex(before, value, calculation);
return HalfCarryTableSub[index & (int)Mask.Mask3];
}
protected virtual void OnRaisingHALT() => this.RaisingHALT?.Invoke(this, EventArgs.Empty);
protected virtual void OnRaisedHALT() => this.RaisedHALT?.Invoke(this, EventArgs.Empty);
@@ -192,5 +212,7 @@ namespace EightBit
++this.PC();
this.RaiseHALT();
}
protected IntelOpCodeDecoded GetDecodedOpCode(byte opCode) => this.decodedOpCodes[opCode];
}
}
-2
View File
@@ -4,8 +4,6 @@
namespace EightBit
{
using System;
public enum Mask
{
None = 0,
+1 -1
View File
@@ -76,7 +76,7 @@ namespace EightBit
return false;
}
Register16 rhs = (Register16)obj;
var rhs = (Register16)obj;
return rhs.Word == this.Word;
}