More ops.
parent
1800179515
commit
6caa80fb9a
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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\" />
|
||||
|
|
Loading…
Reference in New Issue