More ops.

master
Nabile Rahmani 2018-01-24 03:06:39 +01:00
parent 1800179515
commit 6caa80fb9a
9 changed files with 114 additions and 6 deletions

View File

@ -0,0 +1,14 @@
namespace DotN64.CPU
{
public partial class VR4300
{
public partial class SystemControlUnit
{
public enum FunctOpCode : byte
{
/// <summary>Write Indexed TLB Entry.</summary>
TLBWI = 0b000010
}
}
}
}

View File

@ -9,7 +9,9 @@
/// <summary>Move To System Control Coprocessor.</summary>
MT = 0b00100,
/// <summary>Move From System Control Coprocessor.</summary>
MF = 0b00000
MF = 0b00000,
/// <summary>Coprocessor function.</summary>
CO = 0b10000 // TODO: Instruction set details show that this is only a single bit. Other bits could be overwritten by COP instruction structures.
}
}
}

View File

@ -10,6 +10,7 @@ namespace DotN64.CPU
#region Fields
private readonly VR4300 cpu;
private readonly IReadOnlyDictionary<OpCode, Action<Instruction>> operations;
private readonly IReadOnlyDictionary<FunctOpCode, Action<Instruction>> functOperations;
#endregion
#region Properties
@ -32,7 +33,18 @@ namespace DotN64.CPU
operations = new Dictionary<OpCode, Action<Instruction>>
{
[OpCode.MT] = i => Registers[i.RD] = cpu.GPR[i.RT],
[OpCode.MF] = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD]
[OpCode.MF] = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD],
[OpCode.CO] = i =>
{
if (functOperations.TryGetValue((FunctOpCode)i.Funct, out var operation))
operation(i);
else if (i.Funct == 0b010000)
ExceptionProcessing.ReservedInstruction(cpu, i);
}
};
functOperations = new Dictionary<FunctOpCode, Action<Instruction>>
{
[FunctOpCode.TLBWI] = i => { /* TODO. */ }
};
}
#endregion

View File

@ -45,7 +45,17 @@
/// <summary>Store Byte.</summary>
SB = 0b101000,
/// <summary>Load Byte Unsigned.</summary>
LBU = 0b100100
LBU = 0b100100,
/// <summary>Branch On Less Than Or Equal To Zero.</summary>
BLEZ = 0b000110,
/// <summary>Load Doubleword.</summary>
LD = 0b110111,
/// <summary>Set On Less Than Immediate Unsigned.</summary>
SLTIU = 0b001011,
/// <summary>Store Halfword.</summary>
SH = 0b101001,
/// <summary>Load Halfword Unsigned.</summary>
LHU = 0b100101
}
}
}

View File

@ -35,7 +35,17 @@
/// <summary>And.</summary>
AND = 0b100100,
/// <summary>Set On Less Than.</summary>
SLT = 0b101010
SLT = 0b101010,
/// <summary>Doubleword Multiply Unsigned.</summary>
DMULTU = 0b011101,
/// <summary>Doubleword Shift Left Logical + 32.</summary>
DSLL32 = 0b111100,
/// <summary>Doubleword Shift Right Arithmetic + 32.</summary>
DSRA32 = 0b111111,
/// <summary>Doubleword Divide Unsigned.</summary>
DDIVU = 0b011111,
/// <summary>Shift Right Arithmetic.</summary>
SRA = 0b000011
}
}
}

View File

@ -162,6 +162,20 @@ namespace DotN64.CPU
},
[Instruction.FromOpCode(OpCode.LBU)] = i => GPR[i.RT] = (byte)ReadWord((ulong)(short)i.Immediate + GPR[i.RS]),
[Instruction.FromOpCode(OpCode.COP3)] = i => ExceptionProcessing.ReservedInstruction(this, i), // CP3 access throws a reserved instruction for this CPU.
[Instruction.FromOpCode(OpCode.BLEZ)] = i => Branch(i, (rs, rt) => rs <= 0),
[Instruction.FromOpCode(OpCode.LD)] = i =>
{
var address = (ulong)(short)i.Immediate + GPR[i.RS];
GPR[i.RT] = ReadWord(address) << 32 | ReadWord(address + sizeof(uint));
},
[Instruction.FromOpCode(OpCode.SLTIU)] = i => GPR[i.RT] = GPR[i.RS] < (ulong)(short)i.Immediate ? (ulong)1 : 0,
[Instruction.FromOpCode(OpCode.SH)] = i =>
{
var address = (ulong)(short)i.Immediate + GPR[i.RS];
WriteWord(address, (ReadWord(address) & ~((uint)(1 << 16) - 1)) | (ushort)GPR[i.RT]);
},
[Instruction.FromOpCode(OpCode.LHU)] = i => GPR[i.RT] = (ushort)ReadWord((ulong)(short)i.Immediate + GPR[i.RS]),
[Instruction.FromOpCode(SpecialOpCode.ADD)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RS] + (int)GPR[i.RT]),
[Instruction.FromOpCode(SpecialOpCode.JR)] = i =>
{
@ -187,6 +201,27 @@ namespace DotN64.CPU
[Instruction.FromOpCode(SpecialOpCode.SRLV)] = i => GPR[i.RD] = (ulong)(int)((uint)GPR[i.RT] >> (int)(GPR[i.RS] & ((1 << 5) - 1))),
[Instruction.FromOpCode(SpecialOpCode.AND)] = i => GPR[i.RD] = GPR[i.RS] & GPR[i.RT],
[Instruction.FromOpCode(SpecialOpCode.SLT)] = i => GPR[i.RD] = GPR[i.RS] < GPR[i.RT] ? (ulong)1 : 0,
[Instruction.FromOpCode(SpecialOpCode.DMULTU)] = i =>
{
ulong rsHi = (uint)(GPR[i.RS] >> 32), rtHi = (uint)(GPR[i.RT] >> 32);
ulong rsLo = (uint)GPR[i.RS], rtLo = (uint)GPR[i.RT];
ulong midProducts = rsHi * rtLo + rsLo * rtHi, loProduct = rsLo * rtLo, hiProduct = rsHi * rtHi;
LO = (uint)loProduct + (midProducts << 32);
HI = hiProduct + (midProducts >> 32);
},
[Instruction.FromOpCode(SpecialOpCode.DSLL32)] = i => GPR[i.RD] = GPR[i.RT] << (i.SA + 32),
[Instruction.FromOpCode(SpecialOpCode.DSRA32)] = i => GPR[i.RD] = (ulong)((long)GPR[i.RT] >> (i.SA + 32)),
[Instruction.FromOpCode(SpecialOpCode.DDIVU)] = i =>
{
ulong rs = GPR[i.RS], rt = GPR[i.RT];
if (rt == 0)
return;
LO = rs / rt;
HI = rs % rt;
},
[Instruction.FromOpCode(SpecialOpCode.SRA)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RT] >> i.SA),
[Instruction.FromOpCode(RegImmOpCode.BGEZAL)] = i => Branch(i, (rs, rt) => rs >= 0, true),
[Instruction.FromOpCode(RegImmOpCode.BGEZL)] = i => BranchLikely(i, (rs, rt) => rs >= 0)
};

