Proper CPU reset.

master
Nabile Rahmani 2017-11-04 13:43:15 +01:00
parent 35932316c4
commit 467ea2a07d
5 changed files with 44 additions and 18 deletions

View File

@ -7,6 +7,9 @@ namespace DotN64.CPU
{
public partial class SystemControlUnit
{
/// <summary>
/// See: datasheet#5.4.6.
/// </summary>
public class ConfigRegister : Register
{
#region Fields

View File

@ -7,6 +7,9 @@ namespace DotN64.CPU
{
public partial class SystemControlUnit
{
/// <summary>
/// See: datasheet#6.3.5.
/// </summary>
public class StatusRegister : Register
{
#region Fields

View File

@ -31,15 +31,6 @@ namespace DotN64.CPU
#endregion
#region Methods
/// <summary>
/// Cold reset.
/// </summary>
public void Reset()
{
Config.EP = ConfigRegister.TransferDataPattern.D;
Config.BE = ConfigRegister.Endianness.BigEndian;
}
/// <summary>
/// Translates a virtual address into a physical address.
/// See: datasheet#5.2.4 Table 5-3.

View File

@ -3,7 +3,10 @@ using System.Collections.Generic;
namespace DotN64.CPU
{
// Reference: http://datasheets.chipdb.org/NEC/Vr-Series/Vr43xx/U10504EJ7V0UMJ1.pdf
/// <summary>
/// The NEC VR4300 CPU, designed by MIPS Technologies.
/// Datasheet: http://datasheets.chipdb.org/NEC/Vr-Series/Vr43xx/U10504EJ7V0UMJ1.pdf
/// </summary>
public partial class VR4300
{
#region Fields
@ -12,6 +15,8 @@ namespace DotN64.CPU
private readonly IReadOnlyDictionary<RegImmOpCode, Action<Instruction>> regImmOperations;
private ulong? delaySlot;
private const ulong ResetVector = 0xFFFFFFFFBFC00000;
private delegate bool BranchCondition(ulong rs, ulong rt);
#endregion
@ -57,6 +62,17 @@ namespace DotN64.CPU
public float FCR31 { get; set; }
public SystemControlUnit CP0 { get; }
private byte divMode;
/// <summary>
/// Internal operating frequency mode.
/// See: datasheet#2.2.2 Table 2-2.
/// </summary>
public byte DivMode
{
get => divMode;
set => divMode = (byte)(value & ((1 << 2) - 1));
}
#endregion
#region Constructors
@ -130,12 +146,25 @@ namespace DotN64.CPU
#region Methods
/// <summary>
/// Cold reset.
/// See: datasheet#6.4.4.
/// </summary>
public void Reset()
{
PC = 0xFFFFFFFFBFC00000;
PC = ResetVector;
CP0.Reset();
var ds = CP0.Status.DS;
ds.TS = ds.SR = CP0.Status.RP = false;
CP0.Config.EP = 0;
CP0.Status.ERL = ds.BEV = true;
CP0.Config.BE = (SystemControlUnit.ConfigRegister.Endianness)1;
CP0.Registers[(int)SystemControlUnit.RegisterIndex.Random] = 31;
CP0.Config.EC = DivMode;
CP0.Status.DS = ds;
}
public void Run(Instruction instruction)

View File

@ -99,15 +99,15 @@ namespace DotN64
Write = RI.WriteWord
}
};
CPU = new VR4300(memoryMaps);
CPU = new VR4300(memoryMaps)
{
DivMode = 0b01 // Assuming this value as the CPU is clocked at 93.75 MHz, and the RCP would be clocked at 93.75 / 3 * 2 = 62.5 MHz.
};
}
#endregion
#region Methods
/// <summary>
/// Emulates the PIF ROM.
/// </summary>
private void RunPIF()
private void EmulatePIFBootROM()
{
// Replicating the memory writes to properly initialise the subsystems.
var writes = new uint[,]
@ -171,7 +171,7 @@ namespace DotN64
CPU.Reset();
if (PI.BootROM == null)
RunPIF();
EmulatePIFBootROM();
while (true)
{