2018-01-01 18:01:59 +01:00
|
|
|
|
using System;
|
2018-11-29 04:17:35 +01:00
|
|
|
|
using System.Threading;
|
2018-01-01 18:01:59 +01:00
|
|
|
|
|
|
|
|
|
namespace DotN64
|
2017-08-28 08:53:48 +02:00
|
|
|
|
{
|
2017-09-03 09:33:27 +02:00
|
|
|
|
using CPU;
|
2017-11-21 12:59:59 +01:00
|
|
|
|
using Extensions;
|
2017-10-03 19:49:25 +02:00
|
|
|
|
using RCP;
|
2017-09-03 09:33:27 +02:00
|
|
|
|
|
2017-10-03 02:14:41 +02:00
|
|
|
|
public class Nintendo64
|
2017-08-28 08:53:48 +02:00
|
|
|
|
{
|
|
|
|
|
#region Properties
|
2017-08-29 15:40:18 +02:00
|
|
|
|
public VR4300 CPU { get; }
|
2017-08-28 08:53:48 +02:00
|
|
|
|
|
2017-11-04 17:59:34 +01:00
|
|
|
|
public RealityCoprocessor RCP { get; }
|
|
|
|
|
|
2017-12-18 08:50:25 +01:00
|
|
|
|
public RDRAM RAM { get; } = new RDRAM(new byte[0x00400000]); // The base system has 4 MB of RAM installed.
|
|
|
|
|
|
|
|
|
|
public PeripheralInterface PIF { get; }
|
2017-08-31 19:23:56 +02:00
|
|
|
|
|
2018-06-27 16:08:45 +02:00
|
|
|
|
private Cartridge cartridge;
|
|
|
|
|
public Cartridge Cartridge
|
|
|
|
|
{
|
|
|
|
|
get => cartridge;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (Cartridge == value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cartridge = value;
|
|
|
|
|
CartridgeSwapped?.Invoke(this, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-27 16:12:46 +02:00
|
|
|
|
|
|
|
|
|
public IVideoOutput VideoOutput { get; set; }
|
|
|
|
|
|
|
|
|
|
public Switch Power { get; private set; }
|
|
|
|
|
|
|
|
|
|
public Diagnostics.Debugger Debugger { get; set; }
|
2018-06-27 16:08:45 +02:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Events
|
|
|
|
|
public event Action<Nintendo64, Cartridge> CartridgeSwapped;
|
2017-08-28 08:53:48 +02:00
|
|
|
|
#endregion
|
|
|
|
|
|
2017-08-29 15:40:18 +02:00
|
|
|
|
#region Constructors
|
|
|
|
|
public Nintendo64()
|
|
|
|
|
{
|
2017-12-18 08:50:25 +01:00
|
|
|
|
PIF = new PeripheralInterface(this);
|
2017-12-20 01:20:12 +01:00
|
|
|
|
RCP = new RealityCoprocessor(this);
|
2017-11-21 12:59:59 +01:00
|
|
|
|
CPU = new VR4300
|
2017-11-04 13:43:15 +01:00
|
|
|
|
{
|
2018-01-01 18:01:59 +01:00
|
|
|
|
DivMode = 0b01,
|
|
|
|
|
MasterClock = 62.5 * Math.Pow(10, 6),
|
2017-12-20 01:20:12 +01:00
|
|
|
|
ReadSysAD = RCP.MemoryMaps.ReadWord,
|
|
|
|
|
WriteSysAD = RCP.MemoryMaps.WriteWord
|
2017-11-04 13:43:15 +01:00
|
|
|
|
};
|
2017-08-29 15:40:18 +02:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
|
2017-08-28 08:53:48 +02:00
|
|
|
|
#region Methods
|
2017-10-06 02:56:34 +02:00
|
|
|
|
public void PowerOn()
|
2017-08-28 08:53:48 +02:00
|
|
|
|
{
|
2018-06-27 16:12:46 +02:00
|
|
|
|
Power = Switch.On;
|
|
|
|
|
|
2017-11-04 12:14:51 +01:00
|
|
|
|
CPU.Reset();
|
2017-12-18 08:50:25 +01:00
|
|
|
|
PIF.Reset();
|
2017-11-16 08:33:04 +01:00
|
|
|
|
}
|
2017-09-02 08:04:21 +02:00
|
|
|
|
|
2018-06-27 16:12:46 +02:00
|
|
|
|
public void PowerOff() => Power = Switch.Off;
|
|
|
|
|
|
2017-11-16 08:33:04 +01:00
|
|
|
|
public void Run()
|
|
|
|
|
{
|
2018-11-29 04:17:35 +01:00
|
|
|
|
var cpuThread = new Thread(() =>
|
|
|
|
|
{
|
|
|
|
|
if (Debugger == null)
|
2018-06-27 16:12:46 +02:00
|
|
|
|
{
|
2018-11-29 04:17:35 +01:00
|
|
|
|
while (Power == Switch.On)
|
2018-06-27 16:12:46 +02:00
|
|
|
|
{
|
2018-11-29 04:17:35 +01:00
|
|
|
|
if (Debugger == null)
|
|
|
|
|
CPU.Cycle();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Debugger.Run(true);
|
|
|
|
|
Debugger = null;
|
|
|
|
|
}
|
2018-06-27 16:12:46 +02:00
|
|
|
|
}
|
2018-11-29 04:17:35 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Debugger.Run(true);
|
|
|
|
|
PowerOff();
|
|
|
|
|
}
|
2018-12-24 17:13:27 +01:00
|
|
|
|
})
|
|
|
|
|
{ Name = nameof(VR4300) };
|
2018-11-29 04:17:35 +01:00
|
|
|
|
cpuThread.Start();
|
2018-06-27 16:12:46 +02:00
|
|
|
|
|
2018-11-29 04:17:35 +01:00
|
|
|
|
if (VideoOutput != null)
|
|
|
|
|
{
|
|
|
|
|
while (Power == Switch.On && VideoOutput != null)
|
2018-06-27 16:12:46 +02:00
|
|
|
|
{
|
2018-11-29 04:17:35 +01:00
|
|
|
|
VideoOutput.Draw(new VideoFrame(RCP.VI), RCP.VI, RAM);
|
2018-06-27 16:12:46 +02:00
|
|
|
|
}
|
2018-11-29 04:17:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cpuThread.Join();
|
2017-08-28 08:53:48 +02:00
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|