diff --git a/CPU_emu/Attributes/OpcodeAttribute.cs b/CPU_emu/Attributes/OpcodeAttribute.cs new file mode 100644 index 0000000..8bdceb9 --- /dev/null +++ b/CPU_emu/Attributes/OpcodeAttribute.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPU_emulator; + +[AttributeUsage(AttributeTargets.Method)] +internal class OpcodeAttribute : Attribute +{ + public int Cycles { get; } + public bool IsUndocumented { get; } + public bool AddsCycleOnPageCross { get; } + + public OpcodeAttribute(int cycles, bool undocumented = false, bool pageCross = false) + { + Cycles = cycles; + IsUndocumented = undocumented; + AddsCycleOnPageCross = pageCross; + } +} diff --git a/CPU_emu/CPU_emu.CMD_Methods.cs b/CPU_emu/CPU_emu.CMD_Methods.cs index 73e7b6b..1f64848 100644 --- a/CPU_emu/CPU_emu.CMD_Methods.cs +++ b/CPU_emu/CPU_emu.CMD_Methods.cs @@ -1,108 +1,108 @@ using System; using System.Windows.Forms; -namespace CPU_emulator +namespace CPU_emulator; + +public partial class CPU { - public partial class CPU + #region BRK + // BREAK + public void Cmd_00() + { + ExitRequested = true; + OnBreak?.Invoke(this, new CPUEventArgs(this)); + } + #endregion + + #region LDA + // Load Accumulator immidiate A9 + [Opcode(2)] + public void Cmd_A9() + { + SetRegister("A", FetchByte()); + SetZeroAndNegativeFlags(A); + } + + // Load Accumulator zeropage A5 + public void Cmd_A5() + { + SetRegister("A", ReadByteFromMemory(FetchByte())); + SetZeroAndNegativeFlags(A); + } + + // Load Accumulator zeropage X B5 + public void Cmd_B5() { - #region BRK - // BREAK - public void Cmd_00() - { - ExitRequested = true; - OnBreak?.Invoke(this, new CPUEventArgs(this)); - } - #endregion - - #region LDA - // Load Accumulator immidiate A9 - public void Cmd_A9() - { - SetRegister("A", FetchByte(ref _CpuCycle)); - SetZeroAndNegativeFlags(A); - } - - // Load Accumulator zeropage A5 - public void Cmd_A5() - { - SetRegister("A", ReadByteFromMemory(FetchByte(ref _CpuCycle))); - SetZeroAndNegativeFlags(A); - } - - // Load Accumulator zeropage X B5 - public void Cmd_B5() - { - byte b_tmp = FetchByte(ref _CpuCycle); - b_tmp += X; // add regX to address - SetRegister("A", ReadByteFromMemory(b_tmp)); - SetZeroAndNegativeFlags(A); - } - #endregion - - #region LDX - // Load X immidiate A2 - public void Cmd_A2() - { - byte b_tmp = FetchByte(ref _CpuCycle); - SetRegister("X", b_tmp); - SetZeroAndNegativeFlags(X); - } - - // Load X zeropage A6 - public void Cmd_A6() - { - byte b_tmp = FetchByte(ref _CpuCycle); - SetRegister("X", ReadByteFromMemory(b_tmp)); - SetZeroAndNegativeFlags(X); - } - - // Load X zeropage Y B6 - public void Cmd_B6() - { - byte b_tmp = FetchByte(ref _CpuCycle); // Get ZP address - b_tmp += Y; // add regY to address - SetRegister("X", ReadByteFromMemory(b_tmp)); - SetZeroAndNegativeFlags(X); - } - - #endregion - - #region LDY - // Load Y immidiate A0 - public void Cmd_A0() - { - byte b_tmp = FetchByte(ref _CpuCycle); - SetRegister("Y", b_tmp); - SetZeroAndNegativeFlags(Y); - } - - // Load Y zeropage A4 - public void Cmd_A4() - { - byte b_tmp = FetchByte(ref _CpuCycle); - SetRegister("Y", ReadByteFromMemory(b_tmp)); - SetZeroAndNegativeFlags(Y); - } - - // Load Y zeropage X B4 - public void Cmd_B4() - { - byte b_tmp = FetchByte(ref _CpuCycle); // Get ZP address - b_tmp += X; // add regX to address - SetRegister("Y", ReadByteFromMemory(b_tmp)); - SetZeroAndNegativeFlags(Y); - } - - #endregion - - #region stack push pull - - // Push Accumulator on Stack - public void Cmd_48() - { - PushByteToStack(A,ref _CpuCycle); - } - - #endregion + byte b_tmp = FetchByte(); + b_tmp += X; // add regX to address + SetRegister("A", ReadByteFromMemory(b_tmp)); + SetZeroAndNegativeFlags(A); } + #endregion + + #region LDX + // Load X immidiate A2 + public void Cmd_A2() + { + byte b_tmp = FetchByte(); + SetRegister("X", b_tmp); + SetZeroAndNegativeFlags(X); + } + + // Load X zeropage A6 + public void Cmd_A6() + { + byte b_tmp = FetchByte(); + SetRegister("X", ReadByteFromMemory(b_tmp)); + SetZeroAndNegativeFlags(X); + } + + // Load X zeropage Y B6 + public void Cmd_B6() + { + byte b_tmp = FetchByte(); // Get ZP address + b_tmp += Y; // add regY to address + SetRegister("X", ReadByteFromMemory(b_tmp)); + SetZeroAndNegativeFlags(X); + } + + #endregion + + #region LDY + // Load Y immidiate A0 + public void Cmd_A0() + { + byte b_tmp = FetchByte(); + SetRegister("Y", b_tmp); + SetZeroAndNegativeFlags(Y); + } + + // Load Y zeropage A4 + public void Cmd_A4() + { + byte b_tmp = FetchByte(); + SetRegister("Y", ReadByteFromMemory(b_tmp)); + SetZeroAndNegativeFlags(Y); + } + + // Load Y zeropage X B4 + public void Cmd_B4() + { + byte b_tmp = FetchByte(); // Get ZP address + b_tmp += X; // add regX to address + SetRegister("Y", ReadByteFromMemory(b_tmp)); + SetZeroAndNegativeFlags(Y); + } + + #endregion + + #region stack push pull + + // Push Accumulator on Stack + public void Cmd_48() + { + PushByteToStack(A,ref _CpuCycle); + } + + #endregion } \ No newline at end of file diff --git a/CPU_emu/CPU_emu.opcodes.cs b/CPU_emu/CPU_emu.opcodes.cs index 50aaa5c..c1f7b6d 100644 --- a/CPU_emu/CPU_emu.opcodes.cs +++ b/CPU_emu/CPU_emu.opcodes.cs @@ -8,29 +8,29 @@ namespace CPU_emulator { public partial class CPU { - private const byte - OC_BRK = 0x00, - // LDA - OC_LDA_IM = 0xA9, - OC_LDA_ZP = 0xA5, - OC_LDA_ZPX = 0xB5, - // LDX - OC_LDX_IM = 0xA2, - OC_LDX_ZP = 0xA6, - OC_LDX_ZPY = 0xB6, - // LDY - OC_LDY_IM = 0xA0, - OC_LDY_ZP = 0xA4, - OC_LDY_ZPX = 0xB4, + //private const byte + // OC_BRK = 0x00, + // // LDA + // OC_LDA_IM = 0xA9, + // OC_LDA_ZP = 0xA5, + // OC_LDA_ZPX = 0xB5, + // // LDX + // OC_LDX_IM = 0xA2, + // OC_LDX_ZP = 0xA6, + // OC_LDX_ZPY = 0xB6, + // // LDY + // OC_LDY_IM = 0xA0, + // OC_LDY_ZP = 0xA4, + // OC_LDY_ZPX = 0xB4, - // JMP - OC_JMP_ABS = 0x4C, - OC_JMP_IND = 0x6C, + // // JMP + // OC_JMP_ABS = 0x4C, + // OC_JMP_IND = 0x6C, - // Stack - OC_PHA = 0x48, - OC_PLA = 0x68 - ; + // // Stack + // OC_PHA = 0x48, + // OC_PLA = 0x68 + // ; } diff --git a/CPU_emu/Class_CPU.cs b/CPU_emu/Class_CPU.cs index 47162a3..bc8f359 100644 --- a/CPU_emu/Class_CPU.cs +++ b/CPU_emu/Class_CPU.cs @@ -8,421 +8,423 @@ using System.Runtime.InteropServices; using System.Windows.Forms; -namespace CPU_emulator +namespace CPU_emulator; + +public partial class CPU { - public partial class CPU + + public uint PC { get; set; } = 0xFFFC; // ProgramCounter + public bool SlowDown { get; set; } = false; + public int SlowDownTime { get; set; } = 750; // + + public ushort SP; // StackPointer + public byte A, X, Y; // registers + private ushort ResetVector = 0xFFFC; + + //status Flags Carry, Zero, intDisable, Decimalmode, Break, Overflow, Negative flag + public IDictionary flags = new Dictionary(); + public bool CpuIsRunning = true; + private ulong _InterruptPeriod; + private bool _ExitRequested; + private bool _SteppingMode; + internal ulong _CpuCycle; + private const uint MAX_MEM = 1024 * 64; + private byte[] Data = new byte[MAX_MEM]; + + private byte + NegativeFlagBit = 0b10000000, + OverflowFlagBit = 0b01000000, + BreakFlagBit = 0b000010000, + UnusedFlagBit = 0b000100000, + InterruptDisableFlagBit = 0b000000100, + ZeroBit = 0b00000001; + + public bool SteppingMode { get => _SteppingMode; set => _SteppingMode = value; } + public bool ExitRequested { get => _ExitRequested; set => _ExitRequested = value; } + public ulong InterruptPeriod { get => _InterruptPeriod; set => _InterruptPeriod = value; } + public byte[] Memory { - - public uint PC { get; set; } = 0xFFFC; // ProgramCounter - public bool SlowDown { get; set; } = false; - public int SlowDownTime { get; set; } = 750; // - - public ushort SP; // StackPointer - public byte A, X, Y; // registers - private ushort ResetVector = 0xFFFC; - - //status Flags Carry, Zero, intDisable, Decimalmode, Break, Overflow, Negative flag - public IDictionary flags = new Dictionary(); - public bool CpuIsRunning = true; - private ulong _InterruptPeriod; - private bool _ExitRequested; - private bool _SteppingMode; - internal ulong _CpuCycle; - private const uint MAX_MEM = 1024 * 64; - private byte[] Data = new byte[MAX_MEM]; - - private byte - NegativeFlagBit = 0b10000000, - OverflowFlagBit = 0b01000000, - BreakFlagBit = 0b000010000, - UnusedFlagBit = 0b000100000, - InterruptDisableFlagBit = 0b000000100, - ZeroBit = 0b00000001; - - public bool SteppingMode { get => _SteppingMode; set => _SteppingMode = value; } - public bool ExitRequested { get => _ExitRequested; set => _ExitRequested = value; } - public ulong InterruptPeriod { get => _InterruptPeriod; set => _InterruptPeriod = value; } - public byte[] Memory + get { - get - { - return Data; - } - - set - { - Data = value; - OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); - } + return Data; } - //public uint PC { get => pC; set => pC = value; } - //public uint InitialPC { get => _initialPC; set => _initialPC = value; } - - public event EventHandler OnFlagsUpdate; - public event EventHandler OnMemoryUpdate; - public event EventHandler OnRegisterUpdate; - public event EventHandler OnCpuCycleIncrement; - public event EventHandler OnProgramCounterUpdate; - public event EventHandler OnStackPointerUpdate; - public event EventHandler OnPCoverflow; - public event EventHandler OnBreak; - - public CPU() + set { - SetVectors(); + Data = value; + OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); } + } - private void SetVectors() - { - // Reset-Vector - WriteByteToMemory(0x00, 0xFFFC); - WriteByteToMemory(0x02, 0xFFFD); + //public uint PC { get => pC; set => pC = value; } + //public uint InitialPC { get => _initialPC; set => _initialPC = value; } + + public event EventHandler OnFlagsUpdate; + public event EventHandler OnMemoryUpdate; + public event EventHandler OnRegisterUpdate; + public event EventHandler OnCpuCycleIncrement; + public event EventHandler OnProgramCounterUpdate; + public event EventHandler OnStackPointerUpdate; + public event EventHandler OnPCoverflow; + public event EventHandler OnBreak; + + public CPU() + { + SetVectors(); + } - } + private void SetVectors() + { + // Reset-Vector + WriteByteToMemory(0x00, 0xFFFC); + WriteByteToMemory(0x02, 0xFFFD); - public void Reset() - { - ushort tmpPC = ReadWordFromMemory(ResetVector); + } - SetPC(tmpPC); - SetSP(0x01FF); + public void Reset() + { + ushort tmpPC = ReadWordFromMemory(ResetVector); - SetRegister("A", 0); - SetRegister("X", 0); - SetRegister("Y", 0); - InterruptPeriod = 1000; - ExitRequested = false; + SetPC(tmpPC); + SetSP(0x01FF); - // set all status flags to false - flags["C"] = flags["Z"] = flags["I"] = flags["D"] = flags["B"] = flags["V"] = flags["N"] = false; + SetRegister("A", 0); + SetRegister("X", 0); + SetRegister("Y", 0); + InterruptPeriod = 1000; + ExitRequested = false; - //LoadInlineTestProg(); + // set all status flags to false + flags["C"] = flags["Z"] = flags["I"] = flags["D"] = flags["B"] = flags["V"] = flags["N"] = false; - OnFlagsUpdate?.Invoke(this, new CPUEventArgs(this)); - OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); - ResetCpuCycle(); + //LoadInlineTestProg(); - } + OnFlagsUpdate?.Invoke(this, new CPUEventArgs(this)); + OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); + ResetCpuCycle(); - private void LoadInlineTestProg() - { - Data[PC] = 0xB5; - Data[PC + 1] = 0x0b; - Data[PC + 2] = 0x48; - Data[PC + 3] = 0xA9; - Data[PC + 4] = 0xac; - Data[PC + 5] = 0x48; - Data[PC + 6] = 0xA9; - Data[PC + 7] = 0x00; - Data[PC + 8] = 0x48; - Data[PC + 9] = 0xA9; - Data[PC + 10] = 0xae; - Data[PC + 11] = 0x48; - - Data[PC + 12] = 0x48; - Data[PC + 13] = 0x48; - Data[PC + 14] = 0x48; - Data[PC + 15] = 0x48; - - Data[PC + 16] = 0x48; - Data[PC + 17] = 0x48; - Data[PC + 18] = 0x48; - Data[PC + 19] = 0x48; - - Data[PC + 20] = 0x48; - Data[PC + 21] = 0x48; - Data[PC + 22] = 0x48; - Data[PC + 23] = 0x48; - Data[PC + 24] = 0x48; - Data[PC + 25] = 0x48; - Data[PC + 26] = 0x48; - Data[PC + 27] = 0x48; - - Data[PC + 28] = 0x48; - Data[PC + 29] = 0x68; - Data[PC + 30] = 0x68; - Data[PC + 31] = 0x68; - Data[PC + 32] = 0x68; - Data[PC + 33] = 0x68; - Data[PC + 34] = 0x68; - Data[PC + 35] = 0x68; + } - OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); - } + private void LoadInlineTestProg() + { + Data[PC] = 0xB5; + Data[PC + 1] = 0x0b; + Data[PC + 2] = 0x48; + Data[PC + 3] = 0xA9; + Data[PC + 4] = 0xac; + Data[PC + 5] = 0x48; + Data[PC + 6] = 0xA9; + Data[PC + 7] = 0x00; + Data[PC + 8] = 0x48; + Data[PC + 9] = 0xA9; + Data[PC + 10] = 0xae; + Data[PC + 11] = 0x48; + + Data[PC + 12] = 0x48; + Data[PC + 13] = 0x48; + Data[PC + 14] = 0x48; + Data[PC + 15] = 0x48; + + Data[PC + 16] = 0x48; + Data[PC + 17] = 0x48; + Data[PC + 18] = 0x48; + Data[PC + 19] = 0x48; + + Data[PC + 20] = 0x48; + Data[PC + 21] = 0x48; + Data[PC + 22] = 0x48; + Data[PC + 23] = 0x48; + Data[PC + 24] = 0x48; + Data[PC + 25] = 0x48; + Data[PC + 26] = 0x48; + Data[PC + 27] = 0x48; + + Data[PC + 28] = 0x48; + Data[PC + 29] = 0x68; + Data[PC + 30] = 0x68; + Data[PC + 31] = 0x68; + Data[PC + 32] = 0x68; + Data[PC + 33] = 0x68; + Data[PC + 34] = 0x68; + Data[PC + 35] = 0x68; + + OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); + } - public void Start() - { - ExitRequested = false; - - var CpuRunner = new BackgroundWorker(); - CpuRunner.DoWork += CpuRunner_DoWork; - CpuRunner.RunWorkerAsync(); - } + public void Start() + { + ExitRequested = false; + + var CpuRunner = new BackgroundWorker(); + CpuRunner.DoWork += CpuRunner_DoWork; + CpuRunner.RunWorkerAsync(); + } + + + private void CpuRunner_DoWork(object sender, DoWorkEventArgs e) + { + //_CpuCycle = InterruptPeriod; + + Type thisType = this.GetType(); - private void CpuRunner_DoWork(object sender, DoWorkEventArgs e) + while (CpuIsRunning) { - //_CpuCycle = InterruptPeriod; - - Type thisType = this.GetType(); + byte instruction = FetchByte(); + // Build method name from 'Cmd' + opcode + string cmd = "Cmd_" + instruction.ToString("X2").ToUpper(); - while (CpuIsRunning) + MethodInfo theMethod2Call = thisType.GetMethod(cmd); + // Check if method Cmd_ exists + if (theMethod2Call != null) { - byte instruction = FetchByte(ref _CpuCycle); - - // Build method name from 'Cmd' + opcode - string cmd = "Cmd_" + instruction.ToString("X2").ToUpper(); + // check for method attribute + OpcodeAttribute? attribute = theMethod2Call.GetCustomAttribute(); - MethodInfo theMethod2Call = thisType.GetMethod(cmd); - // Check if method Cmd_ exists - if (theMethod2Call != null) - { - theMethod2Call.Invoke(this, new object[] { }); - } - else - { - MessageBox.Show(string.Format("Method {0} not found!", cmd),"Error!",MessageBoxButtons.OK,MessageBoxIcon.Error); - } - - if (_SteppingMode) - { - break; - } - if (ExitRequested) - { - break; - } - if (PC >= MAX_MEM) - { - OnPCoverflow?.Invoke(this, new CPUEventArgs(this)); - break; - } - - //ToDo remove - //if (_CpuCycle <= 0) - //{ - // _CpuCycle = InterruptPeriod; - //} + theMethod2Call.Invoke(this, new object[] { }); - if (SlowDown && !_SteppingMode) + if (attribute != null) { - System.Threading.Thread.Sleep(SlowDownTime); + IncrementCpuCycle((ulong)attribute.Cycles); } - + } + else + { + MessageBox.Show(string.Format("Method {0} not found!", cmd),"Error!",MessageBoxButtons.OK,MessageBoxIcon.Error); + } + + if (_SteppingMode) + { + break; + } + if (ExitRequested) + { + break; + } + if (PC >= MAX_MEM) + { + OnPCoverflow?.Invoke(this, new CPUEventArgs(this)); + break; + } + + if (SlowDown && !_SteppingMode) + { + System.Threading.Thread.Sleep(SlowDownTime); } - } + - private uint AddrAbsolute() - { - return FetchWord(ref _CpuCycle); } + } - private byte PullByteFromStack(ref ulong CpuCycle) - { - IncrementSP(); - IncrementCpuCycle(1); - byte b = ReadByteFromMemory(SP); - IncrementCpuCycle(1); - return b; - } + private uint AddrAbsolute() + { + return FetchWord(ref _CpuCycle); + } - private void PushByteToStack(byte b,ref ulong CpuCycle) - { - WriteByteToMemory(b, SP); - IncrementCpuCycle(1); - DecrementSP(); - IncrementCpuCycle(1); - - } + private byte PullByteFromStack(ref ulong CpuCycle) + { + IncrementSP(); + IncrementCpuCycle(1); + byte b = ReadByteFromMemory(SP); + IncrementCpuCycle(1); + return b; + } - public void Stop() - { - ExitRequested = true; - } + private void PushByteToStack(byte b,ref ulong CpuCycle) + { + WriteByteToMemory(b, SP); + IncrementCpuCycle(1); + DecrementSP(); + IncrementCpuCycle(1); + + } - //UT - private void SetZeroAndNegativeFlags(byte register) - { - flags["Z"] = (register == 0); - flags["N"] = (register & NegativeFlagBit) > 0; - OnFlagsUpdate?.Invoke(this, new CPUEventArgs(this)); - } + public void Stop() + { + ExitRequested = true; + } - private byte FetchByte(ref ulong CpuCycle) - { - byte data = Data[PC]; - IncrementPC(); - IncrementCpuCycle(1); - return data; - } + //UT + private void SetZeroAndNegativeFlags(byte register) + { + flags["Z"] = (register == 0); + flags["N"] = (register & NegativeFlagBit) > 0; + OnFlagsUpdate?.Invoke(this, new CPUEventArgs(this)); + } - private ushort FetchWord(ref ulong CpuCycle) - { - ushort LoByte = ReadByteFromMemory((ushort)PC); - PC++; - ushort HiByte = (ushort)(ReadByteFromMemory((ushort)PC) << 8); + private byte FetchByte() + { + byte data = Data[PC]; + IncrementPC(); + IncrementCpuCycle(1); + return data; + } - IncrementCpuCycle(2); + private ushort FetchWord(ref ulong CpuCycle) + { + ushort LoByte = ReadByteFromMemory((ushort)PC); + PC++; + ushort HiByte = (ushort)(ReadByteFromMemory((ushort)PC) << 8); - return LoByte |= HiByte; - } + IncrementCpuCycle(2); - public void WriteByteToMemory(byte b,ushort address) - { - Data[address] = b; - OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); - } + return LoByte |= HiByte; + } - private byte ReadByteFromMemory(ushort address) - { - return Data[address]; - } + public void WriteByteToMemory(byte b,ushort address) + { + Data[address] = b; + OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); + } - private ushort ReadWordFromMemory(ushort address) - { - //ushort tmpPC = ReadByteFromMemory(ResetVector); - //ResetVector++; - //tmpPC |= (ushort)(ReadByteFromMemory(ResetVector) << 8); + private byte ReadByteFromMemory(ushort address) + { + return Data[address]; + } + private ushort ReadWordFromMemory(ushort address) + { + //ushort tmpPC = ReadByteFromMemory(ResetVector); + //ResetVector++; + //tmpPC |= (ushort)(ReadByteFromMemory(ResetVector) << 8); - ushort LoByte = ReadByteFromMemory(address); - address++; - ushort HiByte = (ushort)(ReadByteFromMemory(address) <<8); - - return LoByte |= HiByte; - } - // Stackpointer SP - //UT - private void SetSP(ushort value) - { - SP = value; - OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); - } - private void IncrementSP() - { - SP++; - OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); - } - private void DecrementSP() - { - SP--; - OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); - } + ushort LoByte = ReadByteFromMemory(address); + address++; + ushort HiByte = (ushort)(ReadByteFromMemory(address) <<8); + + return LoByte |= HiByte; + } - private void IncrementCpuCycle(ulong count) - { - _CpuCycle += count; - OnCpuCycleIncrement?.Invoke(this, new CPUEventArgs(this)); - } + // Stackpointer SP + //UT + private void SetSP(ushort value) + { + SP = value; + OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); + } + private void IncrementSP() + { + SP++; + OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); + } + private void DecrementSP() + { + SP--; + OnStackPointerUpdate?.Invoke(this, new CPUEventArgs(this)); + } - private void ResetCpuCycle() - { - _CpuCycle =0; - OnCpuCycleIncrement?.Invoke(this, new CPUEventArgs(this)); - } + private void IncrementCpuCycle(ulong count) + { + _CpuCycle += count; + OnCpuCycleIncrement?.Invoke(this, new CPUEventArgs(this)); + } - // Programcounter PC - //UT - public void SetPC(uint value) - { - PC = value; - OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); - } - public void IncrementPC() - { - PC++; - OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); - } - public void DecrementPC() + private void ResetCpuCycle() + { + _CpuCycle =0; + OnCpuCycleIncrement?.Invoke(this, new CPUEventArgs(this)); + } + + // Programcounter PC + //UT + public void SetPC(uint value) + { + PC = value; + OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); + } + public void IncrementPC() + { + PC++; + OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); + } + public void DecrementPC() + { + PC--; + OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); + } + + //UT + public void SetRegister(string regname, byte value) + { + switch (regname) { - PC--; - OnProgramCounterUpdate?.Invoke(this, new CPUEventArgs(this)); + case "A": + A = value; + break; + case "X": + X = value; + break; + case "Y": + Y = value; + break; + default: + break; } - - //UT - public void SetRegister(string regname, byte value) + OnRegisterUpdate?.Invoke(this, new CPUEventArgs(this)); + } + //UT + public void ResetMemory() + { + for (int i = 0; i < MAX_MEM; i++) { - switch (regname) - { - case "A": - A = value; - break; - case "X": - X = value; - break; - case "Y": - Y = value; - break; - default: - break; - } - OnRegisterUpdate?.Invoke(this, new CPUEventArgs(this)); + Data[i] = 0x00; } - //UT - public void ResetMemory() - { - for (int i = 0; i < MAX_MEM; i++) - { - Data[i] = 0x00; - } - SetVectors(); + SetVectors(); - OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); - } - public byte[] ReadMemory() - { - return Data; - } + OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); + } + public byte[] ReadMemory() + { + return Data; + } - internal void UpdateMemoryRange(byte[] data, int startAddress) + internal void UpdateMemoryRange(byte[] data, int startAddress) + { + for (int i = 0; i < data.Length; i++) { - for (int i = 0; i < data.Length; i++) - { - Memory[startAddress + i] = data[i]; - } - - OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); + Memory[startAddress + i] = data[i]; } + + OnMemoryUpdate?.Invoke(this, new CPUEventArgs(this)); } +} - public class CPUEventArgs : EventArgs +public class CPUEventArgs : EventArgs +{ + CPU cpu = new CPU(); + + public string Message { get; set; } + public byte[] Memory { get; set; } + public uint PC { get; set; } + public ushort SP { get; set; } + public byte A { get; set; } + public byte X { get; set; } + public byte Y { get; set; } + public ulong Cycles { get; set; } + public IDictionary Flags { get; set; } + + public CPUEventArgs(CPU cpu) { - CPU cpu = new CPU(); - - public string Message { get; set; } - public byte[] Memory { get; set; } - public uint PC { get; set; } - public ushort SP { get; set; } - public byte A { get; set; } - public byte X { get; set; } - public byte Y { get; set; } - public ulong Cycles { get; set; } - public IDictionary Flags { get; set; } - - public CPUEventArgs(CPU cpu) - { - this.cpu = cpu; - SetProperties(); - } + this.cpu = cpu; + SetProperties(); + } - - private void SetProperties() - { - Memory = cpu.ReadMemory(); - PC = cpu.PC; - SP = cpu.SP; - A = cpu.A; - X = cpu.X; - Y = cpu.Y; - Flags = cpu.flags; - Cycles = cpu._CpuCycle; - } - + private void SetProperties() + { + Memory = cpu.ReadMemory(); + PC = cpu.PC; + SP = cpu.SP; + A = cpu.A; + X = cpu.X; + Y = cpu.Y; + Flags = cpu.flags; + Cycles = cpu._CpuCycle; } + + } diff --git a/CPU_emuTests/CPU_Tests.cs b/CPU_emuTests/CPU_Tests.cs index 0764f30..519819b 100644 --- a/CPU_emuTests/CPU_Tests.cs +++ b/CPU_emuTests/CPU_Tests.cs @@ -137,7 +137,7 @@ public void FetchByte_Test() cpu.WriteByteToMemory(value, 200); cpu.SetPC(200); - Assert.That(GetPrivateMethod("FetchByte",cpu).Invoke(cpu,new object[] {cyc}), Is.EqualTo(0xff)); + Assert.That(GetPrivateMethod("FetchByte", cpu).Invoke(cpu,null), Is.EqualTo(0xff)); Assert.That(cpu.PC, Is.EqualTo(201)); }