//Note to self: do not use left shift to remove left bits since operands get converted to ints first public static void Main(string[] args) { CommandLine.Parser.Default.ParseArguments <GraphicUserInterfaceOptions, CommandLineOptions>(args) .MapResult( (GraphicUserInterfaceOptions options) => GraphicUserInterfaceMain(options), (CommandLineOptions options) => CommandLineMain(options), err => // Fall back to GUI directly if not parsed. { if (Environment.UserInteractive) { Console.WriteLine("No mode specified or invalid options occured, fallback to GUI mode..."); Console.WriteLine("Press Enter to continue"); Console.ReadLine(); var lc3 = new LC3(); var assembly = new Assembler(lc3); assembly.AssembleLines(File.ReadAllText("trap.asm")); string program = @"C:\Users\alexm\Downloads\encoder.asm"; new Emulator(lc3, assembly, program).Start(); return(0); } else { Console.WriteLine("No mode specified or invalid options occured, fallback to CLI mode..."); Console.WriteLine("Press Enter to continue"); Console.ReadLine(); CommandLineMain(new CommandLineOptions()); // TODO (3TUSK): Provide fallback parameters return(0); } } ); }
public Terminal(LC3 lc3, Assembler assembly, string fixedInput = null, string fixedOutput = null) { this.lc3 = lc3; this.assembly = assembly; this.fixedInput = fixedInput; this.fixedOutput = fixedOutput; }
public void StateMachineTest1() { var fsm = new LC3(); Assert.Equals(fsm.control.pc, 0x3000); fsm.Execute(0b0001_001_001_1_01111); // ADD R1, R1, #15 Assert.Equals(fsm.processing.registers[1], 15); Assert.Equals(fsm.control.pc, 0x3001); Assert.False(fsm.processing.N); Assert.False(fsm.processing.Z); Assert.True(fsm.processing.P); fsm.Execute(0b0011_001_000111101); // ST R1, LABEL_AT_X3040 Assert.Equals(fsm.memory.Read(0x3040), 0x000F); // 0x000F == 15 }
private static int GraphicUserInterfaceMain(GraphicUserInterfaceOptions options) { if (!Environment.UserInteractive) { Console.Error.WriteLine("It looks like you are attempting running LC-Sharp GUI mode in a headless environment."); Console.Error.WriteLine("Naturally, it does not make much senses. LC-Sharp will quit now to prevent further errors."); return(-1); } LC3 lc3 = new LC3(); Assembler assembly = new Assembler(lc3); assembly.AssembleLines(File.ReadAllLines("trap.asm")); assembly.AssembleLines(File.ReadAllLines(options.program)); new Emulator(lc3, assembly).Start(); return(0); }
private static int CommandLineMain(CommandLineOptions options) { var lc3 = new LC3(); var assembly = new Assembler(lc3); assembly.AssembleLines(File.ReadAllLines("trap.asm")); if (options.program != null) { assembly.AssembleToPC(File.ReadAllLines(options.program)); } string input = options.input != null?File.ReadAllText(options.input) : null; string output = options.output != null?File.ReadAllText(options.output).Replace("\r", null) : null; Console.WriteLine("Assembly successful. Launching machine."); Console.CursorVisible = true; new Terminal(lc3, assembly, input, output).Start(); return(0); }
private static void RunLC3(Options options) { var lc3 = new LC3(); var program = new NeoAssembler(new Parser().ParseFile(options.program)).Assemble(); foreach (var mem in program) { lc3.memory.Write(mem.Key, mem.Value); } while (lc3.Active) { lc3.Execute(); } if (lc3.status == LC3.Status.ERROR) { Console.Error.Write("Program unexpectedly exits"); } }
public Processing(LC3 lc3) { this.lc3 = lc3; }
public void InitWindow() { //Console.WriteLine("Program loaded. Press Enter to continue."); //Console.ReadLine(); Console.SetWindowSize(150, 60); window = new Window(new Rect(0, 0, 150, 60), "LC-Sharp"); { TextField fileField = new TextField(0, 0, 56, programFile ?? ""); window.Add(fileField); bool loading = false; var loadingLabel = new Label(56, 0, "Loading..."); window.Add(loadingLabel); Button loadButton = new Button(56, 0, "Load"); loadButton.Clicked += LoadProgramClick; window.Add(loadButton); var lastLoad = programFile != null?File.GetLastWriteTimeUtc(programFile) : DateTime.Now; bool autoReload = false; CheckBox autoReloadBox = new CheckBox(66, 0, "Auto Reload", false); autoReloadBox.Toggled += b => { if (b) { autoReload = false; } else { autoReload = true; Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(1000), m => { if (autoReload) { if (!loading && fileField.Text.Any() && File.Exists(fileField.Text.ToString())) { var time = File.GetLastWriteTimeUtc(fileField.Text.ToString()); if (time != lastLoad) { lastLoad = time; LoadProgramClick(); } } return(true); } else { return(false); } }); } }; window.Add(autoReloadBox); var clearOutput = new Button(88, 0, "Clear Output"); clearOutput.Clicked += () => { output.Text = ""; }; window.Add(clearOutput); if (programFile != null) { Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(0), m => { LoadProgramClick(); return(false); }); } void LoadProgramClick() { if (loading) { return; } loading = true; fileField.SetFocus(); loadingLabel.Visible = true; loadButton.Visible = false; new Thread(() => { try { LoadProgram(); } catch (Exception e) { WriteConsole(e.Message); } finally { loadingLabel.Visible = false; loadButton.Visible = true; loading = false; } }).Start(); } void LoadProgram() { var programFile = fileField.Text.ToString(); var program = File.ReadAllText(programFile); var lc3 = new LC3(); var assembly = new Assembler(lc3); assembly.AssembleLines(File.ReadAllText("trap.asm")); assembly.AssembleLines(program); //output.Text = ""; //input.Text = ""; //console.Text = ""; //assembleDebugField.Text = ""; //assembleDebugField.Text = program; this.lc3 = lc3; this.assembly = assembly; this.programFile = programFile; UpdateRegisterView(); UpdateHighlight(); UpdateIOView(); UpdateInstructionsView(); ResetStatus(); WriteConsole($"[{DateTime.Now.ToShortTimeString()}] Loaded file {programFile}"); } } int x = 0; int width = 56; instructions = new ScrollView(new Rect(0, 0, width - 2, 40)) { ContentSize = new Size(30, 0xFFFF) }; instructions.ShowVerticalScrollIndicator = true; instructions.MouseClick += _ => UpdateInstructionsView(); UpdateInstructionsView(); { Window w = new Window(new Rect(x, 1, width, 42), "Instructions"); w.Add(instructions); window.Add(w); } { var w = new Window(new Rect(x, 43, width + 32, 15), "Assemble"); assembleDebugField = new TextView(new Rect(0, 0, 62, 13)); /* * try { * var program = File.ReadAllText(programFile); * assembleDebugField.Text = program.Replace("\r", null); * } catch (Exception e) { * assembleDebugField.Text = ""; * } */ assembleDebugField.Text = ""; w.Add(assembleDebugField); window.Add(w); } registerLabels = new Label[8]; for (int i = 0; i < 8; i++) { //We need to make the label 30-wide on init because it won't expand Label l = new Label(1, i, $"R{i}".PadRight(30)); registerLabels[i] = l; } ccLabel = new Label(1, 9, "CC".PadRight(30)); pcLabel = new Label(1, 11, "PC".PadRight(30)); irLabel = new Label(1, 12, "IR".PadRight(30)); x += width; width = 32; { Window w = new Window(new Rect(x, 1, width, 16), "Registers"); w.Add(registerLabels); w.Add(ccLabel); w.Add(pcLabel, irLabel); window.Add(w); } Window labelsView = new Window(new Rect(x, 17, width, 16), "Labels"); labels = new TextView(new Rect(0, 0, width - 2, 14)) { Text = "", ReadOnly = true }; labelsView.Add(labels); window.Add(labelsView); status = new Label(new Rect(x, 33, 16, 4), "Status"); ResetStatus(); window.Add(status); runAllButton = new Button(x, 34, "Run All"); runAllButton.Clicked += ClickRunAll; runStepOnceButton = new Button(x, 35, "Run Step Once"); runStepOnceButton.Clicked += ClickRunStepOnce; runStepOverButton = new Button(x, 36, "Run Step Over"); runStepOverButton.Clicked += ClickRunStepOver; setPCfield = new TextField(x + 22, 37, 9, ""); setPCbutton = new Button(x, 37, "Set PC"); setPCbutton.Clicked += SetPC; void SetPC() { try { string s = setPCfield.Text.ToString().Trim().ToLower(); short pc; if (s.StartsWith("0x")) { pc = short.Parse(s.Substring(2), System.Globalization.NumberStyles.HexNumber); } else { pc = short.Parse(s.Substring(1)); } if (pc == lc3.control.pc) { return; } lc3.control.setPC(pc); WriteConsole($"PC set to {pc.ToHexString()}"); lc3.Unhalt(); UpdateRegisterView(); UpdateHighlight(); ResetStatus(); } catch (Exception e) { WriteConsole(e.Message); } } setScrollField = new TextField(x + 22, 38, 9, ""); setScrollButton = new Button(x, 38, "Set Scroll"); setScrollButton.Clicked += SetScroll; void SetScroll() { try { string s = setScrollField.Text.ToString().Trim().ToLower(); short pc; if (s.StartsWith("0x")) { pc = short.Parse(s.Substring(2), System.Globalization.NumberStyles.HexNumber); } else { pc = short.Parse(s.Substring(1)); } instructions.ContentOffset = new Point(0, pc - instructions.Bounds.Height / 2); UpdateInstructionsView(); } catch (Exception e) { WriteConsole(e.Message); } } assembleDebugButton = new Button(x, 39, "Assemble at PC"); assembleDebugButton.Clicked += AssembleDebug; void AssembleDebug() { try { //assembly.AssembleToPC(assembleDebugField.Text.ToString().Replace("\r", "").Split('\n')); //Create a new assembler so we can redefine labels new Assembler(lc3).AssembleToPC(assembleDebugField.Text.ToString().Replace("\r", "").Split('\n')); instructions.ContentOffset = new Point(0, lc3.control.pc - instructions.Bounds.Height / 2); UpdateInstructionsView(); WriteConsole("Debug code assembled successfully."); } catch (Exception e) { WriteConsole(e.Message); } } window.Add(runAllButton, runStepOnceButton, runStepOverButton, setPCbutton, setPCfield, setScrollButton, setScrollField, assembleDebugButton); x += width; width = 58; { var w = new Window(new Rect(x, 1, width, 16), "Output"); output = new TextView(new Rect(0, 0, width - 2, 14)); output.Text = ""; output.ReadOnly = true; w.Add(output); window.Add(w); } { var w = new Window(new Rect(x, 17, width, 16), "Input"); input = new TextView(new Rect(0, 0, width - 2, 14)); input.Text = ""; w.Add(input); window.Add(w); } { var w = new Window(new Rect(x, 33, width, 25), "Console"); console = new TextView(new Rect(0, 0, width - 2, 24)); console.Text = ""; console.ReadOnly = true; w.Add(console); window.Add(w); } UpdateRegisterView(); UpdateHighlight(); UpdateIOView(); }
public Emulator(LC3 lc3, Assembler assembly, string programFile = "") { this.lc3 = lc3; this.assembly = assembly; this.programFile = programFile; }
public Control(LC3 lc3) { this.lc3 = lc3; pc = 0x3000; ir = 0; }
private Dictionary <short, short> mem; //Lazily initialized memory (we only create entries right when we set or get) public Memory(LC3 lc3) { this.lc3 = lc3; mem = new Dictionary <short, short>(); }