public static int CreateLog(StreamWriter sw, StreamWriter er) { Dictionary <int, string> tempAlias = Data.GetAllLabels(); Data.Restore(a: new Dictionary <int, string>(tempAlias)); bankSize = Data.GetROMMapMode() == Data.ROMMapMode.LoROM ? 0x8000 : 0x10000; AddTemporaryLabels(); string[] split = format.Split('%'); err = er; errorCount = 0; list = new List <Tuple <string, int> >(); for (int i = 0; i < split.Length; i++) { if (i % 2 == 0) { list.Add(Tuple.Create(split[i], int.MaxValue)); } else { int colon = split[i].IndexOf(':'); if (colon < 0) { list.Add(Tuple.Create(split[i], parameters[split[i]].Item2)); } else { list.Add(Tuple.Create(split[i].Substring(0, colon), int.Parse(split[i].Substring(colon + 1)))); } } } int pointer = 0, size = (Data.GetTable() == ExportDisassembly.sampleTable) ? 0x7B : Data.GetROMSize(), bank = -1; if (structure == FormatStructure.OneBankPerFile) { folder = Path.GetDirectoryName(((FileStream)sw.BaseStream).Name); sw.WriteLine(GetLine(pointer, "map")); sw.WriteLine(GetLine(pointer, "bankcross")); sw.WriteLine(GetLine(pointer, "empty")); for (int i = 0; i < size; i += bankSize) { sw.WriteLine(GetLine(i, "incsrc")); } } else { sw.WriteLine(GetLine(pointer, "map")); sw.WriteLine(GetLine(pointer, "bankcross")); sw.WriteLine(GetLine(pointer, "empty")); } while (pointer < size) { int snes = Util.ConvertPCtoSNES(pointer); if ((snes >> 16) != bank) { if (structure == FormatStructure.OneBankPerFile) { sw.Close(); sw = new StreamWriter(string.Format("{0}/bank_{1}.asm", folder, Util.NumberToBaseString((snes >> 16), Util.NumberBase.Hexadecimal, 2))); } sw.WriteLine(GetLine(pointer, "empty")); sw.WriteLine(GetLine(pointer, "org")); sw.WriteLine(GetLine(pointer, "empty")); if ((snes % bankSize) != 0) { err.WriteLine("({0}) Offset 0x{1:X}: An instruction crossed a bank boundary.", ++errorCount, pointer); } bank = snes >> 16; } string label; if ((Data.GetInOutPoint(pointer) & (Data.InOutPoint.ReadPoint)) != 0 || (tempAlias.TryGetValue(pointer, out label) && label.Length > 0)) { sw.WriteLine(GetLine(pointer, "empty")); } sw.WriteLine(GetLine(pointer, null)); if ((Data.GetInOutPoint(pointer) & (Data.InOutPoint.EndPoint)) != 0) { sw.WriteLine(GetLine(pointer, "empty")); } pointer += GetLineByteLength(pointer); } if (structure == FormatStructure.OneBankPerFile) { sw.Close(); } Data.Restore(a: tempAlias); return(errorCount); }
// length forced to 4 private static string GetDirectPage(int offset, int length) { return(Util.NumberToBaseString(Data.GetDirectPage(offset), Util.NumberBase.Hexadecimal, 4)); }
// length forced to 2 private static string GetDataBank(int offset, int length) { return(Util.NumberToBaseString(Data.GetDataBank(offset), Util.NumberBase.Hexadecimal, 2)); }
// trim to length private static string GetComment(int offset, int length) { return(string.Format("{0," + (length * -1) + "}", Data.GetComment(offset))); }
private static int GetLineByteLength(int offset) { int max = 1, step = 1; int size = Data.GetROMSize(); switch (Data.GetFlag(offset)) { case Data.FlagType.Opcode: switch (Data.GetArchitechture(offset)) { case Data.Architechture.CPU65C816: return(CPU65C816.GetInstructionLength(offset)); case Data.Architechture.APUSPC700: return(1); case Data.Architechture.GPUSuperFX: return(1); } return(1); case Data.FlagType.Unreached: case Data.FlagType.Operand: case Data.FlagType.Data8Bit: case Data.FlagType.Graphics: case Data.FlagType.Music: case Data.FlagType.Empty: max = dataPerLine; break; case Data.FlagType.Text: max = 21; break; case Data.FlagType.Data16Bit: step = 2; max = dataPerLine; break; case Data.FlagType.Data24Bit: step = 3; max = dataPerLine; break; case Data.FlagType.Data32Bit: step = 4; max = dataPerLine; break; case Data.FlagType.Pointer16Bit: step = 2; max = 2; break; case Data.FlagType.Pointer24Bit: step = 3; max = 3; break; case Data.FlagType.Pointer32Bit: step = 4; max = 4; break; } int min = step, myBank = offset / bankSize; while ( min < max && offset + min < size && Data.GetFlag(offset + min) == Data.GetFlag(offset) && Data.GetLabel(offset + min) == "" && (offset + min) / bankSize == myBank ) { min += step; } return(min); }
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); 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); }