mirror of
https://github.com/MoleskiCoder/EightBitNet.git
synced 2026-04-19 15:16:41 +00:00
Add Z80 processor (untested, but complete)
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
namespace EightBit
|
||||
{
|
||||
using System;
|
||||
|
||||
public enum Mask
|
||||
{
|
||||
None = 0,
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace EightBit
|
||||
return false;
|
||||
}
|
||||
|
||||
Register16 rhs = (Register16)obj;
|
||||
var rhs = (Register16)obj;
|
||||
return rhs.Word == this.Word;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user