Exemplo n.º 1
0
        public static int GetIntermediateAddress(int offset, bool resolve)
        {
            int bank, directPage, operand, programCounter;
            int opcode = Data.GetROMByte(offset);

            AddressMode mode = GetAddressMode(offset);

            switch (mode)
            {
            case AddressMode.DIRECT_PAGE:
            case AddressMode.DIRECT_PAGE_X_INDEX:
            case AddressMode.DIRECT_PAGE_Y_INDEX:
            case AddressMode.DIRECT_PAGE_INDIRECT:
            case AddressMode.DIRECT_PAGE_X_INDEX_INDIRECT:
            case AddressMode.DIRECT_PAGE_INDIRECT_Y_INDEX:
            case AddressMode.DIRECT_PAGE_LONG_INDIRECT:
            case AddressMode.DIRECT_PAGE_LONG_INDIRECT_Y_INDEX:
                if (resolve)
                {
                    directPage = Data.GetDirectPage(offset);
                    operand    = Data.GetROMByte(offset + 1);
                    return((directPage + operand) & 0xFFFF);
                }
                else
                {
                    goto case AddressMode.DIRECT_PAGE_S_INDEX;
                }

            case AddressMode.DIRECT_PAGE_S_INDEX:
            case AddressMode.DIRECT_PAGE_S_INDEX_INDIRECT_Y_INDEX:
                return(Data.GetROMByte(offset + 1));

            case AddressMode.ADDRESS:
            case AddressMode.ADDRESS_X_INDEX:
            case AddressMode.ADDRESS_Y_INDEX:
            case AddressMode.ADDRESS_X_INDEX_INDIRECT:
                bank = (opcode == 0x20 || opcode == 0x4C || opcode == 0x7C || opcode == 0xFC) ?
                       Util.ConvertPCtoSNES(offset) >> 16 :
                       Data.GetDataBank(offset);
                operand = Util.GetROMWord(offset + 1);
                return((bank << 16) | operand);

            case AddressMode.ADDRESS_INDIRECT:
            case AddressMode.ADDRESS_LONG_INDIRECT:
                operand = Util.GetROMWord(offset + 1);
                return(operand);

            case AddressMode.LONG:
            case AddressMode.LONG_X_INDEX:
                operand = Util.GetROMLong(offset + 1);
                return(operand);

            case AddressMode.RELATIVE_8:
                programCounter = Util.ConvertPCtoSNES(offset + 2);
                bank           = programCounter >> 16;
                offset         = (sbyte)Data.GetROMByte(offset + 1);
                return((bank << 16) | ((programCounter + offset) & 0xFFFF));

            case AddressMode.RELATIVE_16:
                programCounter = Util.ConvertPCtoSNES(offset + 3);
                bank           = programCounter >> 16;
                offset         = (short)Util.GetROMWord(offset + 1);
                return((bank << 16) | ((programCounter + offset) & 0xFFFF));
            }
            return(-1);
        }
Exemplo n.º 2
0
        public static int Step(int offset, bool branch, bool force, int prevOffset)
        {
            int  opcode = Data.GetROMByte(offset);
            int  prevDirectPage = Data.GetDirectPage(offset);
            int  prevDataBank = Data.GetDataBank(offset);
            bool prevX = Data.GetXFlag(offset), prevM = Data.GetMFlag(offset);

            while (prevOffset >= 0 && Data.GetFlag(prevOffset) == Data.FlagType.Operand)
            {
                prevOffset--;
            }
            if (prevOffset >= 0 && Data.GetFlag(prevOffset) == Data.FlagType.Opcode)
            {
                prevDirectPage = Data.GetDirectPage(prevOffset);
                prevDataBank   = Data.GetDataBank(prevOffset);
                prevX          = Data.GetXFlag(prevOffset);
                prevM          = Data.GetMFlag(prevOffset);
            }

            if (opcode == 0xC2 || opcode == 0xE2) // REP SEP
            {
                prevX = (Data.GetROMByte(offset + 1) & 0x10) != 0 ? opcode == 0xE2 : prevX;
                prevM = (Data.GetROMByte(offset + 1) & 0x20) != 0 ? opcode == 0xE2 : prevM;
            }

            // set first byte first, so the instruction length is correct
            Data.SetFlag(offset, Data.FlagType.Opcode);
            Data.SetDataBank(offset, prevDataBank);
            Data.SetDirectPage(offset, prevDirectPage);
            Data.SetXFlag(offset, prevX);
            Data.SetMFlag(offset, prevM);

            int length = GetInstructionLength(offset);

            for (int i = 1; i < length; i++)
            {
                Data.SetFlag(offset + i, Data.FlagType.Operand);
                Data.SetDataBank(offset + i, prevDataBank);
                Data.SetDirectPage(offset + i, prevDirectPage);
                Data.SetXFlag(offset + i, prevX);
                Data.SetMFlag(offset + i, prevM);
            }

            MarkInOutPoints(offset);

            int nextOffset = offset + length;

            if (!force && (opcode == 0x4C || opcode == 0x5C || opcode == 0x80 || opcode == 0x82 || // JMP JML BRA BRL
                           (branch && (opcode == 0x10 || opcode == 0x30 || opcode == 0x50 || // BPL BMI BVC
                                       opcode == 0x70 || opcode == 0x90 || opcode == 0xB0 || opcode == 0xD0 || // BVS BCC BCS BNE
                                       opcode == 0xF0 || opcode == 0x20 || opcode == 0x22)))) // BEQ JSR JSL
            {
                int iaNextOffsetPC = Util.ConvertSNEStoPC(Util.GetIntermediateAddress(offset, true));
                if (iaNextOffsetPC >= 0)
                {
                    nextOffset = iaNextOffsetPC;
                }
            }

            return(nextOffset);
        }