示例#1
0
        /// <summary>
        /// Returns a value between 0 and 255, or -1 if no opcode was found, or -2 if the addressing mode is not available for the instruction..
        /// </summary>
        /// <param name="instruction"></param>
        /// <param name="addressing"></param>
        /// <returns></returns>
        private int FindOpcode(StringSection instruction, Opcode.addressing addressing)
        {
            var  ops = Opcode.allOps;
            bool instructionFound        = false;
            bool foundInstructionInvalid = false;

            for (int i = 0; i < Opcode.allOps.Length; i++)
            {
                if (StringEquals(ops[i].name, instruction, true))
                {
                    // Note that the instruction exists. We need to tell the user whether
                    // an instruction does not exist or the desired addressing mode is not available.
                    instructionFound = true;

                    var addrMode = ops[i].addressing;

                    // Branch instructions will be treated as absolute until they are actually encoded.
                    if (addrMode == Opcode.addressing.relative)
                    {
                        addrMode = Opcode.addressing.absolute;
                    }

                    if (addressing == addrMode)
                    {
                        if (ops[i].valid | Assembler.AllowInvalidOpcodes)
                        {
                            return(i);
                        }
                        else
                        {
                            foundInstructionInvalid = true;
                        }
                    }
                }
            }

            if (instructionFound)
            {
                if (foundInstructionInvalid)
                {
                    return((int)OpcodeError.InvalidOpcode);
                }
                else
                {
                    return((int)OpcodeError.InvalidAddressing);
                }
            }
            else
            {
                return((int)OpcodeError.UnknownInstruction);
            }
        }
示例#2
0
        private bool TryZeroPageEqivalent(ref Opcode.addressing addressing)
        {
            switch (addressing)
            {
            case Opcode.addressing.absolute:
                addressing = Opcode.addressing.zeropage;
                return(true);

            case Opcode.addressing.absoluteIndexedX:
                addressing = Opcode.addressing.zeropageIndexedX;
                return(true);

            case Opcode.addressing.absoluteIndexedY:
                addressing = Opcode.addressing.zeropageIndexedY;
                return(true);

            default:
                return(false);
            }
        }
示例#3
0
        private bool IsZeroPage(Opcode.addressing addressing)
        {
            switch (addressing)
            {
            case Opcode.addressing.zeropage:
            case Opcode.addressing.zeropageIndexedX:
            case Opcode.addressing.zeropageIndexedY:
                return(true);

            case Opcode.addressing.implied:
            case Opcode.addressing.immediate:
            case Opcode.addressing.absolute:
            case Opcode.addressing.indirect:
            case Opcode.addressing.indirectX:
            case Opcode.addressing.indirectY:
            case Opcode.addressing.relative:
            case Opcode.addressing.absoluteIndexedX:
            case Opcode.addressing.absoluteIndexedY:
            default:
                return(false);
            }
        }
示例#4
0
        private static void SetOpcodeError(int sourceLine, string instructionString, Opcode.addressing addressing, int opcodeVal, out Error error)
        {
            var errorCode = (OpcodeError)opcodeVal;

            switch (errorCode)
            {
            case OpcodeError.UnknownInstruction:
                error = new Error(ErrorCode.Invalid_Instruction, Error.Msg_InstructionUndefined, sourceLine);
                break;

            case OpcodeError.InvalidAddressing:
                error = new Error(ErrorCode.Invalid_Instruction, Error.Msg_InstructionBadAddressing, sourceLine);
                break;

            case OpcodeError.InvalidOpcode:
                error = new Error(ErrorCode.Invalid_Instruction, Error.Msg_OpcodeInvalid, sourceLine);
                break;

            default:
                System.Diagnostics.Debug.Fail("Unexpected error.");
                error = new Error(ErrorCode.Engine_Error, Error.Msg_Engine_InvalidState);
                break;
            }
        }
示例#5
0
        // Todo: Move TryToConvertToZeroPage and FindOpcode to another class, probably assembler.
        // (The only reason they need to be instance methods is for AllowInvalidOpcodes, but this
        //  could also be specified as a parameter).
        public bool TryToConvertToZeroPage(ref ParsedInstruction instruction)
        {
            var op         = Opcode.allOps[instruction.opcode];
            var addressing = op.addressing;

            Opcode.addressing newAddressing = addressing;

            switch (addressing)
            {
            case Opcode.addressing.absolute:
                newAddressing = Opcode.addressing.zeropage;
                break;

            case Opcode.addressing.absoluteIndexedX:
                newAddressing = Opcode.addressing.zeropageIndexedX;
                break;

            case Opcode.addressing.absoluteIndexedY:
                newAddressing = Opcode.addressing.zeropageIndexedY;
                break;
            }

            if (addressing == newAddressing)
            {
                return(false);
            }

            int newOpcode = FindOpcode(op.name, newAddressing);

            if (newOpcode >= 0)
            {
                instruction = new ParsedInstruction(instruction, (byte)newOpcode);
                return(true);
            }
            return(false);
        }