uint ScanNazo8DataPointerTable(uint pointer, string prefix, ROM rom) { uint startAddr = U.toOffset(pointer); uint addr = startAddr; for (int i = 0; addr < rom.Data.Length; addr += 4, i++) { uint d = rom.u32(addr); if (!U.isSafetyPointer(d, rom)) { break; } if (this.AsmMap.ContainsKey(d)) { continue; } AsmMapSt p = new AsmMapSt(); p.Length = 8; p.Name = prefix + " NAZO8 " + U.ToHexString(i); this.AsmMap[d] = p; } return(addr - startAddr); }
uint ScanASMPointerTable(uint pointer, string prefix, ROM rom) { uint startAddr = U.toOffset(pointer); uint addr = startAddr; for (int i = 0; addr < rom.Data.Length; addr += 4, i++) { uint d = rom.u32(addr); if (!U.isSafetyPointer(d, rom)) { break; } d = DisassemblerTrumb.ProgramAddrToPlain(d); if (this.AsmMap.ContainsKey(d)) { continue; } AsmMapSt p = new AsmMapSt(); p.Length = 0; p.Name = prefix + " ASM " + U.ToHexString(i); this.AsmMap[d] = p; } return(addr - startAddr); }
public void AppendMAP(Dictionary <uint, uint> dic) { foreach (var pair in dic) { { uint length = 4; uint pointer = pair.Key; pointer = U.toPointer(pointer); if (!U.isSafetyPointer(pointer)) { continue; } AsmMapSt a; if (AsmMap.TryGetValue(pointer, out a)) { //既に知っている if (a.Length >= length) { //既に知っているデータより長いデータではないので無視する continue; } if (a.TypeName.Length > 0) {//相手側にtypeが指定されており、現在追加するのはタイプが指定されていない continue; } } AsmMapSt p = new AsmMapSt(); p.Name = R._("SWITCH CASE"); p.ResultAndArgs = R._("とび先のコード:{0}", U.ToHexString(pointer)); p.Length = length; AsmMap[pointer] = p; } } }
public static void ROMInfoLoadResource(Dictionary <uint, AsmMapSt> asmMap, bool isWithOutProcs) { //せっかくなので、ROMで判明しているデータも追加する. MethodInfo[] methods = Program.ROM.RomInfo.GetType().GetMethods(); foreach (MethodInfo info in methods) { if (isWithOutProcs) { if (info.Name.IndexOf("procs") >= 0) { continue; } } if (info.Name.IndexOf("_pointer") >= 0) { uint addr = (uint)info.Invoke(Program.ROM.RomInfo, null); addr = U.toOffset(addr); if (addr > 0 && U.isSafetyOffset(addr)) { uint pointer = U.toPointer(addr); AsmMapSt p = new AsmMapSt(); p.Name = info.Name; asmMap[pointer] = p; uint pointer2 = Program.ROM.u32(addr); if (U.isPointer(pointer2)) { p = new AsmMapSt(); p.Name = info.Name.Replace("_pointer", "_address"); asmMap[pointer2] = p; } } } if (info.Name.IndexOf("_address") >= 0) { uint addr = (uint)info.Invoke(Program.ROM.RomInfo, null); addr = U.toOffset(addr); if (addr > 0 && U.isSafetyOffset(addr)) { uint pointer = U.toPointer(addr); AsmMapSt p = new AsmMapSt(); p.Name = info.Name; asmMap[pointer] = p; } } } }
uint ScanSECONDARYOAMTable(uint pointer, string prefix, ROM rom) { uint startAddr = U.toOffset(pointer); uint addr = startAddr; for (int i = 0; addr < rom.Data.Length; addr += 4, i++) { uint d = rom.u32(addr); if (!U.isSafetyPointer(d, rom)) { break; } AsmMapSt p = new AsmMapSt(); p.Length = 14; p.Name = prefix + " SECONDARYOAM " + U.ToHexString(i); this.AsmMap[d] = p; } return(addr - startAddr); }
uint ScanOAMREGSTable(uint pointer, string prefix, ROM rom) { uint startAddr = U.toOffset(pointer); uint addr = startAddr; for ( ; addr < rom.Data.Length; addr += 4) { uint d = rom.u32(addr); if (!U.isSafetyPointer(d)) { break; } AsmMapSt p = new AsmMapSt(); p.Length = U.OAMREGSLength(U.toOffset(d), rom); p.Name = prefix + " Count_" + ((p.Length - 2) / (3 * 2)); this.AsmMap[d] = p; } return(addr - startAddr); }
public void AppendMAP(List <Address> list, string typeName = "") { for (int i = 0; i < list.Count; i++) { uint pointer = list[i].Addr; if (pointer == U.NOT_FOUND || pointer <= 1) { continue; } pointer = U.toPointer(pointer); if (!U.isSafetyPointer(pointer)) { continue; } AsmMapSt a; if (AsmMap.TryGetValue(pointer, out a)) { //既に知っている if (a.Length >= list[i].Length) { //既に知っているデータより長いデータではないので無視する continue; } if (a.TypeName.Length > 0 && typeName.Length <= 0) {//相手側にtypeが指定されており、現在追加するのはタイプが指定されていない continue; } } AsmMapSt p = new AsmMapSt(); p.Name = list[i].Info; p.ResultAndArgs = ""; p.Length = list[i].Length; p.TypeName = typeName; if (list[i].DataType == Address.DataTypeEnum.FFor00) {//フリーエリア p.IsFreeArea = true; } if (p.Name == "") { p.Name = "_" + U.ToHexString(pointer); } AsmMap[pointer] = p; } for (int i = 0; i < list.Count; i++) { uint pointer = list[i].Pointer; if (pointer == U.NOT_FOUND || pointer <= 1) { continue; } pointer = U.toPointer(pointer); if (!U.isSafetyPointer(pointer)) { continue; } if (AsmMap.ContainsKey(pointer)) { continue; } AsmMapSt p = new AsmMapSt(); p.Name = list[i].Info; p.ResultAndArgs = ""; p.Length = 0; p.TypeName = typeName; p.IsPointer = true; if (p.Name == "") { p.Name = "_" + U.ToHexString(pointer); } AsmMap[pointer] = p; } }
void TypeToLengthAndName(AsmMapSt p, uint pointer, ROM rom) { string type = p.TypeName; if (type == "LZ77") { p.Length = LZ77.getCompressedSize(rom.Data, U.toOffset(pointer)); } else if (type == "OAMREGS") { p.Length = U.OAMREGSLength(U.toOffset(pointer), rom); p.Name += " Count_" + ((p.Length - 2) / (3 * 2)); } else if (type == "OAMREGS_ARRAY") { p.Length = ScanOAMREGSTable(pointer, p.Name, rom); } else if (type == "TEXTBATCH") { p.Length = U.TextBatchLength(U.toOffset(pointer), rom); p.Name += " Count_" + ((p.Length) / 8); } else if (type == "TEXTBATCHSHORT") { p.Length = U.TextBatchShortLength(U.toOffset(pointer), rom); p.Name += " Count_" + ((p.Length) / 2); } else if (type == "EVENT") { p.Length = EventScript.SearchEveneLength(rom.Data, U.toOffset(pointer)); p.Name += " Count_" + ((p.Length - 2) / (3 * 2)); } else if (type == "HEADERTSA") { p.Length = ImageUtil.CalcByteLengthForHeaderTSAData(rom.Data, (int)U.toOffset(pointer)); } else if (type == "ROMPALETTEANIMEFRAME") { p.Length = ImageRomAnimeForm.GetPaletteFrameCountLow(rom.Data, U.toOffset(pointer)) * 2; } else if (type == "PALETTE") { p.Length = 0x20; } else if (type == "PALETTE2") { p.Length = 0x20 * 2; } else if (type == "PALETTE3") { p.Length = 0x20 * 3; } else if (type == "PALETTE4") { p.Length = 0x20 * 4; } else if (type == "PALETTE8") { p.Length = 0x20 * 8; } else if (type == "PALETTE7") { p.Length = 0x20 * 7; } else if (type == "PALETTE16") { p.Length = 0x20 * 16; } else if (type == "ROMTCS") { p.Length = ImageUtilAP.CalcROMTCSLength(U.toOffset(pointer), rom); } else if (type == "NAZO60") { p.Length = 60; } else if (type == "FONTCOLOR0x200") { p.Length = 0x200; } else if (type == "NewPopupSimple") { p.Length = ImageUtilAP.CalcPopupSimpleLength(U.toOffset(pointer), rom); } else if (type == "SECONDARYOAM") { p.Length = 14; } else if (type == "SECONDARYOAM_ARRAY") { p.Length = ScanSECONDARYOAMTable(pointer, p.Name, rom); } else if (type == "CSTRING") { int length; string strname = rom.getString(U.toOffset(pointer), out length); p.Length = (uint)length; p.Name += " => " + strname; } else if (type == "SOUND_85COMMAND_POINTER_ARRAY") { p.Length = ScanSOUND85COMMANDPointerTable(pointer, p.Name, rom); } else if (type == "ASM_POINTER_ARRAY") { p.Length = ScanASMPointerTable(pointer, p.Name, rom); } else if (type == "PROC") { uint length = ProcsScriptForm.CalcLengthAndCheck(U.toOffset(pointer)); if (length != U.NOT_FOUND) { p.Length = length; } } else if (type == "NAZO8_DATA_POINTER_ARRAY") { p.Length = ScanNazo8DataPointerTable(pointer, p.Name, rom); } else if (type == "ASM") { p.Length = 0; } else if (type == "BGCONFIG") { p.Length = 10 * 2; } }
Dictionary <string, AsmStruct> AsmStructs = new Dictionary <string, AsmStruct>(); //コメントデータ. void ASMMapLoadResource(string fullfilename, ROM rom) { if (!U.IsRequiredFileExist(fullfilename)) { return; } //ユーザが定義したmapファイル using (StreamReader reader = File.OpenText(fullfilename)) { string line; while ((line = reader.ReadLine()) != null) { if (U.IsComment(line) || U.OtherLangLine(line, rom)) { continue; } line = U.ClipComment(line); string[] sp = line.Split('\t'); if (sp.Length <= 1) { continue; } string op = sp[0]; if (op.Length <= 0) { continue; } if (op[0] == '@') {//struct定義 continue; } uint pointer = U.toPointer(U.atoh(op)); if (pointer < 0x02000000) { continue; } if (sp[1].Length <= 0) { continue; } if (sp[1][0] == '@') {//structを利用している if (sp.Length <= 2) { continue; } string[] types = sp[1].Split('@'); if (types.Length <= 1) { continue; } //配列指定. Cとは違い型の方につけます。 @STRUCT@[A] 値は16進数です. uint count = 0; if (types.Length >= 3) { if (types[2].Length <= 0 && types[2][0] != '[') { Debug.Assert(false); continue; } count = U.atoh(U.substr(types[2], 1)); if (count <= 0) { Debug.Assert(false); } } string structName = types[1]; if (!AsmStructs.ContainsKey(structName)) { Debug.Assert(false); continue; } AsmStruct asmSt = AsmStructs[structName]; if (count <= 1) { for (int i = 0; i < asmSt.Nodes.Count; i++) { AsmStructNode node = asmSt.Nodes[i]; AsmMapSt p = new AsmMapSt(); //p.Pointer = pointer; //keyに移動. string name; ParseFuncName(sp, out name); p.Name = structName + "@" + name + "." + node.Name; if (node.TypeName == "") { p.ResultAndArgs = node.Comment; p.TypeName = ""; } else { p.ResultAndArgs = "RET=@" + node.TypeName + " " + node.Comment; p.TypeName = node.TypeName; } AsmMap[pointer + node.Offset] = p; } } else { for (uint n = 0; n < count; n++) { for (int i = 0; i < asmSt.Nodes.Count; i++) { AsmStructNode node = asmSt.Nodes[i]; AsmMapSt p = new AsmMapSt(); string name; ParseFuncName(sp, out name); //p.Pointer = pointer; //keyに移動. p.Name = structName + "@" + name + "[" + n + "]" + "." + node.Name; p.ResultAndArgs = node.Comment; p.TypeName = node.TypeName; AsmMap[pointer + node.Offset] = p; } pointer += asmSt.SizeOf; } } } else if (sp[1][0] == ':') {//範囲指定 絶対指定 if (sp.Length <= 2) { continue; } uint endpointer = U.toPointer(U.atoh(sp[1].Substring(1))); if (endpointer == 0) { Debug.Assert(false); endpointer = pointer; } else if (pointer > endpointer) { Debug.Assert(false); U.Swap(ref pointer, ref endpointer); } AsmMapSt p = new AsmMapSt(); //p.Pointer = pointer; //keyに移動. ParseFuncNamePlus(sp, out p.Name, out p.ResultAndArgs, out p.TypeName); p.Length = endpointer - pointer; AsmMap[pointer] = p; } else {//structを利用していない 範囲してもしない AsmMapSt p = new AsmMapSt(); //p.Pointer = pointer; //keyに移動. ParseFuncNamePlus2(sp, out p.Name, out p.ResultAndArgs, out p.TypeName); TypeToLengthAndName(p, pointer, rom); AsmMap[pointer] = p; } } } }