Exemple #1
0
        /// <summary>
        /// only for instructions that use labels
        /// </summary>
        /// <param name="Assembly.AddressingMethod"></param>
        /// <param name="pc"></param>
        void setValue(Assembly.AddressingMethod AddressingMethod, ushort pc)
        {
            int nval = 0;

            try
            {
                nval = ComputedValue.GetNumeral();
            }
            catch (FormatException ex)
            {
                throw new SyntaxErrorException("Invalid label or literal", ex);
            }
            int fnval = nval;

            if (AddressingMethod == Assembly.AddressingMethod.relative)
            {
                nval -= ((ushort)pc + 2);
            }
            int onval = nval;

            if (nval < 0)
            {
                nval = Assembly.TwosComplement8bit(nval);
            }

            if (nval > ushort.MaxValue)
            {
                throw new SyntaxErrorException("Value out of range: " + nval + ", it first was " + fnval + ", after possible relative subtraction is was " + onval + ", then if so it was complemented to " + nval);
            }

            setValue(nval);
            return;
        }
Exemple #2
0
        /// <summary>
        /// Populate the ComputedValue object with the results determined from the earlier-set ValueLeft, ValueMiddle, ValueRight, and OpCode
        /// For use on the second pass for opcodes that use a label
        /// </summary>
        /// <param name="opcode"></param>
        /// <param name="Assembly.AddressingMethod"></param>
        /// <param name="pc"></param>
        public void ParseValue(Assembly.OpCode opcode, Assembly.AddressingMethod AddressingMethod, ushort pc)
        {
            if (!(labelUsers.Contains(opcode)))
            {
                return;
            }

            parseValue();

            setValue(AddressingMethod, pc);

            return;
        }
Exemple #3
0
        /// <summary>
        /// Determines addressing method of a line
        /// </summary>
        /// <param name="assembler"></param>
        public void DetermineAddressingMethod(AssemblerConfig config)
        {
            if (this.OpCode == null)
            {
                throw new InvalidOperationException("Attempt to determine addressing method of non-statement");
            }

            if (this.RValue == null)
            {
                this.AddressingMethod = Assembly.AddressingMethod.implied;
                return;
            }

            //will include branches, jmp, implied, accumulator (shown as implied
            if (Assembly.OpcodeTable[OpCode.Value].Keys.Count == 1)
            {
                AddressingMethod = Assembly.OpcodeTable[OpCode.Value].Keys.First();
                return;
            }

            //branches and jumps were already detected before this point
            this.RValue.ParseValue(this.OpCode.Value);

            var result = this.RValue.ComputedValue;

            var choices =
                RValue.LineEndingToOptions[this.RValue.ValueRight].Where(
                    choice => Assembly.OpcodeTable[this.OpCode.Value].Keys.Contains(choice)
                    ).ToList();

            if (choices.Count == 0)
            {
                throw new SyntaxErrorException("Illegal addressing method for opcode");
            }

            if (choices.Count == 1)
            {
                this.AddressingMethod = choices.First();
                return;
            }

            if (result.Literal)
            {
                this.AddressingMethod = Assembly.AddressingMethod.immediate;
                return;
            }

            choices.Remove(Assembly.AddressingMethod.immediate);

            if (choices.Count == 0)
            {
                throw new SyntaxErrorException("Illegal addressing method for opcode");
            }

            if (choices.Count == 1)
            {
                this.AddressingMethod = choices.First();
                return;
            }

            Assembly.AddressingMethod lo = choices.Where(choice => Assembly.AddressingMethodLength[choice] == 1).First();
            Assembly.AddressingMethod hi = choices.Where(choice => Assembly.AddressingMethodLength[choice] == 2).First();

            switch (config.OperandLength)
            {
            case AssemblerConfig.OperandLengthOption.Longest:
                this.AddressingMethod = hi;
                return;

            case AssemblerConfig.OperandLengthOption.Smallest:
                if (result.Result > byte.MaxValue)
                {
                    this.AddressingMethod = hi;
                    return;
                }

                this.AddressingMethod = lo;
                return;

            case AssemblerConfig.OperandLengthOption.AsWritten:
                //Only works in binary and hex because they're the ones where one extra digit is the point where it goes from one byte to two
                if (result.Base == 2 || result.Base == 16)
                {
                    //maximum characters before there are more characters than necessary to represent 256
                    int bumpLimit = result.Base == 2 ? 8 : 2;

                    if (result.ValueString.Length > bumpLimit)
                    {
                        this.AddressingMethod = hi;
                        return;
                    }

                    this.AddressingMethod = lo;
                    return;
                }

                if (result.Result > byte.MaxValue)
                {
                    this.AddressingMethod = hi;
                    return;
                }
                this.AddressingMethod = lo;
                return;
            }

            throw new SyntaxErrorException("Unable to determine addressing method");
        }