private static string GetLine(int offset, string special) { string line = ""; for (int i = 0; i < list.Count; i++) { if (list[i].Item2 == int.MaxValue) // string literal { line += list[i].Item1; } else if (special != null) // special parameter (replaces code & everything else = empty) { line += GetParameter(offset, "%" + (list[i].Item1 == "code" ? special : "empty"), list[i].Item2); } else // normal parameter { line += GetParameter(offset, list[i].Item1, list[i].Item2); } } if (special == null) { // throw out some errors if stuff looks fishy Data.FlagType flag = Data.GetFlag(offset), check = flag == Data.FlagType.Opcode ? Data.FlagType.Operand : flag; int step = flag == Data.FlagType.Opcode ? GetLineByteLength(offset) : Util.TypeStepSize(flag), size = Data.GetROMSize(); if (flag == Data.FlagType.Operand) { err.WriteLine("({0}) Offset 0x{1:X}: Bytes marked as operands formatted as data.", ++errorCount, offset); } else if (step > 1) { for (int i = 1; i < step; i++) { if (offset + i >= size) { err.WriteLine("({0}) Offset 0x{1:X}: {2} extends past the end of the ROM.", ++errorCount, offset, Util.TypeToString(check)); break; } else if (Data.GetFlag(offset + i) != check) { err.WriteLine("({0}) Offset 0x{1:X}: Expected {2}, but got {3} instead.", ++errorCount, offset + i, Util.TypeToString(check), Util.TypeToString(Data.GetFlag(offset + i))); break; } } } int ia = Util.GetIntermediateAddress(offset, true); if (ia >= 0 && flag == Data.FlagType.Opcode && Data.GetInOutPoint(offset) == Data.InOutPoint.OutPoint && Data.GetFlag(Util.ConvertSNEStoPC(ia)) != Data.FlagType.Opcode) { err.WriteLine("({0}) Offset 0x{1:X}: Branch or jump instruction to a non-instruction.", ++errorCount, offset); } } return(line); }
private static string FormatOperandAddress(int offset, AddressMode mode) { int address = Util.GetIntermediateAddress(offset); if (address < 0) { return(""); } if (Data.GetLabel(address) != "") { return(Data.GetLabel(address)); } int count = BytesToShow(mode); if (mode == AddressMode.RELATIVE_8 || mode == AddressMode.RELATIVE_16) { address = Util.GetROMWord(offset + 1); } address &= ~(-1 << (8 * count)); return(Util.NumberToBaseString(address, Util.NumberBase.Hexadecimal, 2 * count, true)); }
public static void MarkInOutPoints(int offset) { int opcode = Data.GetROMByte(offset); int iaOffsetPC = Util.ConvertSNEStoPC(Util.GetIntermediateAddress(offset, true)); // set read point on EA if (iaOffsetPC >= 0 && ( // these are all read/write/math instructions ((opcode & 0x04) != 0) || ((opcode & 0x0F) == 0x01) || ((opcode & 0x0F) == 0x03) || ((opcode & 0x1F) == 0x12) || ((opcode & 0x1F) == 0x19)) && (opcode != 0x45) && (opcode != 0x55) && (opcode != 0xF5) && (opcode != 0x4C) && (opcode != 0x5C) && (opcode != 0x6C) && (opcode != 0x7C) && (opcode != 0xDC) && (opcode != 0xFC) ) { Data.SetInOutPoint(iaOffsetPC, Data.InOutPoint.ReadPoint); } // set end point on offset if (opcode == 0x40 || opcode == 0x4C || opcode == 0x5C || opcode == 0x60 || // RTI JMP JML RTS opcode == 0x6B || opcode == 0x6C || opcode == 0x7C || opcode == 0x80 || // RTL JMP JMP BRA opcode == 0x82 || opcode == 0xDB || opcode == 0xDC // BRL STP JML ) { Data.SetInOutPoint(offset, Data.InOutPoint.EndPoint); } // set out point on offset // set in point on EA if (iaOffsetPC >= 0 && ( opcode == 0x4C || opcode == 0x5C || opcode == 0x80 || opcode == 0x82 || // JMP JML BRA BRL opcode == 0x10 || opcode == 0x30 || opcode == 0x50 || opcode == 0x70 || // BPL BMI BVC BVS opcode == 0x90 || opcode == 0xB0 || opcode == 0xD0 || opcode == 0xF0 || // BCC BCS BNE BEQ opcode == 0x20 || opcode == 0x22)) // JSR JSL { Data.SetInOutPoint(offset, Data.InOutPoint.OutPoint); Data.SetInOutPoint(iaOffsetPC, Data.InOutPoint.InPoint); } }
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); }