AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Runtime/Core/CPU.Core.cs
2024-06-28 18:08:25 +08:00

82 lines
2.2 KiB
C#

using System;
namespace AxibugEmuOnline.Client.UNES
{
sealed partial class CPU
{
public enum InterruptType
{
NMI,
IRQ,
RESET
}
private readonly uint[] _interruptHandlerOffsets = { 0xFFFA, 0xFFFE, 0xFFFC };
private readonly bool[] _interrupts = new bool[2];
public void Initialize()
{
A = 0;
X = 0;
Y = 0;
SP = 0xFD;
P = 0x24;
PC = ReadWord(_interruptHandlerOffsets[(int) InterruptType.RESET]);
}
public void Reset()
{
SP -= 3;
F.InterruptsDisabled = true;
}
public void TickFromPPU()
{
if (Cycle-- > 0) return;
ExecuteSingleInstruction();
}
public void ExecuteSingleInstruction()
{
for (var i = 0; i < _interrupts.Length; i++)
{
if (_interrupts[i])
{
PushWord(PC);
Push(P);
PC = ReadWord(_interruptHandlerOffsets[i]);
F.InterruptsDisabled = true;
_interrupts[i] = false;
return;
}
}
_currentInstruction = NextByte();
Cycle += _opCodeDefs[_currentInstruction].Cycles;
ResetInstructionAddressingMode();
// if (_numExecuted > 10000 && PC - 1 == 0xFF61)
// if(_emulator.Controller.debug || 0x6E00 <= PC && PC <= 0x6EEF)
// Console.WriteLine($"{(PC - 1).ToString("X4")} {_currentInstruction.ToString("X2")} {opcodeNames[_currentInstruction]}\t\t\tA:{A.ToString("X2")} X:{X.ToString("X2")} Y:{Y.ToString("X2")} P:{P.ToString("X2")} SP:{SP.ToString("X2")}");
var op = _opCodes[_currentInstruction];
if (op == null)
{
throw new ArgumentException(_currentInstruction.ToString("X2"));
}
op();
}
public void TriggerInterrupt(InterruptType type)
{
if (!F.InterruptsDisabled || type == InterruptType.NMI)
{
_interrupts[(int)type] = true;
}
}
}
}