Move IP to a structure.

master
Nabile Rahmani 2018-01-02 15:34:22 +01:00
parent 158f01ccf9
commit da3a886d71
2 changed files with 53 additions and 11 deletions

View File

@ -43,9 +43,9 @@ namespace DotN64.CPU
/// IP(6:2) : External normal interrupts. Controlled by Int[4:0], or external write requests
/// IP(1:0) : Software interrupts. Only these bits can cause interrupt exception when they are set to 1 by software.
/// </summary>
public byte IP
public InterruptPending IP
{
get => (byte)this[ip];
get => (InterruptPending)this[ip];
set => this[ip] = value;
}
@ -76,6 +76,45 @@ namespace DotN64.CPU
: base(cp0) { }
#endregion
#region Structures
public struct InterruptPending
{
#region Fields
private BitVector32 bits;
private static BitVector32.Section softwareInterrupts = BitVector32.CreateSection((1 << 2) - 1),
externalNormalInterrupts = BitVector32.CreateSection((1 << 5) - 1, softwareInterrupts),
timerInterrupt = BitVector32.CreateSection(1, externalNormalInterrupts);
#endregion
#region Properties
public byte SoftwareInterrupts
{
get => (byte)bits[softwareInterrupts];
set => bits[softwareInterrupts] = value;
}
public byte ExternalNormalInterrupts
{
get => (byte)bits[externalNormalInterrupts];
set => bits[externalNormalInterrupts] = value;
}
public bool TimerInterrupt
{
get => Convert.ToBoolean(bits[timerInterrupt]);
set => bits[timerInterrupt] = Convert.ToInt32(value);
}
#endregion
#region Operators
public static implicit operator InterruptPending(byte data) => new InterruptPending { bits = new BitVector32(data) };
public static implicit operator byte(InterruptPending interrupt) => (byte)interrupt.bits.Data;
#endregion
}
#endregion
#region Enumerations
public enum ExceptionCode : byte
{

View File

@ -4,8 +4,6 @@ using System.Runtime.CompilerServices;
namespace DotN64.CPU
{
using Helpers;
/// <summary>
/// The NEC VR4300 CPU, designed by MIPS Technologies.
/// Datasheet: http://datasheets.chipdb.org/NEC/Vr-Series/Vr43xx/U10504EJ7V0UMJ1.pdf
@ -21,8 +19,6 @@ namespace DotN64.CPU
[0b11] = 3.0f
};
private const byte IntShift = 2, IntSize = (1 << 5) - 1;
private delegate bool BranchCondition(ulong rs, ulong rt);
#endregion
@ -102,12 +98,12 @@ namespace DotN64.CPU
/// </summary>
public byte Int
{
get => (byte)BitHelper.Get(CP0.Cause.IP, IntShift, IntSize);
get => CP0.Cause.IP.ExternalNormalInterrupts;
set
{
var ip = (uint)CP0.Cause.IP;
BitHelper.Set(ref ip, IntShift, IntSize, value);
CP0.Cause.IP = (byte)ip;
var ip = CP0.Cause.IP;
ip.ExternalNormalInterrupts = value;
CP0.Cause.IP = ip;
}
}
@ -230,10 +226,17 @@ namespace DotN64.CPU
public void Cycle()
{
if ((uint)++CP0.Registers[(int)SystemControlUnit.RegisterIndex.Count] == (uint)CP0.Registers[(int)SystemControlUnit.RegisterIndex.Compare])
CP0.Cause.IP |= 1 << 7; // Set the Timer interrupt.
{
var ip = CP0.Cause.IP;
ip.TimerInterrupt = true;
CP0.Cause.IP = ip;
}
if (CP0.Status.IE && !CP0.Status.EXL && !CP0.Status.ERL && (CP0.Status.IM & CP0.Cause.IP) != 0)
{
ExceptionProcessing.Interrupt(this);
return;
}
Step();
}