View File

@ -31,7 +31,15 @@
switch (instruction.OP)
{
case VR4300.OpCode.COP0:
opCode = ((VR4300.SystemControlUnit.OpCode)instruction.RS).ToString(); // Not accounting for RT, Func...
switch ((VR4300.SystemControlUnit.OpCode)instruction.RS)
{
case VR4300.SystemControlUnit.OpCode.CO:
opCode = ((VR4300.SystemControlUnit.FunctOpCode)instruction.Funct).ToString();
break;
default:
opCode = ((VR4300.SystemControlUnit.OpCode)instruction.RS).ToString();
break;
}
break;
case VR4300.OpCode.COP1:
opCode = ((VR4300.FloatingPointUnit.OpCode)instruction.RS).ToString();
@ -70,6 +78,7 @@
case VR4300.OpCode.BNEL:
return Format(instruction, FormatRegister(instruction.RS, cpu), FormatRegister(instruction.RT, cpu), (short)instruction.Immediate);
case VR4300.OpCode.BLEZL:
case VR4300.OpCode.BLEZ:
return Format(instruction, FormatRegister(instruction.RS, cpu), (short)instruction.Immediate);
default:
return Format(instruction, FormatRegister(instruction.RT, cpu), FormatRegister(instruction.RS, cpu), (short)instruction.Immediate);
@ -89,12 +98,17 @@
case VR4300.SpecialOpCode.MFLO:
return Format(instruction, FormatRegister(instruction.RD, cpu));
case VR4300.SpecialOpCode.MULTU:
case VR4300.SpecialOpCode.DMULTU:
case VR4300.SpecialOpCode.DDIVU:
return Format(instruction, FormatRegister(instruction.RS, cpu), FormatRegister(instruction.RT, cpu));
case VR4300.SpecialOpCode.SLLV:
case VR4300.SpecialOpCode.SRLV:
return Format(instruction, FormatRegister(instruction.RD, cpu), FormatRegister(instruction.RT, cpu), FormatRegister(instruction.RS, cpu));
case VR4300.SpecialOpCode.SLL:
case VR4300.SpecialOpCode.SRL:
case VR4300.SpecialOpCode.DSLL32:
case VR4300.SpecialOpCode.DSRA32:
case VR4300.SpecialOpCode.SRA:
return Format(instruction, FormatRegister(instruction.RD, cpu), FormatRegister(instruction.RT, cpu), (sbyte)instruction.SA);
}

View File

@ -23,22 +23,31 @@ namespace DotN64.Diagnostics
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BEQ)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BEQL)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BLEZL)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BLEZ)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BNE)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.BNEL)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.CACHE)] = null,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.COP0)] = InstructionFormat.R, // FIXME: all CP0 ops are treated as such at the moment.
[VR4300.Instruction.FromOpCode(VR4300.OpCode.JAL)] = InstructionFormat.J,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.LBU)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.LUI)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.LD)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.LHU)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.LW)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.COP0)] = InstructionFormat.R, // FIXME: all CP0 ops are treated as such at the moment.
[VR4300.Instruction.FromOpCode(VR4300.OpCode.ORI)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.SB)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.SH)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.SLTI)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.SLTIU)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.SW)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.OpCode.XORI)] = InstructionFormat.I,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.ADD)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.ADDU)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.AND)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.DDIVU)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.DMULTU)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.DSLL32)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.DSRA32)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.JR)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFHI)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFLO)] = InstructionFormat.R,
@ -48,6 +57,7 @@ namespace DotN64.Diagnostics
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SLLV)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SLT)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SLTU)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SRA)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SRL)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SRLV)] = InstructionFormat.R,
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SUBU)] = InstructionFormat.R,

View File

@ -92,6 +92,7 @@
<Compile Include="CPU\VR4300\CP1\VR4300.FloatingPointUnit.Register.cs" />
<Compile Include="CPU\VR4300\CP1\VR4300.FloatingPointUnit.ImplementationRevisionRegister.cs" />
<Compile Include="CPU\VR4300\CP1\VR4300.FloatingPointUnit.ControlStatusRegister.cs" />
<Compile Include="CPU\VR4300\CP0\VR4300.SystemControlUnit.FunctOpCode.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="CPU\" />