Proper CPU reset.
parent
35932316c4
commit
467ea2a07d
|
@ -7,6 +7,9 @@ namespace DotN64.CPU
|
|||
{
|
||||
public partial class SystemControlUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// See: datasheet#5.4.6.
|
||||
/// </summary>
|
||||
public class ConfigRegister : Register
|
||||
{
|
||||
#region Fields
|
||||
|
|
|
@ -7,6 +7,9 @@ namespace DotN64.CPU
|
|||
{
|
||||
public partial class SystemControlUnit
|
||||
{
|
||||
/// <summary>
|
||||
/// See: datasheet#6.3.5.
|
||||
/// </summary>
|
||||
public class StatusRegister : Register
|
||||
{
|
||||
#region Fields
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue