public Instruction(VirtualMachine virtualMachine) { machine = virtualMachine; Left = new Operand(machine); Right = new Operand(machine); }
private static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, e) => DumpError((Exception)e.ExceptionObject); var speed = VmSpeed.Medium; var running = true; Config = ConfigFile.Load("VmConfig.xml"); TextDisplay.Initialize(CharWidth, CharHeight); window = new RenderWindow(new VideoMode(200 * CharWidth, 81 * CharHeight), "", Styles.Close); window.SetFramerateLimit(Config.Framerate); window.Closed += (sender, e) => window.Close(); display = new TextDisplay(200, 80); memory = new Memory(); machine = new VirtualMachine(memory); statusDisplay = new TextDisplay(200, 1); machine.AttachDevice(new Devices.Motherboard(machine, display)); var devMap = new Dictionary<string, Type>() { { "Controller", typeof(Devices.Controller) }, { "Keyboard", typeof(Devices.Keyboard) }, { "HardDrive", typeof(Devices.HardDrive) }, { "Speaker", typeof(Devices.Speaker) }, }; foreach (var devConfig in Config.Devices) { var devName = devConfig.Name.ToString(); if (!devMap.ContainsKey(devName)) continue; var devEnabledAttr = devConfig.Attribute("Enabled"); var devEnabled = devEnabledAttr == null || devEnabledAttr.Value.ToLower() == "true"; if (!devEnabled) continue; var device = (Device)Activator.CreateInstance(devMap[devName], window, machine, devConfig); machine.AttachDevice(device); } var file = Config.DefaultFile; if (args.Length > 0) file = args[0]; if (error == null) Load(file); window.KeyPressed += (sender, eventArgs) => { if (eventArgs.Code == Config.Pause) running = !running; if (eventArgs.Code == Config.ChangeSpeed) speed = (VmSpeed)(((int)speed + 1) % 4); if (eventArgs.Code == Config.Reload) Load(file); }; var previousSteps = new LinkedList<int>(); var ipX = 0; var ipY = 0; var spX = 0; var spY = 0; while (window.IsOpen()) { window.DispatchEvents(); #region Stepping var requestedSteps = 0; var steps = 0; switch (speed) { case VmSpeed.Slow: requestedSteps = Config.Slow; break; case VmSpeed.Medium: requestedSteps = Config.Medium; break; case VmSpeed.Fast: requestedSteps = Config.Fast; break; case VmSpeed.Unlimited: requestedSteps = int.MaxValue; // "unlimited" break; } if (running && error == null) { try { var stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds < (0.95 / Config.Framerate)) { if (steps >= requestedSteps) break; for (var i = 0; i < 100; i++, steps++) { machine.Step(); } } } catch (VmException e) { error = e.Message; } } previousSteps.AddLast(steps); if (previousSteps.Count > Config.Framerate) previousSteps.RemoveFirst(); #endregion display.DrawImage(0, 0, memory); #region IP and SP markers display.Set(ipX, ipY, Character.Create(background: 0)); display.Set(spX, spY, Character.Create(background: 0)); var ip = machine.IP / 2; ipX = ip % 200; ipY = ip / 200; var sp = machine.SP / 2; spX = sp % 200; spY = sp / 200; if (ipY < 80) display.Set(ipX, ipY, Character.Create(background: 255)); if (spY < 80) display.Set(spX, spY, Character.Create(background: 255)); #endregion var statusString = "Paused"; if (error != null) statusString = string.Format("ERROR: {0}", error); else if (machine.Flags.HasFlag(VirtualMachine.Flag.Trap)) statusString = "Trapped"; else if (running) statusString = string.Format("Running: {0} instructions per second ({1})", previousSteps.Sum(), speed); statusDisplay.Clear(Character.Create(' ')); statusDisplay.DrawText(0, 0, statusString, Character.Create(foreground: 255)); display.Draw(window, new Vector2f(0, 0)); statusDisplay.Draw(window, new Vector2f(0, 80 * CharHeight)); window.Display(); } machine.Dispose(); }
public abstract void Attach(VirtualMachine machine);
public Operand(VirtualMachine machine) { this.machine = machine; }