Handle special cases for CP0 register writes.
- The timer interrupt is cleared on writes to the Compare register (see: #6.3.4). - Only software interrupt bits are writable into the Cause register (see: #6.3.6).master
parent
bb4d756ebb
commit
a4d06cef67
|
@ -21,6 +21,7 @@ namespace DotN64.CPU
|
|||
ce = BitVector32.CreateSection((1 << 2) - 1, constant2),
|
||||
constant3 = BitVector32.CreateSection(1, ce),
|
||||
bd = BitVector32.CreateSection(1, constant3);
|
||||
public static readonly ulong WriteMask = (ulong)(InterruptPending.WriteMask << ip.Offset);
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
@ -80,9 +81,10 @@ namespace DotN64.CPU
|
|||
#region Fields
|
||||
private BitVector32 bits;
|
||||
|
||||
private static BitVector32.Section softwareInterrupts = BitVector32.CreateSection((1 << 2) - 1),
|
||||
private static readonly BitVector32.Section softwareInterrupts = BitVector32.CreateSection((1 << 2) - 1),
|
||||
externalNormalInterrupts = BitVector32.CreateSection((1 << 5) - 1, softwareInterrupts),
|
||||
timerInterrupt = BitVector32.CreateSection(1, externalNormalInterrupts);
|
||||
public static readonly byte WriteMask = (byte)(softwareInterrupts.Mask << softwareInterrupts.Offset);
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
|
|
@ -34,7 +34,26 @@ namespace DotN64.CPU
|
|||
Cause = new CauseRegister(this);
|
||||
operations = new Dictionary<Instruction, Action<Instruction>>
|
||||
{
|
||||
[From(OpCode.MT)] = i => Registers[i.RD] = cpu.GPR[i.RT],
|
||||
[From(OpCode.MT)] = i =>
|
||||
{
|
||||
var destination = i.RD;
|
||||
var data = cpu.GPR[i.RT];
|
||||
|
||||
switch ((RegisterIndex)destination)
|
||||
{
|
||||
case RegisterIndex.Cause:
|
||||
Registers[destination] &= ~CauseRegister.WriteMask;
|
||||
Registers[destination] |= data & CauseRegister.WriteMask;
|
||||
return;
|
||||
case RegisterIndex.Compare:
|
||||
var ip = Cause.IP;
|
||||
ip.TimerInterrupt = false;
|
||||
Cause.IP = ip;
|
||||
break;
|
||||
}
|
||||
|
||||
Registers[destination] = data;
|
||||
},
|
||||
[From(OpCode.MF)] = i => cpu.GPR[i.RT] = (ulong)(int)Registers[i.RD],
|
||||
[From(FunctOpCode.TLBWI)] = i => { /* TODO. */ },
|
||||
[From(FunctOpCode.ERET)] = i =>
|
||||
|
|
Loading…
Reference in New Issue