예제 #1
0
        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);
        }
예제 #2
0
        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)");
        }