/// <summary>
 /// This function executes an instruction by calling its delegate function
 /// </summary>
 public void ExecuteInstruction()
 {
     try
     {
         Console.WriteLine("Executing instruction");
         logicalAddress = currentIndex * 4;
         Console.WriteLine(logicalAddress);
         currentInstruction =
             program.Instructions.Where(x => x.LogicalAddress == logicalAddress).FirstOrDefault();
         if (currentInstruction != null)
         {
             if (CurrentInstruction.Execute == null)
             {
                 BindInstructionDelegates(ref program);
             }
             if (currentInstruction.Opcode == (int)EnumOpcodes.JMP ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JEQ ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JNE ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JGT ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JGE ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JLT ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JLE ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JNZ ||
                 currentInstruction.Opcode == (int)EnumOpcodes.JZR)
             // if we are executing a jump instruction do not increment the program counter
             {
                 //program.Instructions.ElementAt(currentIndex).Execute();
                 currentInstruction.Execute();
             }
             else // otherwise increment the program counter
             {
                 //program.Instructions.ElementAt(currentIndex).Execute();
                 currentInstruction.Execute();
                 currentIndex++;
             }
             SpecialRegister.FindSpecialRegister("PC")
             .SetRegisterValue(currentInstruction.LogicalAddress, EnumOperandType.VALUE);
             SpecialRegister.FindSpecialRegister("IR")
             .SetRegisterValue(currentInstruction.InstructionString, EnumOperandType.VALUE);
             SpecialRegister.FindSpecialRegister("MDR")
             .SetRegisterValue(currentInstruction.InstructionString, EnumOperandType.VALUE);
             SpecialRegister.FindSpecialRegister("MAR")
             .SetRegisterValue(currentInstruction.PhysicalAddress, EnumOperandType.VALUE);
             if (currentIndex == program.Instructions.Count)
             {
                 Done = true;
             }
             Thread.Sleep(clockSpeed);
         }
         else
         {
             Done = true;
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.StackTrace);
     }
 }
 /// <summary>
 /// Constructor for execution unit that starts executing from the beginning of the program
 /// </summary>
 /// <param name="program"> the program to execute </param>
 /// <param name="clockSpeed"> the clock speed of the CPU </param>
 public ExecutionUnit(SimulatorProgram program, int clockSpeed)
 {
     try
     {
         this.program       = program;
         this.clockSpeed    = clockSpeed;
         currentIndex       = 0;
         logicalAddress     = currentIndex * 4;
         currentInstruction =
             program.Instructions.Where(x => x.LogicalAddress == logicalAddress).FirstOrDefault();
         stop = false;
         done = false;
         SpecialRegister.FindSpecialRegister("BR").SetRegisterValue(program.BaseAddress, EnumOperandType.ADDRESS);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.StackTrace);
         MessageBox.Show("Please load a program before running the CPU");
     }
 }