CPU: refactored control flow and load/store methods, added new ops.
parent
dca7725258
commit
eb41337dce
|
@ -0,0 +1,13 @@
|
|||
namespace DotN64.CPU
|
||||
{
|
||||
public partial class VR4300
|
||||
{
|
||||
private enum AccessSize : byte
|
||||
{
|
||||
Byte,
|
||||
HalfWord,
|
||||
Word,
|
||||
DoubleWord
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,7 +55,11 @@
|
|||
/// <summary>Store Halfword.</summary>
|
||||
SH = 0b101001,
|
||||
/// <summary>Load Halfword Unsigned.</summary>
|
||||
LHU = 0b100101
|
||||
LHU = 0b100101,
|
||||
/// <summary>Jump.</summary>
|
||||
J = 0b000010,
|
||||
/// <summary>Load Byte.</summary>
|
||||
LB = 0b100000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
/// <summary>Branch On Greater Than Or Equal To Zero And Link.</summary>
|
||||
BGEZAL = 0b10001,
|
||||
/// <summary>Branch On Greater Than Or Equal To Zero Likely.</summary>
|
||||
BGEZL = 0b00011
|
||||
BGEZL = 0b00011,
|
||||
/// <summary>Branch On Less Than Zero.</summary>
|
||||
BLTZ = 0b00000,
|
||||
/// <summary>Branch On Greater Than Or Equal To Zero.</summary>
|
||||
BGEZ = 0b00001
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,9 @@
|
|||
/// <summary>Move To LO.</summary>
|
||||
MTLO = 0b010011,
|
||||
/// <summary>Move To HI.</summary>
|
||||
MTHI = 0b010001
|
||||
MTHI = 0b010001,
|
||||
/// <summary>Jump And Link Register.</summary>
|
||||
JALR = 0b001001
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,11 +135,11 @@ namespace DotN64.CPU
|
|||
{
|
||||
[Instruction.FromOpCode(OpCode.LUI)] = i => GPR[i.RT] = (ulong)(i.Immediate << 16),
|
||||
[Instruction.FromOpCode(OpCode.ORI)] = i => GPR[i.RT] = GPR[i.RS] | i.Immediate,
|
||||
[Instruction.FromOpCode(OpCode.LW)] = i => GPR[i.RT] = (ulong)(int)ReadWord((ulong)(short)i.Immediate + GPR[i.RS]),
|
||||
[Instruction.FromOpCode(OpCode.LW)] = i => Load(i, AccessSize.Word),
|
||||
[Instruction.FromOpCode(OpCode.ANDI)] = i => GPR[i.RT] = i.Immediate & GPR[i.RS],
|
||||
[Instruction.FromOpCode(OpCode.BEQL)] = i => BranchLikely(i, (rs, rt) => rs == rt),
|
||||
[Instruction.FromOpCode(OpCode.ADDIU)] = i => GPR[i.RT] = (ulong)(int)(GPR[i.RS] + (ulong)(short)i.Immediate),
|
||||
[Instruction.FromOpCode(OpCode.SW)] = i => WriteWord((ulong)(short)i.Immediate + GPR[i.RS], (uint)GPR[i.RT]),
|
||||
[Instruction.FromOpCode(OpCode.SW)] = i => Store(i, AccessSize.Word),
|
||||
[Instruction.FromOpCode(OpCode.BNEL)] = i => BranchLikely(i, (rs, rt) => rs != rt),
|
||||
[Instruction.FromOpCode(OpCode.BNE)] = i => Branch(i, (rs, rt) => rs != rt),
|
||||
[Instruction.FromOpCode(OpCode.BEQ)] = i => Branch(i, (rs, rt) => rs == rt),
|
||||
|
@ -147,41 +147,24 @@ namespace DotN64.CPU
|
|||
[Instruction.FromOpCode(OpCode.CACHE)] = i => { /* TODO: Implement and compare the performance if it's a concern. */ },
|
||||
[Instruction.FromOpCode(OpCode.JAL)] = i =>
|
||||
{
|
||||
GPR[31] = PC + Instruction.Size;
|
||||
DelaySlot = PC;
|
||||
PC = (PC & ~((ulong)(1 << 28) - 1)) | (i.Target << 2);
|
||||
StoreLink();
|
||||
Jump((PC & ~((ulong)(1 << 28) - 1)) | (i.Target << 2));
|
||||
},
|
||||
[Instruction.FromOpCode(OpCode.SLTI)] = i => GPR[i.RT] = (long)GPR[i.RS] < (long)(short)i.Immediate ? (ulong)1 : 0,
|
||||
[Instruction.FromOpCode(OpCode.XORI)] = i => GPR[i.RT] = GPR[i.RS] ^ i.Immediate,
|
||||
[Instruction.FromOpCode(OpCode.BLEZL)] = i => BranchLikely(i, (rs, rt) => rs <= 0),
|
||||
[Instruction.FromOpCode(OpCode.SB)] = i =>
|
||||
{
|
||||
var address = (ulong)(short)i.Immediate + GPR[i.RS];
|
||||
|
||||
WriteWord(address, (ReadWord(address) & ~((uint)(1 << 8) - 1)) | (byte)GPR[i.RT]);
|
||||
},
|
||||
[Instruction.FromOpCode(OpCode.LBU)] = i => GPR[i.RT] = (byte)ReadWord((ulong)(short)i.Immediate + GPR[i.RS]),
|
||||
[Instruction.FromOpCode(OpCode.SB)] = i => Store(i, AccessSize.Byte),
|
||||
[Instruction.FromOpCode(OpCode.LBU)] = i => LoadUnsigned(i, AccessSize.Byte),
|
||||
[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.LD)] = i => Load(i, AccessSize.DoubleWord),
|
||||
[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(OpCode.SH)] = i => Store(i, AccessSize.HalfWord),
|
||||
[Instruction.FromOpCode(OpCode.LHU)] = i => LoadUnsigned(i, AccessSize.HalfWord),
|
||||
[Instruction.FromOpCode(OpCode.J)] = i => Jump((PC & ~((ulong)(1 << 28) - 1)) | (i.Target << 2)),
|
||||
[Instruction.FromOpCode(OpCode.LB)] = i => Load(i, AccessSize.Byte),
|
||||
[Instruction.FromOpCode(SpecialOpCode.ADD)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RS] + (int)GPR[i.RT]),
|
||||
[Instruction.FromOpCode(SpecialOpCode.JR)] = i =>
|
||||
{
|
||||
DelaySlot = PC;
|
||||
PC = GPR[i.RS];
|
||||
},
|
||||
[Instruction.FromOpCode(SpecialOpCode.JR)] = i => Jump(GPR[i.RS]),
|
||||
[Instruction.FromOpCode(SpecialOpCode.SRL)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RT] >> i.SA),
|
||||
[Instruction.FromOpCode(SpecialOpCode.OR)] = i => GPR[i.RD] = GPR[i.RS] | GPR[i.RT],
|
||||
[Instruction.FromOpCode(SpecialOpCode.MULTU)] = i =>
|
||||
|
@ -224,8 +207,19 @@ namespace DotN64.CPU
|
|||
[Instruction.FromOpCode(SpecialOpCode.SRA)] = i => GPR[i.RD] = (ulong)((int)GPR[i.RT] >> i.SA),
|
||||
[Instruction.FromOpCode(SpecialOpCode.MTLO)] = i => LO = GPR[i.RS],
|
||||
[Instruction.FromOpCode(SpecialOpCode.MTHI)] = i => HI = GPR[i.RS],
|
||||
[Instruction.FromOpCode(RegImmOpCode.BGEZAL)] = i => Branch(i, (rs, rt) => rs >= 0, true),
|
||||
[Instruction.FromOpCode(RegImmOpCode.BGEZL)] = i => BranchLikely(i, (rs, rt) => rs >= 0)
|
||||
[Instruction.FromOpCode(SpecialOpCode.JALR)] = i =>
|
||||
{
|
||||
StoreLink((GPRIndex)i.RD);
|
||||
Jump(GPR[i.RS]);
|
||||
},
|
||||
[Instruction.FromOpCode(RegImmOpCode.BGEZAL)] = i =>
|
||||
{
|
||||
StoreLink();
|
||||
Branch(i, (rs, rt) => rs >= 0);
|
||||
},
|
||||
[Instruction.FromOpCode(RegImmOpCode.BGEZL)] = i => BranchLikely(i, (rs, rt) => rs >= 0),
|
||||
[Instruction.FromOpCode(RegImmOpCode.BLTZ)] = i => Branch(i, (rs, rt) => rs < 0),
|
||||
[Instruction.FromOpCode(RegImmOpCode.BGEZ)] = i => Branch(i, (rs, rt) => rs >= 0)
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
@ -289,18 +283,12 @@ namespace DotN64.CPU
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool Branch(Instruction instruction, BranchCondition condition, bool storeLink = false)
|
||||
private bool Branch(Instruction instruction, BranchCondition condition)
|
||||
{
|
||||
var result = condition(GPR[instruction.RS], GPR[instruction.RT]);
|
||||
|
||||
if (storeLink)
|
||||
GPR[31] = PC + Instruction.Size;
|
||||
|
||||
if (result)
|
||||
{
|
||||
DelaySlot = PC;
|
||||
PC += (ulong)(short)instruction.Immediate << 2;
|
||||
}
|
||||
Jump(PC + ((ulong)(short)instruction.Immediate << 2));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -313,10 +301,92 @@ namespace DotN64.CPU
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private uint ReadWord(ulong address) => ReadSysAD(CP0.Translate(address));
|
||||
private void Jump(ulong address)
|
||||
{
|
||||
DelaySlot = PC;
|
||||
PC = address;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void WriteWord(ulong address, uint value) => WriteSysAD(CP0.Translate(address), value);
|
||||
private void StoreLink(GPRIndex index = GPRIndex.RA) => GPR[(int)index] = PC + Instruction.Size;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private uint ReadWord(ulong address) => (uint)Read(address, AccessSize.Word);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private ulong Read(ulong address, AccessSize size)
|
||||
{
|
||||
var physicalAddress = CP0.Translate(address);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case AccessSize.Byte:
|
||||
return (byte)ReadSysAD(physicalAddress);
|
||||
case AccessSize.HalfWord:
|
||||
return (ushort)ReadSysAD(physicalAddress);
|
||||
case AccessSize.Word:
|
||||
return ReadSysAD(physicalAddress);
|
||||
case AccessSize.DoubleWord:
|
||||
return ReadSysAD(physicalAddress) << 32 | ReadSysAD(physicalAddress + sizeof(uint));
|
||||
default:
|
||||
throw new ArgumentException("Invalid system bus access size.", nameof(size));
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void Write(ulong address, ulong value, AccessSize size)
|
||||
{
|
||||
var physicalAddress = CP0.Translate(address);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case AccessSize.Byte:
|
||||
WriteSysAD(physicalAddress, (ReadWord(address) & ~((uint)(1 << 8) - 1)) | (byte)value);
|
||||
break;
|
||||
case AccessSize.HalfWord:
|
||||
WriteSysAD(physicalAddress, (ReadWord(address) & ~((uint)(1 << 16) - 1)) | (ushort)value);
|
||||
break;
|
||||
case AccessSize.Word:
|
||||
WriteSysAD(physicalAddress, (uint)value);
|
||||
break;
|
||||
case AccessSize.DoubleWord:
|
||||
WriteSysAD(physicalAddress, (uint)(value >> 32));
|
||||
WriteSysAD(physicalAddress + sizeof(uint), (uint)value);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid system bus access size.", nameof(size));
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void Load(Instruction instruction, AccessSize size, bool signExtend = true)
|
||||
{
|
||||
var value = Read((ulong)(short)instruction.Immediate + GPR[instruction.RS], size);
|
||||
|
||||
if (signExtend)
|
||||
{
|
||||
switch (size)
|
||||
{
|
||||
case AccessSize.Byte:
|
||||
value = (ulong)(sbyte)value;
|
||||
break;
|
||||
case AccessSize.HalfWord:
|
||||
value = (ulong)(short)value;
|
||||
break;
|
||||
case AccessSize.Word:
|
||||
value = (ulong)(int)value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GPR[instruction.RT] = value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void LoadUnsigned(Instruction instruction, AccessSize size) => Load(instruction, size, false);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void Store(Instruction instruction, AccessSize size) => Write((ulong)(short)instruction.Immediate + GPR[instruction.RS], GPR[instruction.RT], size);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
{
|
||||
case VR4300.RegImmOpCode.BGEZAL:
|
||||
case VR4300.RegImmOpCode.BGEZL:
|
||||
case VR4300.RegImmOpCode.BLTZ:
|
||||
case VR4300.RegImmOpCode.BGEZ:
|
||||
return Format(instruction, FormatRegister(instruction.RS, cpu), (short)instruction.Immediate);
|
||||
}
|
||||
|
||||
|
@ -92,6 +94,8 @@
|
|||
{
|
||||
switch (instruction.Special)
|
||||
{
|
||||
case VR4300.SpecialOpCode.JALR:
|
||||
return Format(instruction, FormatRegister(instruction.RD, cpu), FormatRegister(instruction.RS, cpu));
|
||||
case VR4300.SpecialOpCode.JR:
|
||||
case VR4300.SpecialOpCode.MTLO:
|
||||
case VR4300.SpecialOpCode.MTHI:
|
||||
|
@ -133,7 +137,7 @@
|
|||
/// <summary>
|
||||
/// Jump type.
|
||||
/// </summary>
|
||||
public static string J(VR4300.Instruction instruction, VR4300 cpu) => Format(instruction, $"0x{instruction.Target:X8}");
|
||||
public static string J(VR4300.Instruction instruction, VR4300 cpu) => Format(instruction, $"0x{((cpu != null ? (cpu.DelaySlot ?? cpu.PC) : 0) & ~(ulong)((1 << 28) - 1)) | (instruction.Target << 2):X8}");
|
||||
|
||||
public static string Unknown(VR4300.Instruction instruction) => FormatOpCode(instruction);
|
||||
#endregion
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace DotN64.Diagnostics
|
|||
[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.J)] = 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,
|
||||
|
@ -41,6 +42,7 @@ namespace DotN64.Diagnostics
|
|||
[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.OpCode.LB)] = 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,
|
||||
|
@ -49,6 +51,7 @@ namespace DotN64.Diagnostics
|
|||
[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.JALR)] = InstructionFormat.R,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFHI)] = InstructionFormat.R,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MFLO)] = InstructionFormat.R,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.MTHI)] = InstructionFormat.R,
|
||||
|
@ -65,7 +68,9 @@ namespace DotN64.Diagnostics
|
|||
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.SUBU)] = InstructionFormat.R,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.SpecialOpCode.XOR)] = InstructionFormat.R,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.RegImmOpCode.BGEZAL)] = InstructionFormat.I,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.RegImmOpCode.BGEZL)] = InstructionFormat.I
|
||||
[VR4300.Instruction.FromOpCode(VR4300.RegImmOpCode.BGEZL)] = InstructionFormat.I,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.RegImmOpCode.BLTZ)] = InstructionFormat.I,
|
||||
[VR4300.Instruction.FromOpCode(VR4300.RegImmOpCode.BGEZ)] = InstructionFormat.I
|
||||
};
|
||||
#endregion
|
||||
|
||||
|
@ -92,8 +97,24 @@ namespace DotN64.Diagnostics
|
|||
nintendo64.CPU.Cycle();
|
||||
}
|
||||
}),
|
||||
new Command(new[] { "goto", "g" }, "Sets the CPU's PC to the specified address.", args => nintendo64.CPU.PC = ulong.Parse(args.First(), NumberStyles.HexNumber)),
|
||||
new Command(new[] { "disassemble", "d" }, "Disassembles instructions from the current PC.", args =>
|
||||
new Command(new[] { "goto", "g" }, "Sets the CPU's PC to the specified address or register value.", args =>
|
||||
{
|
||||
var target = args.First();
|
||||
const char RegisterPrefix = '$';
|
||||
|
||||
if (target[0] == RegisterPrefix)
|
||||
{
|
||||
target = target.Substring(1);
|
||||
|
||||
if (Enum.TryParse<VR4300.GPRIndex>(target, true, out var gprIndex))
|
||||
nintendo64.CPU.PC = nintendo64.CPU.GPR[(int)gprIndex];
|
||||
else if (Enum.TryParse<VR4300.SystemControlUnit.RegisterIndex>(target, true, out var cp0Index))
|
||||
nintendo64.CPU.PC = nintendo64.CPU.CP0.Registers[(int)cp0Index];
|
||||
}
|
||||
else
|
||||
nintendo64.CPU.PC = ulong.Parse(target, NumberStyles.HexNumber);
|
||||
}),
|
||||
new Command(new[] { "disassemble", "disasm", "d" }, "Disassembles instructions from the current PC.", args =>
|
||||
{
|
||||
var count = args.Length > 0 ? BigInteger.Parse(args.First()) : 1;
|
||||
|
||||
|
@ -127,14 +148,14 @@ namespace DotN64.Diagnostics
|
|||
{
|
||||
foreach (var pair in labels)
|
||||
{
|
||||
Console.WriteLine($".{pair.Value}: {pair.Key:X16}");
|
||||
Console.WriteLine($"{pair.Value}: {pair.Key:X16}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var address = ulong.Parse(args[index++], NumberStyles.HexNumber);
|
||||
|
||||
Console.WriteLine($".{labels[address]}: {address:X16}");
|
||||
Console.WriteLine($"{labels[address]}: {address:X16}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -203,7 +224,7 @@ namespace DotN64.Diagnostics
|
|||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
|
||||
Console.WriteLine($".{label}:");
|
||||
Console.WriteLine($"{label}:");
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
<RootNamespace>DotN64</RootNamespace>
|
||||
<AssemblyName>DotN64</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<ReleaseVersion>0.0.0.*</ReleaseVersion>
|
||||
<SynchReleaseVersion>false</SynchReleaseVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -93,6 +95,7 @@
|
|||
<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" />
|
||||
<Compile Include="CPU\VR4300\VR4300.AccessSize.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="CPU\" />
|
||||
|
|
Loading…
Reference in New Issue