public Simulator(ConnectionSetup previous) { this.connectionSetup = previous; this.simulated_program = null; InitializeComponent(); this.programState.Text = ""; this.Icon = Properties.Resources.rgb; }
public void updateProgram(byte[] program_bytes) { this.inst_list = new InstructionList(program_bytes); }
public void RefreshSimulation(SimulatorComms comms) { if (this.simulated_program != null) { long ticks = DateTime.Now.Ticks - this.start_time; long milliseconds = ticks / TimeSpan.TicksPerMillisecond; int sim_time = (int)milliseconds; int size = this.simulated_program.contents.Count(); if ((this.program_time + 120000) < sim_time) { // clock skew - reset the program this.program_time = 0; this.start_time = DateTime.Now.Ticks; this.program_counter = 0; } while (this.program_time < sim_time) { // run forwards until the program time matches the simulator time if (this.program_counter >= size) { this.program_counter = 0; // loop at end of program } Instruction inst = this.simulated_program.contents[this.program_counter]; int end_time = inst.getTime() + this.program_time; bool commit = true; switch (inst.t) { case InstructionType.InstructionSetDisplay: this.setDisplay(inst.value); break; case InstructionType.InstructionTransition: if (end_time < sim_time) { // Running behind. Apply this instruction immediately. this.r = inst.r; this.g = inst.g; this.b = inst.b; this.setColour(this.r, this.g, this.b); } else { // Transition int rS = this.r, gS = this.g, bS = this.b; int rT = inst.r, gT = inst.g, bT = inst.b; int tD = (int)(sim_time - this.program_time); int tI = (int)(end_time - this.program_time); byte r = linear(rS, rT, tD, tI); byte g = linear(gS, gT, tD, tI); byte b = linear(bS, bT, tD, tI); this.setColour(r, g, b); commit = false; } break; default: break; } if (commit) { // Go to next instruction this.program_counter++; this.program_time = end_time; } else { // Need to wait for this instruction to complete this.programState.Text = "Inst " + (this.program_counter + 1) + " of " + size + ": " + inst.ToString(); break; } } } while (true) { Command c = comms.SimulatorGetCommand(); Reply r; switch (c.t) { case CommandType.CommandNone: return; case CommandType.CommandConnect: r = new Reply(); r.red = r.green = r.blue = 0x20; r.t = ReplyType.ReplyConnected; comms.SimulatorSendReply(r); for (int i = 0; i < Comms.num_programs; i++) { r = new Reply(); r.program_number = i; r.program_bytes = readProgram(i); r.t = ReplyType.ReplyProgram; comms.SimulatorSendReply(r); } r = new Reply(); r.errorCode = "Simulated mode"; r.t = ReplyType.ReplyMsg; comms.SimulatorSendReply(r); this.display.Text = "C"; this.Show(); break; case CommandType.CommandSetColour: this.simulated_program = null; this.setColour(c.red, c.green, c.blue); this.r = c.red; this.g = c.green; this.b = c.blue; this.programState.Text = ""; break; case CommandType.CommandGetColour: this.simulated_program = null; r = new Reply(); r.red = this.r; r.green = this.g; r.blue = this.b; r.t = ReplyType.ReplyGotColour; comms.SimulatorSendReply(r); break; case CommandType.CommandSetDisplay: this.simulated_program = null; setDisplay(c.value); this.programState.Text = ""; break; case CommandType.CommandExit: this.simulated_program = null; break; case CommandType.CommandRunEEPROMProgram: this.simulated_program = new InstructionList(readProgram(c.value)); startProgram(comms, "" + c.value); break; case CommandType.CommandRunTemporaryProgram: this.simulated_program = new InstructionList(c.program_bytes); startProgram(comms, "(temporary)"); break; case CommandType.CommandSaveEEPROMProgram: writeProgram(c.program_number, c.program_bytes); r = new Reply(); r.t = ReplyType.ReplyProgram; r.program_number = c.program_number; r.program_bytes = readProgram(c.program_number); comms.SimulatorSendReply(r); r = new Reply(); r.errorCode = "Written to simulated EEPROM"; r.t = ReplyType.ReplyMsg; comms.SimulatorSendReply(r); break; } } }
private void startProgram(SimulatorComms comms, string name) { Reply r; this.start_time = DateTime.Now.Ticks; this.program_time = 0; this.program_counter = 0; if (this.simulated_program.contents.Count() == 0) { r = new Reply(); r.errorCode = "Program " + name + " contains no instructions."; r.t = ReplyType.ReplyMsg; comms.SimulatorSendReply(r); this.simulated_program = null; } else if (this.simulated_program.end_time <= 0) { r = new Reply(); r.errorCode = "Program " + name + " has no running time."; r.t = ReplyType.ReplyMsg; comms.SimulatorSendReply(r); this.simulated_program = null; } else { r = new Reply(); r.errorCode = "Program " + name + " simulating..."; r.t = ReplyType.ReplyMsg; comms.SimulatorSendReply(r); } this.programState.Text = r.errorCode; }
private void checkProgramThenDoSomething(ModeType mode) { InstructionList copy_inst_list = new InstructionList(); foreach (InstructionEditor inst_ed in this.instructions.Items) { copy_inst_list.contents.Add(inst_ed.inst); } copy_inst_list.name = this.namebox.Text; // create a programming command Command c = new Command(); c.program_bytes = new byte[Comms.program_size]; // translate the program to bytes int rc = copy_inst_list.encode(c.program_bytes); copy_inst_list.updateProperties(); string err = ""; if (rc == InstructionList.program_too_big) { err = "This program is too large: there are too many instructions."; } else if (rc <= 0) { err = "This program contains no instructions: add at least one."; } else if (copy_inst_list.end_time <= 0) { err = "This program has no running time. It must contain some delays."; } switch (mode) { case ModeType.RunMode: // Start running the program if (err != "") { MessageBox.Show(err, "Run Program"); } else { c.t = CommandType.CommandRunTemporaryProgram; this.comms.SendCommand(c); SetProgram(copy_inst_list, this.program_number); buttonsUpdate(); } break; case ModeType.CheckMode: // Just checking, no other action if (err != "") { this.properties.Text = err; } break; case ModeType.SaveMode: // Are you sure you want to save? if (err != "") { MessageBox.Show(err, "Save Program"); } else { DialogResult dialogResult = MessageBox.Show("Really store program " + this.program_number + " in memory?", "Save Program", MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { c.t = CommandType.CommandSaveEEPROMProgram; c.program_number = this.program_number; this.comms.SendCommand(c); this.Hide(); SetProgram(copy_inst_list, this.program_number); buttonsUpdate(); } } break; case ModeType.ExportMode: if (err != "") { MessageBox.Show(err, "Export Program"); } else { SaveFileDialog theDialog = new SaveFileDialog(); theDialog.Title = "Export Light Program File"; theDialog.Filter = save_filter; theDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); theDialog.FileName = this.save_filename; if (theDialog.ShowDialog() == DialogResult.OK) { this.save_filename = theDialog.FileName; ProgramIO.writeProgram(this.save_filename, c.program_bytes); } } break; } }
public void SetProgram(InstructionList inst_list, int program_number) { this.transition.Hide(); // make a copy of the program byte[] tmp = new byte[Comms.program_size]; inst_list.encode(tmp); InstructionList copy_inst_list = new InstructionList(tmp); // update the GUI with the details this.instructions.Items.Clear(); foreach (Instruction inst in copy_inst_list.contents) { this.instructions.Items.Add(new InstructionEditor (inst)); } this.instructions.Refresh(); this.program_number = program_number; this.namebox.Text = copy_inst_list.name; this.properties.Text = copy_inst_list.getProperties(); this.Text = "Edit Program " + program_number; buttonsUpdate(); }