private void AddToMicrocodeSource(string mnemonic, FlagsState flags, string tstates) { var instructionCode = new InstructionMicrocode { Instruction = this.Instructions.FirstOrDefault(i => i.Mnemonic.Equals(mnemonic, StringComparison.OrdinalIgnoreCase)), Flags = flags, TStates = this.ParseTStateCode(tstates, mnemonic) }; if (instructionCode.Instruction == null) { throw new CompilerException($"Could not find instruction definition for '{mnemonic}'"); } this.MicrocodeSource.Add(instructionCode); }
private void LoadCode() { var sw = Stopwatch.StartNew(); Console.Write("Loading code..."); int cursor = this.source.IndexOf(SECTION_CODE, StringComparison.OrdinalIgnoreCase); if (cursor == -1) { throw new CompilerException($"Could not find '{SECTION_CODE}' section"); } // Instruction starts on next line. cursor = this.source.IndexOf("\n", cursor) + 1; // Move cursor through the source file until we reach the end. while (cursor > -1 && cursor < this.source.Length - 1) { // Get instruction mnemonic. int mnemonicEnd = this.source.IndexOf("\n", cursor); if (mnemonicEnd == -1) { mnemonicEnd = this.source.Length; } string mnemonic = this.source.Substring(cursor, mnemonicEnd - cursor); if (mnemonic.Equals(".end", StringComparison.OrdinalIgnoreCase)) { // End of .code block reached. break; } // Get t-states code. cursor = mnemonicEnd + 1; int tstatesEnd = this.source.IndexOf(".end", cursor, StringComparison.OrdinalIgnoreCase); string tstates = string.Empty; if (tstatesEnd - cursor > 0) { tstates = this.source.Substring(cursor, tstatesEnd - cursor - 1); } FlagsState flags = null; // Get flags criteria. if (mnemonic.IndexOf("[") > -1) { int flagStart = mnemonic.IndexOf("["); int flagEnd = mnemonic.IndexOf("]", flagStart); string flagString = mnemonic.Substring(flagStart, flagEnd - flagStart + 1); mnemonic = mnemonic.Replace(flagString, string.Empty) .Replace(" ", " ") .Trim(); flags = new FlagsState(flagString); } // If we don't need to replace anything in the source code, just add the instruction to memory. if (mnemonic.IndexOf("r1", StringComparison.OrdinalIgnoreCase) > -1 || mnemonic.IndexOf("r2", StringComparison.OrdinalIgnoreCase) > -1 || mnemonic.IndexOf("hl1", StringComparison.OrdinalIgnoreCase) > -1 || mnemonic.IndexOf("hl2", StringComparison.OrdinalIgnoreCase) > -1) { foreach (string r1 in REGISTERS) { foreach (string r2 in REGISTERS) { foreach (string hl1 in REGISTERS_PAIRS) { foreach (string hl2 in REGISTERS_PAIRS) { string targetMnemonic = mnemonic.Replace("r1", r1).Replace("r2", r2) .Replace("hl1", hl1).Replace("hl2", hl2); if (this.Instructions.Exists(i => i.Mnemonic.Equals(targetMnemonic, StringComparison.OrdinalIgnoreCase)) && !this.MicrocodeSource.Exists(c => c.Instruction.Mnemonic.Equals(targetMnemonic, StringComparison.OrdinalIgnoreCase) && c.Flags == flags)) { string targetTstates = tstates.Replace("r1", r1).Replace("r2", r2) .Replace("hl1", hl1).Replace("hl2", hl2) .Replace("h1", $"{hl1[0]}").Replace("l1", $"{hl1[1]}") .Replace("h2", $"{hl2[0]}").Replace("l2", $"{hl2[1]}"); this.AddToMicrocodeSource(targetMnemonic, flags, targetTstates); } } } } } } else { this.AddToMicrocodeSource(mnemonic, flags, tstates); } // Move cursor to next instruction. cursor = this.source.IndexOf("\n", tstatesEnd) + 1; } Console.WriteLine($"Done ({sw.ElapsedMilliseconds} ms)"); }