예제 #1
0
        public static void ResolveIncludes(AsmSource asmSource)
        {
            string[] lines = asmSource.Text.Split(
                new[] { Environment.NewLine },
                StringSplitOptions.None
                );

            string newText = "";

            foreach (var line in lines)
            {
                if (line.Trim().ToLower().StartsWith("#include"))
                {
                    var fileName = line.Trim().Substring(8).Trim();

                    var linesIncludeFile = File.ReadAllLines(fileName);

                    foreach (var lineInclude in linesIncludeFile)
                    {
                        newText += lineInclude + Environment.NewLine;
                    }
                }
                else
                {
                    newText += line + Environment.NewLine;
                }
            }

            asmSource.Text = newText;
        }
예제 #2
0
        public static void ConvertTokensToMachineCode(AsmSource asmSource)
        {
            var nextProgramAddress = 0;

            foreach (var line in asmSource.Lines)
            {
                if (line.Address >= nextProgramAddress)
                {
                    // Fill bytes with zeroes when there is a gap between
                    // instructions (caused by an #org directive)
                    var start = nextProgramAddress;
                    for (var i = start; i < line.Address; i++)
                    {
                        asmSource.Bytes.Add(0);
                        nextProgramAddress++;
                    }

                    asmSource.Bytes.AddRange(ConvertLineTokensToMachineCode(line));
                    nextProgramAddress += 3;
                }
                else
                {
                    var bytes = ConvertLineTokensToMachineCode(line);

                    asmSource.Bytes[line.Address]     = bytes[0];
                    asmSource.Bytes[line.Address + 1] = bytes[1];
                    asmSource.Bytes[line.Address + 2] = bytes[2];
                }
            }

            var lastAddr = nextProgramAddress;

            foreach (var defMem in asmSource.DefMems)
            {
                var address = defMem.Key;
                var value   = Convert.ToByte(defMem.Value);

                if (address >= lastAddr)
                {
                    // Fill space between end of program (or last defmem addr)
                    // and defmem addr
                    for (int i = lastAddr; i < address; i++)
                    {
                        asmSource.Bytes.Add(0);
                        lastAddr++;
                    }

                    asmSource.Bytes.Add(value);
                    lastAddr++;
                }
                else
                {
                    asmSource.Bytes[address] = value;
                }
            }
        }
예제 #3
0
        public static AsmSource SourceToMachineCode(string source)
        {
            var asmSource = new AsmSource(source);

            AssemblerClass.ResolveIncludes(asmSource);
            AssemblerClass.ConvertToTokens(asmSource);
            AssemblerClass.ResolveLabelsAndDirectives(asmSource);
            AssemblerClass.ConvertTokensToMachineCode(asmSource);

            return(asmSource);
        }
예제 #4
0
        public static void ConvertToTokens(AsmSource asmSource)
        {
            var lines = asmSource.Text.Split(
                new[] { Environment.NewLine },
                StringSplitOptions.None
                );


            foreach (var line in lines)
            {
                Line newLine = ConvertLineToTokens(line);

                if (newLine.Tokens.Count > 0)
                {
                    asmSource.Lines.Add(newLine);
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Identifies and resolves Labels and Variables
        /// </summary>
        /// <param name="asmSource"></param>
        public static void ResolveLabelsAndDirectives(AsmSource asmSource)
        {
            var programAddress    = 0;
            var varAddress        = 0xc00;
            var defMemLastAddress = 0;

            foreach (var line in asmSource.Lines)
            {
                if (line.IsLabelDefinition())
                {
                    asmSource.Labels.Add(new KeyValuePair <string, int>(
                                             line.Tokens[0].Text,
                                             programAddress));
                }
                else if (line.IsVariableDefinition())
                {
                    asmSource.Variables.Add(new KeyValuePair <string, int>(
                                                line.Tokens[1].Text,
                                                varAddress));

                    varAddress++;
                }
                else if (line.IsOrgDirective())
                {
                    programAddress = ((LiteralToken)line.Tokens[1]).NumericValue;
                }
                else if (line.IsDefMemDirective())
                {
                    var address = 0;
                    var value   = 0;
                    if (line.Tokens.Count == 3)
                    {
                        address           = ((LiteralToken)line.Tokens[1]).NumericValue;
                        defMemLastAddress = address;

                        value = ((LiteralToken)line.Tokens[2]).NumericValue;
                    }
                    else if (line.Tokens.Count == 2)
                    {
                        defMemLastAddress++;
                        address = defMemLastAddress;

                        value = ((LiteralToken)line.Tokens[1]).NumericValue;
                    }


                    asmSource.DefMems.Add(new KeyValuePair <int, int>(
                                              address,
                                              value));
                }
                else
                {
                    line.Address    = programAddress;
                    programAddress += 3;
                }
            }

            IList <Line> newLines = new List <Line>();

            foreach (var line in asmSource.Lines)
            {
                try
                {
                    // if is label definition or defbyte, drop line
                    if (line.IsLabelDefinition() ||
                        line.IsVariableDefinition() ||
                        line.IsOrgDirective() ||
                        line.IsDefMemDirective())
                    {
                        continue;
                    }

                    // if has label or variable in line, resolve it
                    // (convert to corresponding memory address)
                    IList <Token> newTokens = new List <Token>();
                    foreach (var token in line.Tokens)
                    {
                        if (token is LabelToken)
                        {
                            var literal      = asmSource.Labels[token.Text].ToString();
                            var literalToken = new LiteralToken(literal);

                            newTokens.Add(literalToken);
                        }
                        else if (token is DirectiveToken)
                        {
                            var address      = asmSource.Variables[token.Text].ToString();
                            var addressToken = new AddressToken(address);

                            newTokens.Add(addressToken);
                        }
                        else
                        {
                            newTokens.Add(token);
                        }
                    }
                    line.Tokens.Clear();
                    line.Tokens = newTokens;

                    newLines.Add(line);
                }
                catch (Exception ex)
                {
                    throw new Exception("Error in line: " + line.Text, ex);
                }
            }
            asmSource.Lines.Clear();
            asmSource.Lines = newLines;
        }