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); }
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); }