Move IP to a structure.
parent
158f01ccf9
commit
da3a886d71
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue