Beispiel #1
0
            private static void DJRNZ(string[] args, CompilerEnvironment env)
            {
                if (args.Length != 2)
                {
                    throw new CompilationErrorExcepton("Оператор DJRNZ должен принимать ровно 2 аргумента.", env.GetCurrentLine());
                }

                var R = CompilerSupport.ConvertToRegister(args[0]);

                if (!R.HasValue)
                {
                    throw new CompilationErrorExcepton("Первым аргументом должен быть регистр.", env.GetCurrentLine());
                }
                var register = R.Value;

                if (!register.IsDirect)
                {
                    throw new CompilationErrorExcepton("В этой команде нельзя использовать косвенную адерсацию.", env.GetCurrentLine());
                }
                if (register.Number > 3)
                {
                    throw new CompilationErrorExcepton("В этой команде можно использовать только первые 4 регистра.", env.GetCurrentLine());
                }
                string L       = args[1];
                int    address = CompilerSupport.ConvertLabelToFarAddress(L, env);

                var lowBitArray  = new BitArray(8);
                var highBitArray = new BitArray(8)
                {
                    [2] = (register.Number & 1) != 0,
                    [3] = (register.Number & 2) != 0,
                    [4] = true
                };

                if (address == -1)
                {
                    var memoryForLabel = new CompilerEnvironment.MemoryForLabel {
                        HighBitArray = highBitArray,
                        LowBitArray  = lowBitArray,
                        Address      = env.CurrentAddress
                    };
                    env.SetCommandWithoutLabel(memoryForLabel, L);
                    return;
                }

                CompilerSupport.FillBitArray(highBitArray, lowBitArray, address, Constants.FarAddressBitsCount);
                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }
Beispiel #2
0
            private static void FillAddressAndSetCommand(BitArray highBitArray, BitArray lowBitArray, string label, CompilerEnvironment env)
            {
                int address = CompilerSupport.ConvertLabelToFarAddress(label, env);

                if (address == -1)
                {
                    var memoryForLabel = new CompilerEnvironment.MemoryForLabel {
                        HighBitArray = highBitArray,
                        LowBitArray  = lowBitArray,
                        Address      = env.CurrentAddress
                    };
                    env.SetCommandWithoutLabel(memoryForLabel, label);
                    return;
                }

                CompilerSupport.FillBitArray(highBitArray, lowBitArray, address, Constants.FarAddressBitsCount);

                env.SetByte(lowBitArray);
                env.SetByte(highBitArray);
            }
Beispiel #3
0
        /// <summary>
        /// Обрабатывает директиву процессора, и изменяет окружение в соответствии с ней.
        /// В случае, если директива некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, из которой извлекается директива.</param>
        /// <param name="env">Текущее окружение компилятора, которое изменяется в соответствии с директивой.</param>
        public void HandleDirective(string line, CompilerEnvironment env)
        {
            if (line.Substring(1).ToLower().StartsWith("org"))
            {
                string[] components = line.Split(' ');
                if (components.Length != 2)
                {
                    throw new CompilationErrorExcepton("После /org должно следовать одно число через пробел.", env.GetCurrentLine());
                }

                try {
                    int address = CompilerSupport.ConvertToInt(components[1]);
                    if (address > 255 || address < 0)
                    {
                        throw new Exception();
                    }
                    env.CurrentAddress = address;
                } catch (Exception) {
                    throw new CompilationErrorExcepton("Некорректная директива процессора. Адрес должен быть числом в диапазоне от 0 до 255.", env.GetCurrentLine());
                }
            }
            else if (line[1] == 'C' || line[1] == 'c')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultCodeSegment = segment;
            }
            else if (line[1] == 'S' || line[1] == 's')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultStackSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && line[2] != 'B' && line[2] != 'b' && line[2] != 'W' && line[2] != 'w')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultDataSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'B' || line[2] == 'b'))                 //работа дерективы .db
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string value   = i.Trim();
                    int    address = CompilerSupport.ConvertLabelToFarAddress(value, env);
                    if (address != -1)
                    {
                        address = address & 0xFF;

                        env.SetByte(new ExtendedBitArray(address));
                    }
                    else
                    {
                        env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel {
                            HighBitArray = new ExtendedBitArray(),
                            LowBitArray  = new ExtendedBitArray(),
                            Address      = env.CurrentAddress,
                            SingleByte   = true
                        }, value);
                    }
                }
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'W' || line[2] == 'w'))             //работа дерективы .dw
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string        value      = i.Trim();
                    List <string> parameters = new List <string>();
                    if (value.StartsWith("0x") && value.Length > 4)                    //если адрес формата 0xFFFF или 0xFFF, раскладываем на 2 байта
                    {
                        parameters.Add("0x" + value.Substring(value.Length - 2));
                        parameters.Add(value.Substring(0, value.Length - 2));
                    }
                    else if (value.StartsWith("0b") && value.Length > 10)                    //если 0b11..11 (больше 1 байта)
                    {
                        parameters.Add("0b" + value.Substring(value.Length - 8));
                        parameters.Add(value.Substring(0, value.Length - 8));
                    }
                    else
                    {
                        parameters.Add(value);                        //если 0xFF, 0b11111111 или Метка
                        parameters.Add("0x00");
                    }
                    foreach (var p in parameters)
                    {
                        int address = CompilerSupport.ConvertLabelToFarAddress(p, env);
                        if (address != -1)
                        {
                            address = address & 0xFF;
                            env.SetByte(new ExtendedBitArray(address));
                        }
                        else
                        {
                            env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel
                            {
                                HighBitArray = new ExtendedBitArray(),
                                LowBitArray  = new ExtendedBitArray(),
                                Address      = env.CurrentAddress,
                                SingleByte   = true
                            }, p);
                        }
                    }
                }
            }
            else
            {
                throw new CompilationErrorExcepton("Некорректная директива процессора.", env.GetCurrentLine());
            }
        }
Beispiel #4
0
        /// <summary>
        /// Обрабатывает директиву процессора, и изменяет окружение в соответствии с ней.
        /// В случае, если директива некорректна, генерируется <see cref="CompilationErrorExcepton"/>
        /// </summary>
        /// <param name="line">Строка кода, из которой извлекается директива.</param>
        /// <param name="env">Текущее окружение компилятора, которое изменяется в соответствии с директивой.</param>
        public void HandleDirective(string line, CompilerEnvironment env)
        {
            if (line.Substring(1).ToLower().StartsWith("org"))
            {
                string[] components = line.Split(' ');
                if (components.Length != 2)
                {
                    throw new CompilationErrorExcepton("После /org должно следовать одно число через пробел.", env.GetCurrentLine());
                }

                try {
                    int address = CompilerSupport.ConvertToInt(components[1]);
                    if (address > 255 || address < 0)
                    {
                        throw new Exception();
                    }
                    env.CurrentAddress = address;
                } catch (Exception) {
                    throw new CompilationErrorExcepton("Некорректная директива процессора. Адрес должен быть числом в диапазоне от 0 до 255.", env.GetCurrentLine());
                }
            }
            else if (line[1] == 'C' || line[1] == 'c')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultCodeSegment = segment;
            }
            else if (line[1] == 'S' || line[1] == 's')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultStackSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && line[2] != 'B' && line[2] != 'b')
            {
                int segment = TryToGetSegmentFromDirecrive(line, env.GetCurrentLine());
                env.DefaultDataSegment = segment;
            }
            else if ((line[1] == 'D' || line[1] == 'd') && (line[2] == 'B' || line[2] == 'b'))
            {
                string   values     = line.Substring(3);
                string[] components = values.Split(',');
                foreach (var i in components)
                {
                    string value   = i.Trim();
                    int    address = CompilerSupport.ConvertLabelToFarAddress(value, env);
                    if (address != -1)
                    {
                        address = address & 0xFF;

                        env.SetByte(new ExtendedBitArray(address));
                    }
                    else
                    {
                        env.SetCommandWithoutLabel(new CompilerEnvironment.MemoryForLabel {
                            HighBitArray = new ExtendedBitArray(),
                            LowBitArray  = new ExtendedBitArray(),
                            Address      = env.CurrentAddress,
                            SingleByte   = true
                        }, value);
                    }
                }
            }
            else
            {
                throw new CompilationErrorExcepton("Некорректная директива процессора.", env.GetCurrentLine());
            }
        }