//KILL ME private void ComputeJump(MicroInstruction microInstruction) { string[] jumpStrings = microInstruction.RamificationConditionString.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (jumpStrings[0].Contains("NONE")) { microInstruction.RamificationConditionBinary = _microInstructionDictionaries.RamificationConditionDictionary[jumpStrings[0]]; if (jumpStrings.Length >= 2) { microInstruction.TrueOrFalseExecutionBinary = "1"; if (jumpStrings[1].Contains("STEP")) { microInstruction.IndexSelectionBinaryFirst = "111"; } else if (jumpStrings[1].Equals("JMP")) { byte microInstructionAddress = Convert.ToByte( _microInstructionTuples.Find(mistr => mistr.Item1.Equals(jumpStrings[2])).Item2); microInstruction.MicroAddressJumpBinaryFirst = Convert.ToString(microInstructionAddress, 2).PadLeft(8, '0'); microInstruction.MicroAddressJumpStringFirst = microInstructionAddress.ToString(); microInstruction.IndexSelectionBinaryFirst = "000"; // NONE } else if (jumpStrings[1].Equals("JMPI")) { string[] jumpTarget = jumpStrings[2].Split('+'); byte microInstructionAddress = Convert.ToByte( _microInstructionTuples.Find(mistr => mistr.Item1.Equals(jumpTarget[0])).Item2); microInstruction.MicroAddressJumpBinaryFirst = Convert.ToString(microInstructionAddress, 2).PadLeft(8, '0'); microInstruction.MicroAddressJumpStringFirst = microInstructionAddress.ToString(); microInstruction.IndexSelectionBinaryFirst = GetIndex(jumpTarget[1]); } } } else if (jumpStrings[0].Contains("IF")) { microInstruction.RamificationConditionBinary = _microInstructionDictionaries.RamificationConditionDictionary[jumpStrings[0] + " " + jumpStrings[1]]; // 0 Specifica TRUE(saltul se face pe conditie adev, adica f = 1) // 1 Specifica FALSE(saltul se face pe conditie falsa, adica f(neg) = 1 / f = 0) microInstruction.TrueOrFalseExecutionBinary = jumpStrings[1].StartsWith("N") ? "1" : "0"; microInstruction.TrueOrFalseExecutionString = microInstruction.TrueOrFalseExecutionBinary == "1" ? "false" : "true"; GetFirstOperand(microInstruction, jumpStrings, 2); GetSecondOperand(microInstruction, jumpStrings, 5); } }
private void GetSecondOperand(MicroInstruction microInstruction, string[] jumpStrings, int position) { if (jumpStrings[position].Equals("JMP")) { byte microInstructionAddress = Convert.ToByte( _microInstructionTuples.Find(mistr => mistr.Item1.Equals(jumpStrings[position + 1])).Item2); microInstruction.MicroAddressJumpBinarySecond = Convert.ToString(microInstructionAddress, 2).PadLeft(8, '0'); microInstruction.MicroAddressJumpStringSecond = microInstructionAddress.ToString(); } else if (jumpStrings[position].Equals("JMPI")) { string[] jumpTarget = jumpStrings[position + 1].Split('+'); byte microInstructionAddress = Convert.ToByte( _microInstructionTuples.Find(mistr => mistr.Item1.Equals(jumpTarget[0])).Item2); microInstruction.MicroAddressJumpBinarySecond = Convert.ToString(microInstructionAddress, 2).PadLeft(8, '0'); microInstruction.MicroAddressJumpStringSecond = microInstructionAddress.ToString(); microInstruction.IndexSelectionBinarySecond = GetIndex(jumpTarget[1]); } else if (jumpStrings[position].Equals("STEP")) { microInstruction.IndexSelectionBinarySecond = "111"; // STEP } }
private void OnMicrocodeSourceValueNeeded(object sender, DataGridViewCellValueEventArgs e) { if (e.RowIndex > 1024) { // Top of uCode memory, nothing to do. return; } DataGridView view = (DataGridView)sender; int bank = 0; switch ((string)view.Tag) { case "RAM0": bank = 0; break; case "RAM1": bank = 1; break; case "RAM2": bank = 2; break; default: throw new InvalidOperationException("Invalid view Tag for disassembly view."); } ushort address = (ushort)(e.RowIndex + (bank * 1024)); // Yes, switching on the Header Text seems clumsy and awful but this is // what WinForms has driven me to do. switch (((DataGridView)sender).Columns[e.ColumnIndex].HeaderText) { case "B": e.Value = GetMicrocodeBreakpoint(MicrocodeBank.RAM0 + bank, (ushort)(address % 1024)); break; case "Addr": e.Value = Conversion.ToOctal(e.RowIndex, 4); break; case "Word": e.Value = Conversion.ToOctal((int)UCodeMemory.UCodeRAM[address], 11); break; case "Disassembly": // TODO: should provide means to disassemble as specific task, not just Emulator. MicroInstruction instruction = new MicroInstruction(UCodeMemory.UCodeRAM[address]); e.Value = UCodeDisassembler.DisassembleInstruction(instruction, _system.CPU.CurrentTask.TaskType); break; } }
protected override void ExecuteSpecialFunction1Early(MicroInstruction instruction) { // // Based on readings of the below MRT microcode comment, the MRT keeps its wakeup // until it executes a BLOCK on Alto IIs. (i.e. no special wakeup handling at all.) // On Alto Is, this was accomplished by doing an MAR <- R37. // // "; This version assumes MRTACT is cleared by BLOCK, not MAR<- R37" // if (_systemType == SystemType.AltoI && instruction.F1 == SpecialFunction1.LoadMAR && _rSelect == 31) { BlockTask(); } base.ExecuteSpecialFunction1Early(instruction); }
public void Parse() { foreach (var microInstructionTuple in _microInstructionTuples) { var microInstruction = new MicroInstruction(); microInstruction.MicroInstructionString = microInstructionTuple.Item3; string[] microCommands = microInstructionTuple.Item3.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); microInstruction.SBUSSourceBinary = _microInstructionDictionaries.SBUSDictionary[microCommands[0]]; microInstruction.DBUSSourceBinary = _microInstructionDictionaries.DBUSDictionary[microCommands[1]]; microInstruction.ALUOperationBinary = _microInstructionDictionaries.ALUOperationDictionary[microCommands[2]]; microInstruction.RBUSDestinationBinary = _microInstructionDictionaries.RBUSDictionary[microCommands[3]]; microInstruction.OtherOperationsBinary = _microInstructionDictionaries.OtherOperationDictionary[microCommands[4]]; microInstruction.MemoryOperationsBinary = _microInstructionDictionaries.MemoryOperationDictionary[microCommands[5]]; microInstruction.SBUSSourceString = microCommands[0]; microInstruction.DBUSSourceString = microCommands[1]; microInstruction.ALUOperationString = microCommands[2]; microInstruction.RBUSDestinationString = microCommands[3]; microInstruction.OtherOperationsString = microCommands[4]; microInstruction.MemoryOperationsString = microCommands[5]; microInstruction.RamificationConditionString = microCommands[6]; ComputeJump(microInstruction); MicroInstructions.Add(microInstruction); //Console.WriteLine("Address: " + microInstructionTuple.Item2 + " " + microInstruction.GetMicroInstructionBinary() + " Length:" + microInstruction.GetMicroInstructionBinary().Length); } MicroInstructions.ForEach(mistr => MicroInstructionsBinaryList.Add(new SimpleMicroInstruction { MicroInstructionBinary = mistr.GetMicroInstructionBinary(), MicroInstructionString = mistr.MicroInstructionString })); }
private static CpuConfigurationBuilder Generate32Bit() { var config = new CpuConfigurationBuilder() .SetMemorySize(512) .SetInstructionSize(32) .SetOpcodeSize(8) #region = registers = .AddRegister("ax", 32) .AddRegister("bx", 32) .AddRegister("ma", 32) .AddRegister("md", 32) .AddRegister("ir", 32) .AddRegister("pc", 32) .AddRegister("halt", 1, true) #endregion #region = micros = .AddMicroInstruction(MicroInstruction.RegisterToRegister("ax-bx", "ax", "bx")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("bx-ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("pc-ma", "pc", "ma")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("md-ax", "md", "ax")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("md-bx", "md", "bx")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("md-ir", "md", "ir")) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(9-16)-ax", "ir", "ax", 8, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(17-24)-ax", "ir", "ax", 16, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(25-32)-ax", "ir", "ax", 24, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(9-16)-bx", "ir", "bx", 8, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(17-24)-bx", "ir", "bx", 16, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(25-32)-bx", "ir", "bx", 24, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(9-16)-pc", "ir", "pc", 8, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(17-24)-pc", "ir", "pc", 16, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(25-32)-pc", "ir", "pc", 24, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(9-16)-ma", "ir", "ma", 8, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(17-24)-ma", "ir", "ma", 16, 24, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister( "ir(25-32)-ma", "ir", "ma", 24, 24, 8)) .AddMicroInstruction(MicroInstruction.MemoryRead("memr", "ma", "md", 32)) .AddMicroInstruction(MicroInstruction.MemoryWrite("memw", "ma", "md")) .AddMicroInstruction(MicroInstruction.Set("zero-ax", "ax", 0)) .AddMicroInstruction(MicroInstruction.Set("zero-bx", "bx", 0)) .AddMicroInstruction(MicroInstruction.IoReadInt("read_i", "ax")) .AddMicroInstruction(MicroInstruction.IoWriteInt("write_i", "ax")) .AddMicroInstruction(MicroInstruction.RegisterCondition( "exeq", "ax", "bx", 1, (x, y) => x == y)) .AddMicroInstruction(MicroInstruction.RegisterCondition( "exne", "ax", "bx", 1, (x, y) => x != y)) .AddMicroInstruction(MicroInstruction.RegisterCondition( "exgt", "ax", "bx", 1, (x, y) => x > y)) .AddMicroInstruction(MicroInstruction.RegisterCondition( "exlt", "ax", "bx", 1, (x, y) => x < y)) .AddMicroInstruction(MicroInstruction.Add("add", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Subtract("sub", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Multiply("mul", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Divide("div", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Decode("decode", "ir")) .AddMicroInstruction(MicroInstruction.Increment("pc_inc", "pc", 32)) .AddMicroInstruction(MicroInstruction.Set("halt", "halt", 1)) #endregion .AddFdeCycle("pc-ma", "memr", "md-ir", "pc_inc", "decode") #region = fields = .AddInstructionField("ignore24", 24, CpuFieldType.Ignore) .AddInstructionField("ignore16", 16, CpuFieldType.Ignore) .AddInstructionField("ignore8", 8, CpuFieldType.Ignore) .AddInstructionField("data24", 24, CpuFieldType.Value) .AddInstructionField("data16", 16, CpuFieldType.Value) .AddInstructionField("data8", 8, CpuFieldType.Value) .AddInstructionField("address24", 24, CpuFieldType.Address) .AddInstructionField("address16", 16, CpuFieldType.Address) .AddInstructionField("address8", 8, CpuFieldType.Address) #endregion #region = instructions = system .AddCpuInstruction("halt", CpuValue.FromInteger(0, 8), new[] { "halt" }, new[] { "ignore24" }) .AddCpuInstruction("call", CpuValue.FromInteger(1, 8), new[] { "ir(9-16)-pc" }, new[] { "address8", "ignore16" }) #endregion #region = instructions = io .AddCpuInstruction("out", CpuValue.FromInteger(2, 8), new[] { "write_i" }, new[] { "ignore24" }) .AddCpuInstruction("in", CpuValue.FromInteger(3, 8), new[] { "read_i" }, new[] { "ignore24" }) .AddCpuInstruction("load", CpuValue.FromInteger(4, 8), new[] { "write_i" }, new[] { "ignore24" }) .AddCpuInstruction("save", CpuValue.FromInteger(5, 8), new[] { "read_i" }, new[] { "ignore24" }) #endregion #region = instructions = arithmetics .AddCpuInstruction("add_a", CpuValue.FromInteger(6, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "add" }, new[] { "address8", "ignore16" }) .AddCpuInstruction("sub_a", CpuValue.FromInteger(7, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "sub" }, new[] { "address8", "ignore16" }) .AddCpuInstruction("add_v", CpuValue.FromInteger(8, 8), new[] { "ir(9-16)-bx", "add" }, new[] { "data8", "ignore16" }) .AddCpuInstruction("sub_v", CpuValue.FromInteger(9, 8), new[] { "ir(9-16)-bx", "sub" }, new[] { "data8", "ignore16" }) .AddCpuInstruction("mul_a", CpuValue.FromInteger(10, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "mul" }, new[] { "address8", "ignore16" }) .AddCpuInstruction("div_a", CpuValue.FromInteger(11, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "div" }, new[] { "address8", "ignore16" }) .AddCpuInstruction("mul_v", CpuValue.FromInteger(12, 8), new[] { "ir(9-16)-bx", "mul" }, new[] { "data8", "ignore16" }) .AddCpuInstruction("div_v", CpuValue.FromInteger(13, 8), new[] { "ir(9-16)-bx", "div" }, new[] { "data8", "ignore16" }) #endregion #region = instructions = logic .AddCpuInstruction("call_eq_a", CpuValue.FromInteger(14, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "exeq", "ir(17-24)-pc" }, new[] { "address8", "address8", "ignore8" }) .AddCpuInstruction("call_eq_v", CpuValue.FromInteger(15, 8), new[] { "ir(9-16)-bx", "exeq", "ir(17-24)-pc" }, new[] { "data8", "address8", "ignore8" }) .AddCpuInstruction("call_ne_a", CpuValue.FromInteger(16, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "exne", "ir(17-24)-pc" }, new[] { "address8", "address8", "ignore8" }) .AddCpuInstruction("call_ne_v", CpuValue.FromInteger(17, 8), new[] { "ir(9-16)-bx", "exne", "ir(17-24)-pc" }, new[] { "data8", "address8", "ignore8" }) .AddCpuInstruction("call_lt_a", CpuValue.FromInteger(18, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "exlt", "ir(17-24)-pc" }, new[] { "address8", "address8", "ignore8" }) .AddCpuInstruction("call_lt_v", CpuValue.FromInteger(19, 8), new[] { "ir(9-16)-bx", "exlt", "ir(17-24)-pc" }, new[] { "data8", "address8", "ignore8" }) .AddCpuInstruction("call_gt_a", CpuValue.FromInteger(20, 8), new[] { "ir(9-16)-ma", "memr", "md-bx", "exgt", "ir(17-24)-pc" }, new[] { "address8", "address8", "ignore8" }) .AddCpuInstruction("call_gt_v", CpuValue.FromInteger(21, 8), new[] { "ir(9-16)-bx", "exgt", "ir(17-24)-pc" }, new[] { "data8", "address8", "ignore8" }); #endregion return(config); }
private static CpuConfigurationBuilder Generate16Bit() { var config = new CpuConfigurationBuilder() .SetMemorySize(256) .SetOpcodeSize(8) .SetInstructionSize(16) .AddRegister("ax", 16) .AddRegister("bx", 16) .AddRegister("ma", 16) .AddRegister("md", 16) .AddRegister("pc", 16) .AddRegister("ir", 16) .AddRegister("halt", 1, true) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ax-bx", "ax", "bx")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ax-md", "ax", "md")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("pc-ma", "pc", "ma")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("md-ax", "md", "ax")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("md-ir", "md", "ir")) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ir(9-16)-ax", "ir", "ax", 8, 8, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ir(9-16)-bx", "ir", "bx", 8, 8, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ir(9-16)-ma", "ir", "ma", 8, 8, 8)) .AddMicroInstruction(MicroInstruction.RegisterToRegister("ir(9-16)-pc", "ir", "pc", 8, 8, 8)) .AddMicroInstruction(MicroInstruction.MemoryRead("memr", "ma", "md", 16)) .AddMicroInstruction(MicroInstruction.MemoryWrite("memw", "ma", "md")) .AddMicroInstruction(MicroInstruction.Increment("pc-inc", "pc", 16)) .AddMicroInstruction(MicroInstruction.Add("add", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Subtract("sub", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Multiply("mult", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Divide("div", "ax", "bx", "ax")) .AddMicroInstruction(MicroInstruction.Decode("decode", "ir")) .AddMicroInstruction(MicroInstruction.IoReadInt("read", "ax")) .AddMicroInstruction(MicroInstruction.IoWriteInt("write", "ax")) .AddMicroInstruction(MicroInstruction.IoReadChar("reads", "ax")) .AddMicroInstruction(MicroInstruction.IoWriteChar("writes", "ax")) .AddMicroInstruction(MicroInstruction.Set("zero-ax", "ax", 0)) .AddMicroInstruction(MicroInstruction.Set("zero-bx", "bx", 0)) .AddMicroInstruction(MicroInstruction.Set("halt", "halt", 1)) .AddMicroInstruction(MicroInstruction.StaticCondition("eqze", "ax", 1, i => i == 0)) .AddMicroInstruction(MicroInstruction.StaticCondition("neze", "ax", 1, i => i != 0)) .AddFdeCycle("pc-ma", "memr", "md-ir", "pc-inc", "decode") .AddInstructionField("ignore8", 8, CpuFieldType.Ignore) .AddInstructionField("data8", 8, CpuFieldType.Value) .AddInstructionField("address8", 8, CpuFieldType.Address) .AddCpuInstruction("read_int", CpuValue.FromInteger(1, 8), new[] { "read" }, new[] { "ignore8" }) .AddCpuInstruction("write_int", CpuValue.FromInteger(2, 8), new[] { "write" }, new[] { "ignore8" }) .AddCpuInstruction("add", CpuValue.FromInteger(3, 8), new[] { "ax-bx", "zero-ax", "ir(9-16)-ax", "add" }, new[] { "data8" }) .AddCpuInstruction("sub", CpuValue.FromInteger(4, 8), new[] { "zero-bx", "ir(9-16)-bx", "sub" }, new[] { "data8" }) .AddCpuInstruction("mult", CpuValue.FromInteger(5, 8), new[] { "zero-bx", "ir(9-16)-bx", "mult" }, new[] { "data8" }) .AddCpuInstruction("div", CpuValue.FromInteger(6, 8), new[] { "zero-bx", "ir(9-16)-bx", "div" }, new[] { "data8" }) .AddCpuInstruction("halt", CpuValue.FromInteger(7, 8), new[] { "halt" }, new[] { "ignore8" }) .AddCpuInstruction("jump", CpuValue.FromInteger(8, 8), new[] { "ir(9-16)-pc" }, new[] { "address8" }) .AddCpuInstruction("jeqz", CpuValue.FromInteger(9, 8), new[] { "eqze", "ir(9-16)-pc" }, new[] { "address8" }) .AddCpuInstruction("jnez", CpuValue.FromInteger(10, 8), new[] { "neze", "ir(9-16)-pc" }, new[] { "address8" }) .AddCpuInstruction("load", CpuValue.FromInteger(11, 8), new[] { "ir(9-16)-ma", "memr", "md-ax" }, new[] { "address8" }) .AddCpuInstruction("save", CpuValue.FromInteger(12, 8), new[] { "ir(9-16)-ma", "ax-md", "memw" }, new[] { "address8" }) .AddCpuInstruction("read_s", CpuValue.FromInteger(13, 8), new[] { "reads" }, new[] { "ignore8" }) .AddCpuInstruction("write_s", CpuValue.FromInteger(14, 8), new[] { "writes" }, new[] { "ignore8" }); return(config); }
private List <MicroInstruction> ParseTStateCode(string tstates, string mnemonic) { var result = new List <MicroInstruction>(); if (string.IsNullOrEmpty(tstates)) { return(result); } if (tstates.Trim().StartsWith(">")) { // Instruction doesn't define T-states, but instead refers to another instruction for the T-state definition. string referredMnemonic = tstates.Substring(1).Trim(); var referredInstruction = this.MicrocodeSource.FirstOrDefault(m => m.Instruction.Mnemonic.Equals(referredMnemonic, StringComparison.OrdinalIgnoreCase)); if (referredInstruction == null) { throw new CompilerException($"Could not find reference instruction '{referredMnemonic}' for instruction {mnemonic}"); } return(referredInstruction.TStates); } tstates = tstates.Replace(" ", string.Empty); int cursor = tstates.IndexOf(":"); while (cursor > -1) { int tstateEnd = tstates.IndexOf(":", cursor + 1); if (tstateEnd == -1) { tstateEnd = tstates.Length; } string tstate = tstates.Substring(cursor + 1, tstateEnd - cursor - 1); string[] uinstructions = tstate.Split('\n', StringSplitOptions.RemoveEmptyEntries); var microInstruction = new MicroInstruction { Type = MicroInstructionType.FunctionOperation, ControlLines = new List <BitPattern>(), OperandLoad = new BitPattern { Bits = "0000" }, OperandOut = new BitPattern { Bits = "0000" } }; for (int i = 0; i < uinstructions.Length; i++) { if (i == 0 && uinstructions[i].IndexOf("[data]", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.Type = MicroInstructionType.DataOperation; string aluFuncString = uinstructions[i].Replace("[data]", string.Empty) .Replace("[", string.Empty) .Replace("]", string.Empty); if (!string.IsNullOrWhiteSpace(aluFuncString) && this.AluFunctions.Exists(f => f.Identifier.Equals(aluFuncString, StringComparison.OrdinalIgnoreCase))) { microInstruction.AluFunction = this.AluFunctions.FirstOrDefault(f => f.Identifier.Equals(aluFuncString, StringComparison.OrdinalIgnoreCase)); } } else if (i == 0 && uinstructions[i].IndexOf("[function]", StringComparison.OrdinalIgnoreCase) > -1) { // Ignore } else { var function = this.InstructionFunctions.FirstOrDefault(o => o.Identifier.Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase)); var operand = this.Operands.FirstOrDefault(o => $"{o.Identifier}_load".Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase) || $"{o.Identifier}_out".Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase)); if (operand != null) { if (uinstructions[i].IndexOf("_load", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.OperandLoad = operand; } else if (uinstructions[i].IndexOf("_out", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.OperandOut = operand; } } else if (function != null) { microInstruction.ControlLines.Add(function); } else if (int.TryParse(uinstructions[i], out int tmp)) { // Ignore } else { throw new CompilerException($"Could not locate operand or function '{uinstructions[i]}' for tstate at position {cursor} for instruction {mnemonic}"); } } } result.Add(microInstruction); cursor = tstateEnd < tstates.Length ? tstates.IndexOf(":", tstateEnd) : -1; } if (result.Count > 16) { throw new CompilerException($"Maximum number of tstates exceeded ({result.Count}) for instruction {mnemonic}"); } return(result); }
private void TraceMicroInstruction(MicroInstruction microInstruction) { MicroInstructions.Add(microInstruction); }
private List <MicroInstruction> ParseTStateCode(string tstates) { var result = new List <MicroInstruction>(); if (string.IsNullOrEmpty(tstates)) { return(result); } tstates = tstates.Replace(" ", string.Empty); int cursor = tstates.IndexOf(":"); while (cursor > -1) { int tstateEnd = tstates.IndexOf(":", cursor + 1); if (tstateEnd == -1) { tstateEnd = tstates.Length; } string tstate = tstates.Substring(cursor + 1, tstateEnd - cursor - 1); string[] uinstructions = tstate.Split('\n', StringSplitOptions.RemoveEmptyEntries); var microInstruction = new MicroInstruction { Type = MicroInstructionType.FunctionOperation, ControlLines = new List <BitPattern>() }; for (int i = 0; i < uinstructions.Length; i++) { if (i == 0 && uinstructions[i].IndexOf("[data]", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.Type = MicroInstructionType.DataOperation; string aluFuncString = uinstructions[i].Replace("[data]", string.Empty) .Replace("[", string.Empty) .Replace("]", string.Empty); if (!string.IsNullOrWhiteSpace(aluFuncString) && this.AluFunctions.Exists(f => f.Identifier.Equals(aluFuncString, StringComparison.OrdinalIgnoreCase))) { microInstruction.AluFunction = this.AluFunctions.FirstOrDefault(f => f.Identifier.Equals(aluFuncString, StringComparison.OrdinalIgnoreCase)); } } else if (i == 0 && uinstructions[i].IndexOf("[function]", StringComparison.OrdinalIgnoreCase) > -1) { // Ignore } else { var function = this.InstructionFunctions.FirstOrDefault(o => o.Identifier.Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase)); var operand = this.Operands.FirstOrDefault(o => $"{o.Identifier}_load".Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase) || $"{o.Identifier}_out".Equals(uinstructions[i], StringComparison.OrdinalIgnoreCase)); if (operand != null) { if (uinstructions[i].IndexOf("_load", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.OperandLoad = operand; } else if (uinstructions[i].IndexOf("_out", StringComparison.OrdinalIgnoreCase) > -1) { microInstruction.OperandOut = operand; } } else if (function != null) { microInstruction.ControlLines.Add(function); } else if (int.TryParse(uinstructions[i], out int tmp)) { // Ignore } else { throw new CompilerException($"Could not locate operand or function '{uinstructions[i]}' for tstate at position {cursor}"); } } } result.Add(microInstruction); cursor = tstateEnd < tstates.Length ? tstates.IndexOf(":", tstateEnd) : -1; } return(result); }
public CpuConfigurationBuilder AddMicroInstruction(MicroInstruction mi) { _microInstructions.Add(mi); return(this); }