/// <summary> /// Starts with the CPU execution. /// </summary> public void Execute() { CPUExecution executionContext = CPUExecution.MORE_INSTRUCTIONS_AVAILABLE; string OutputPortC = string.Empty; string OutputPortD = string.Empty; while (executionContext == CPUExecution.MORE_INSTRUCTIONS_AVAILABLE) { executionContext = ExecuteNextInstruction(out OutputPortC, out OutputPortD); } }
public static void Main(string[] args) { CPUExecution context = CPUExecution.MORE_INSTRUCTIONS_AVAILABLE; string outC, outD; char keyPressed = ' '; // Initialize the BIOS bios = new BIOS(rootFolder + "VirtualDisk.img"); // Load the binary code and initialize the CPU LoadBinaryCode(); while (context != CPUExecution.FINISHED) { // Execute the next instruction context = cpu.SingleStep(out outC, out outD); if (context == CPUExecution.IN_A) { // Pass the read character from the console into the CPU Input Port A... cpu.XL.SetBits(Convert.ToByte(keyPressed)); } if (context == CPUExecution.IN_B) { ConsoleKeyInfo key = Console.ReadKey(true); keyPressed = key.KeyChar; // Set the Ready Bit on Input Port B when we have read the character from the console cpu.XL.SetBits(1); } if (context == CPUExecution.INTERRUPT) { // We have triggered a software based interrupt... switch (cpu.XL.GetInt()) { case 1: { // Interrupt 1 is used for accessing hard disks HandleHardDiskInterrupt(); break; } default: throw new ArgumentException("Invalid Interrupt Number!"); } // After we have handled the interrupt, we continue program execution by incrementing the Program Counter... cpu.ProgramCounter.Increment(); continue; } if (outC != string.Empty) { Console.Write(Convert.ToChar(Helper.GetByte(outC))); } } Console.WriteLine(); Console.WriteLine("Done"); Console.ReadLine(); }
private void ExecuteNextAssemblyInstruction() { string OutputPortC = string.Empty; string OutputPortD = string.Empty; bool incrementIndex = true; instructionsExecuted++; if (lstAssembly.SelectedItems.Count == 0) { cpu.SingleStep(out OutputPortC, out OutputPortD); UpdateUI(OutputPortC, OutputPortD); lblCPUState.Text = "RUNNING..."; lblCPUState.ForeColor = Color.Green; // Highlight the first assembly instruction in the ListView. lstAssembly.FocusedItem = lstAssembly.Items[0]; lstAssembly.Items[0].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } else { CPUExecution executionContext = cpu.SingleStep(out OutputPortC, out OutputPortD); UpdateUI(OutputPortC, OutputPortD); if (executionContext == CPUExecution.MORE_INSTRUCTIONS_AVAILABLE) { if (txtInstruction.Text == "JMP" || txtInstruction.Text == "JZ" || txtInstruction.Text == "JNZ") { incrementIndex = false; } // Highlight the next assembly instruction in the ListView if (highlightInstruction) { lstAssembly.Items[indexForNextInstruction].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } lblCPUState.Text = "RUNNING..."; lblCPUState.ForeColor = Color.Green; } else if (executionContext == CPUExecution.BREAKPOINT_HIT) { // Highlight the current assembly instruction in the ListView if (highlightInstruction) { lstAssembly.Items[indexForNextInstruction].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } lblCPUState.Text = "BREAKPOINT HIT!"; lblCPUState.ForeColor = Color.Red; // Disable automatic CPU execution // if (executionTimer.Enabled) // executionTimer.Enabled = false; if (microTimer.Enabled) { microTimer.Enabled = false; } } else if (executionContext == CPUExecution.IN_A) { // Highlight the current assembly instruction in the ListView if (highlightInstruction) { lstAssembly.Items[indexForNextInstruction].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } lblCPUState.Text = "IN A!"; lblCPUState.ForeColor = Color.Red; // Disable automatic CPU execution // if (executionTimer.Enabled) // executionTimer.Enabled = false; if (microTimer.Enabled) { microTimer.Enabled = false; } } else if (executionContext == CPUExecution.IN_B) { // Highlight the current assembly instruction in the ListView if (highlightInstruction) { lstAssembly.Items[indexForNextInstruction].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } lblCPUState.Text = "IN B!"; lblCPUState.ForeColor = Color.Red; // Disable automatic CPU execution // if (executionTimer.Enabled) // executionTimer.Enabled = false; if (microTimer.Enabled) { microTimer.Enabled = false; } } else if (executionContext == CPUExecution.FINISHED) { // Highlight the current assembly instruction in the ListView if (highlightInstruction) { lstAssembly.Items[indexForNextInstruction].Selected = true; lstAssembly.Select(); lstAssembly.EnsureVisible(0); lstAssembly.Items[lstAssembly.SelectedItems[0].Index].EnsureVisible(); } lblCPUState.Text = "FINISHED!"; lblCPUState.ForeColor = Color.Green; cmdExecute.Enabled = cmdSingleStep.Enabled = false; // Disable automatic CPU execution // if (executionTimer.Enabled) // executionTimer.Enabled = false; if (microTimer.Enabled) { microTimer.Enabled = false; } } } if (incrementIndex) { indexForNextInstruction++; } else { // Find the correct line for highlighting based on the new Program Counter value. // Used during jumps (conditional, unconditional). indexForNextInstruction = 0; foreach (ListViewItem item in lstAssembly.Items) { indexForNextInstruction++; if (item.SubItems[0].Text == txtProgramCounter.Text) { break; } } // Correct the index by 1 indexForNextInstruction--; } }