/* * Copyright (C) 2012 Dale C. Schultz * RomRaider member ID: dschultz * * You are free to use this script for any purpose, but please keep * notice of where it came from! * * Version: 5 * Date : 2012-11-18 * * To use this script you must locate the bounds of the map table * definitions in the ROM. For a 32bit ROM this is in the 0x82000 * to 0x83000 area. Locate the ending of these definitions and copy * the address. Move the cursor to beginning and start the script. * Paste in the end address when requested. * Check for warnings at the end of the script. A rom_def.xml file * will be written to the directory where the ROM is located. This * file can be used with RomRaider Editor to view the RAW formatted * tables. */ #include static main() { auto currAddr, endAddr, lastAddr, globals, fout, size, maxSize, calIdAddr, calId, ync, nextTable; calIdAddr = Word(SegEnd(0) - 2); calId = GetString(calIdAddr, 8, ASCSTR_C); ync = AskYN(1,calId + ", is this the correct CAL ID?"); // -1:cancel,0-no,1-ok if (ync == -1) { return 0;} if (ync == 0 ) { calIdAddr = AskAddr(0x2000,"Enter the address where the CAL ID is stored,\n typically 2000, 2004 400C:"); calId = GetString(calIdAddr, 8, ASCSTR_C); } globals = GetArrayId("myGlobals"); DeleteArray(globals); globals = CreateArray("myGlobals"); fout = fopen("rom_def.xml", "w"); SetArrayLong(globals, 0, fout); writestr(fout, "\n\n \n " + calId + "\n " + ltoa(calIdAddr, 16) + "\n"); writestr(fout, " " + calId + "\n 0123456789\n 05\n"); writestr(fout, " USDM\n Subaru\n CarModel\n 2.5\n"); writestr(fout, " MT\n SH7058\n sti05\n"); writestr(fout, " 1024kb\n \n"); currAddr = AskAddr(0,"Enter a start address or leave at 0 to use the current cursor position:"); endAddr = AskAddr(0,"Enter end address:"); if (currAddr == 0){ currAddr = here; } nextTable = currAddr; while (currAddr <= endAddr) { // 1 axis table with no data conversion values, undefined data type // Table Definition is 12 bytes long with the format: // word = axis length // word = data storage type // dword = axis address //dword = data address if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && (Word(currAddr+2) == 0x0000) && (((Word(currAddr+12) > 0) && (Word(currAddr+12) < 256)) && ((Word(currAddr+14) >= 0) && (Word(currAddr+14) < 4097)))) { nextTable = nextTable + 12; lastAddr = currAddr; currAddr = Make2dRawTable(currAddr); size = currAddr+1-lastAddr; Message("Table 2D, size:" + form("%d", size) + ", data:raw, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } // 1 axis table with data conversion values and defined data type // Table Definition is 20 bytes long with the format: // word = axis length // word = data storage type // dword = axis address // dword = data address // float = data multiplier // float = data additive if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && ((Word(currAddr+2) == 0x0400) || (Word(currAddr+2) == 0x0800) || (Word(currAddr+2) == 0x0C00) || (Word(currAddr+2) == 0x1000)) && (((Word(currAddr+20) > 0) && (Word(currAddr+20) < 256)) && ((Word(currAddr+22) >= 0) && (Word(currAddr+22) < 4097)))) { nextTable = nextTable + 20; lastAddr = currAddr; currAddr = Make2dUintTable(currAddr); size = currAddr+1-lastAddr; Message("Table 2D, size:" + form("%d", size) + ", data:int, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } // 1 axis table with no data conversion values and defined data type // Table Definition is 12 bytes long with the format: // word = axis length // word = data storage type // dword = axis address // dword = data address if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && ((Word(currAddr+2) == 0x0400) || (Word(currAddr+2) == 0x0800) || (Word(currAddr+2) == 0x0C00) || (Word(currAddr+2) == 0x1000)) && (((Word(currAddr+12) > 0) && (Word(currAddr+12) < 256)) && ((Word(currAddr+14) >= 0) && (Word(currAddr+14) < 4097)))) { nextTable = nextTable + 12; lastAddr = currAddr; currAddr = Make2dUintTableNoConv(currAddr); size = currAddr+1-lastAddr; Message("Table 2D, size:" + form("%d", size) + ", data:int, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } // 2 axis table with no data conversion values, defined data type // Table Definition is 20 bytes long with the format: // word = X axis length // word = Y axis length // dword = X axis address // dword = Y axis address // dword = data address // word = data storage type if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && ((Word(currAddr+2) > 0) && (Word(currAddr+2) < 256)) && ((Dword(currAddr+16) == 0x04000000) || (Dword(currAddr+16) == 0x08000000) || (Dword(currAddr+16) == 0x0C000000) || (Dword(currAddr+16) == 0x10000000)) && (((Word(currAddr+20) > 0) && (Word(currAddr+20) < 256)) && ((Word(currAddr+22) >= 0) && (Word(currAddr+22) < 4097)))) { nextTable = nextTable + 20; lastAddr = currAddr; currAddr = Make3dUintTableNoConv(currAddr); size = currAddr+1-lastAddr; Message("Table 3D, size:" + form("%d", size) + ", data:int, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } // 2 axis table with no data conversion values, undefined data type // Table Definition is 20 bytes long with the format: // word = X axis length // word = Y axis length // dword = X axis address // dword = Y axis address // dword = data address // word = data storage type if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && ((Word(currAddr+2) > 0) && (Word(currAddr+2) < 256)) && (Dword(currAddr+16) == 0x00000000) && (((Word(currAddr+20) > 0) && (Word(currAddr+20) < 256)) && ((Word(currAddr+22) >= 0) && (Word(currAddr+22) < 4097)))) { nextTable = nextTable + 20; lastAddr = currAddr; currAddr = Make3dRawTable(currAddr); size = currAddr+1-lastAddr; Message("Table 3D, size:" + form("%d", size) + ", data:raw, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } // 2 axis table with data conversion values and defined data type // Table Definition is 28 bytes long with the format: // word = X axis length // word = Y axis length // dword = X axis address // dword = Y axis address // dword = data address // word = data storage type // float = data multiplier // float = data additive if (((Word(currAddr) > 0) && (Word(currAddr) < 256)) && ((Word(currAddr+2) > 0) && (Word(currAddr+2) < 256)) && ((Dword(currAddr+16) == 0x04000000) || (Dword(currAddr+16) == 0x08000000) || (Dword(currAddr+16) == 0x0C000000) || (Dword(currAddr+16) == 0x10000000)) && (((Word(currAddr+28) > 0) && (Word(currAddr+28) < 256)) && ((Word(currAddr+30) >= 0) && (Word(currAddr+30) < 4097)))) { nextTable = nextTable + 28; lastAddr = currAddr; currAddr = Make3dUintTable(currAddr); size = currAddr+1-lastAddr; Message("Table 3D, size:" + form("%d", size) + ", data:int, ROM:0x" + ltoa(lastAddr, 16) + ", " + GetArrayElement(AR_STR, globals, 1)); lastAddr = currAddr+1; } if (size > maxSize) { maxSize = size; } // Message("Next table expected at ROM:0x" + ltoa(lastAddr, 16) + "\n"); SetArrayString(globals, 1, "\n"); currAddr = currAddr+1; } writestr(fout, "\n\n"); fclose(fout); DeleteArray(globals); if (maxSize > 28) { Message("WARNING: Table definitions found that are greater than 28 bytes long. These tables need attention\n"); } else { Message("Finished, no warnings BUT the last table may not have been defined.\n You should double check it. ROM:0x" + ltoa(lastAddr, 16) + "\n"); } } static Make2dRawTable(currAddr) { auto axisAddr, dataAddr, dataLength, dataType, dataAlign, x, fMin, fMax, fNum, fNumNext; fMin = 0 - 66000.1; fMax = 66000.; MakeUnknown(currAddr, 12, DOUNK_SIMPLE); MakeWord(currAddr); // length dataLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // no data conversion currAddr = currAddr+2; MakeDword(currAddr); // axis address axisAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data address dataAddr = Dword(currAddr); currAddr = currAddr+3; FormatTableAxis(axisAddr, dataLength); dataAlign = dataLength % 0x2; if (DfirstB((dataAddr + (dataLength + dataAlign))) != BADADDR) { dataType = 0x04; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else if (DfirstB(dataAddr + ((dataLength + dataAlign)*2)) != BADADDR) { dataType = 0x08; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else if (DfirstB(dataAddr + (dataLength*4)) != BADADDR) { fNum = GetFpNum(dataAddr,4); fNumNext = GetFpNum(dataAddr+4,4); if ((fNum >= fMin && fNum <= fMax && fNumNext >= fMin && fNumNext <= fMax) || Dword(dataAddr) == 0) { dataType = "float"; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else { dataType = "float"; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } } Print2dTable(axisAddr, dataAddr, dataLength, dataType, 1, 0); return currAddr; } static Make2dUintTable(currAddr) { auto axisAddr, dataAddr, dataLength, dataType, dataM, dataA; MakeUnknown(currAddr, 20, DOUNK_SIMPLE); MakeWord(currAddr); // length dataLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // data type and conversion dataType = Byte(currAddr); currAddr = currAddr+2; MakeDword(currAddr); // axis address axisAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data addreess dataAddr = Dword(currAddr); currAddr = currAddr+4; MakeFloat(currAddr); // multiplier dataM = GetFpNum(currAddr,4); currAddr = currAddr+4; MakeFloat(currAddr); // additive dataA = GetFpNum(currAddr,4); currAddr = currAddr+3; FormatTableAxis(axisAddr, dataLength); FormatTableData(dataAddr, dataLength, dataM, dataA, dataType); Print2dTable(axisAddr, dataAddr, dataLength, dataType, dataM, dataA); return currAddr; } static Make2dUintTableNoConv(currAddr) { auto axisAddr, dataAddr, dataLength, dataType; MakeUnknown(currAddr, 12, DOUNK_SIMPLE); MakeWord(currAddr); // length dataLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // data type and conversion dataType = Byte(currAddr); currAddr = currAddr+2; MakeDword(currAddr); // axis address axisAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data addreess dataAddr = Dword(currAddr); currAddr = currAddr+3; FormatTableAxis(axisAddr, dataLength); FormatTableData(dataAddr, dataLength, 1, 0, dataType); Print2dTable(axisAddr, dataAddr, dataLength, dataType, 1, 0); return currAddr; } static Make3dRawTable(currAddr) { auto axisYAddr, dataYLength, axisXAddr, dataXLength, dataAddr, dataLength, dataAlign, dataType, fMin, fMax, fNum, fNumNext; fMin = 0 - 66000.1; fMax = 66000.1; MakeUnknown(currAddr, 20, DOUNK_SIMPLE); MakeWord(currAddr); // X length dataXLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // Y Length dataYLength = Word(currAddr); currAddr = currAddr+2; MakeDword(currAddr); // X axis address axisXAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // Y axis address axisYAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data address dataAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // no data conversion currAddr = currAddr+3; FormatTableAxis(axisYAddr, dataYLength); FormatTableAxis(axisXAddr, dataXLength); dataLength = dataXLength * dataYLength; if (dataLength > 0x4) { dataAlign = dataLength % 0x2; } else { if (dataLength%0x4 == 0) dataAlign = 0; if (dataLength%0x4 == 1) dataAlign = 3; if (dataLength%0x4 == 2) dataAlign = 2; if (dataLength%0x4 == 3) dataAlign = 1; } if (DfirstB((dataAddr + (dataLength + dataAlign))) != BADADDR) { dataType = 0x04; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else if (DfirstB(dataAddr + ((dataLength + dataAlign)*2)) != BADADDR) { dataType = 0x08; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else if (DfirstB(dataAddr + (dataLength*4)) != BADADDR) { fNum = GetFpNum(dataAddr,4); fNumNext = GetFpNum(dataAddr+4,4); if ((fNum >= fMin && fNum <= fMax && fNumNext >= fMin && fNumNext <= fMax) || Dword(dataAddr) == 0) { dataType = "float"; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } else { dataType = "float"; FormatTableData(dataAddr, dataLength, 1, 0, dataType); } } Print3dTable(axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, 1, 0); return currAddr; } static Make3dUintTable(currAddr) { auto axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, dataM, dataA; MakeUnknown(currAddr, 28, DOUNK_SIMPLE); MakeWord(currAddr); // X length dataXLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // Y Length dataYLength = Word(currAddr); currAddr = currAddr+2; MakeDword(currAddr); // X axis address axisXAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // Y axis address axisYAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data address dataAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data type dataType = Byte(currAddr); currAddr = currAddr+4; MakeFloat(currAddr); // multiplier dataM = GetFpNum(currAddr,4); currAddr = currAddr+4; MakeFloat(currAddr); // additive dataA = GetFpNum(currAddr,4); currAddr = currAddr+3; FormatTableAxis(axisYAddr, dataYLength); FormatTableAxis(axisXAddr, dataXLength); FormatTableData(dataAddr, dataYLength*dataXLength, dataM, dataA, dataType); Print3dTable(axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, dataM, dataA); return currAddr; } static Make3dUintTableNoConv(currAddr) { auto axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, dataM, dataA; MakeUnknown(currAddr, 20, DOUNK_SIMPLE); MakeWord(currAddr); // X length dataXLength = Word(currAddr); currAddr = currAddr+2; MakeWord(currAddr); // Y Length dataYLength = Word(currAddr); currAddr = currAddr+2; MakeDword(currAddr); // X axis address axisXAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // Y axis address axisYAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data address dataAddr = Dword(currAddr); currAddr = currAddr+4; MakeDword(currAddr); // data type dataType = Byte(currAddr); currAddr = currAddr+3; FormatTableAxis(axisYAddr, dataYLength); FormatTableAxis(axisXAddr, dataXLength); FormatTableData(dataAddr, dataYLength*dataXLength, 1, 0, dataType); Print3dTable(axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, 1, 0); return currAddr; } static FormatTableAxis(axisAddr, myLength) { auto i; for ( i=0; i < myLength*4; i=i+4 ) { MakeUnknown(axisAddr+i, 4, DOUNK_SIMPLE); MakeFloat(axisAddr+i); } } static FormatTableData(dataAddr, dataLength, dataM, dataA, dataType) { auto i, x, da, arrayId, msg; arrayId = GetArrayId("myGlobals"); da = dataAddr; if ((dataType == 0x04) || (dataType == 0x0C)) { // byte data size x = 1; for ( i=0; i < dataLength*x; i=i+x ) { MakeUnknown(dataAddr+i, x, DOUNK_SIMPLE); MakeByte(dataAddr+i); if ((dataType == 0x0C) && ((Byte(dataAddr+i) & 0x80) == 0x80)) { // is most sig bit set? MakeRptCmt((dataAddr+i), "= " + form("%1.3f",(float((Byte(dataAddr+i)-0x100)) * dataM + dataA))); } else { MakeRptCmt((dataAddr+i), "= " + form("%1.3f",(float(Byte(dataAddr+i)) * dataM + dataA))); } } SetArrayString(arrayId, 1, "formatted 8bit data at 0x" + ltoa(da, 16) + "\n"); } if ((dataType == 0x08) || (dataType == 0x10)) { // word data size x = 2; for ( i=0; i < dataLength*x; i=i+x ) { MakeUnknown(dataAddr+i, x, DOUNK_SIMPLE); MakeWord(dataAddr+i); if ((dataType == 0x10) && ((Word(dataAddr+i) & 0x8000) == 0x8000)) { // is most sig bit set? MakeRptCmt((dataAddr+i), "= " + form("%1.3f",(float((Word(dataAddr+i)-0x10000)) * dataM + dataA))); } else { MakeRptCmt((dataAddr+i), "= " + form("%1.3f",(float(Word(dataAddr+i)) * dataM + dataA))); } } SetArrayString(arrayId, 1, "formatted 16bit data at 0x" + ltoa(da, 16) + "\n"); } if (dataType == "dword") { x = 4; for ( i=0; i < dataLength*x; i=i+x ) { MakeUnknown(dataAddr+i, x, DOUNK_SIMPLE); MakeDword(dataAddr+i); MakeRptCmt((dataAddr+i), "= " + form("%1.3f",(float(Dword(dataAddr+i)) * dataM + dataA))); } SetArrayString(arrayId, 1, "formatted dword data at 0x" + ltoa(da, 16) + "\n"); } if (dataType == "float") { x = 4; for ( i=0; i < dataLength*x; i=i+x ) { MakeUnknown(dataAddr+i, x, DOUNK_SIMPLE); MakeFloat(dataAddr+i); MakeRptCmt((dataAddr+i), ""); } SetArrayString(arrayId, 1, "formatted float data at 0x" + ltoa(da, 16) + "\n"); } } static Print2dTable(axisAddr, dataAddr, dataLength, dataType, dataM, dataA) { auto arrayId, dataStr; arrayId = GetArrayId("myGlobals"); if (dataType == "raw") { dataType = "uint8"; dataStr = "unkn data type"; } if (dataType == "dword") { dataType = "int32"; dataStr = "int32"; } if (dataType == "float") { dataStr = dataType; } if (dataType == 0x04) { dataType = "uint8"; dataStr = dataType; } if (dataType == 0x08) { dataType = "uint16"; dataStr = dataType; } if (dataType == 0x0C) { dataType = "int8"; dataStr = dataType; } if (dataType == 0x10) { dataType = "int16"; dataStr = dataType; } if (dataType == "") { dataType = "uint8"; dataStr = "unkn data type"; } dataLength = form("%d", dataLength); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t
\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\t\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t
\n\tno description\n\n"); } static Print3dTable(axisYAddr, dataYLength, axisXAddr, dataAddr, dataXLength, dataType, dataM, dataA) { auto arrayId, dataStr; arrayId = GetArrayId("myGlobals"); if (dataType == "raw") { dataType = "uint8"; dataStr = "unkn data type"; } if (dataType == "dword") { dataType = "int32"; dataStr = "int32"; } if (dataType == "float") { dataStr = dataType; } if (dataType == 0x04) { dataType = "uint8"; dataStr = dataType; } if (dataType == 0x08) { dataType = "uint16"; dataStr = dataType; } if (dataType == 0x0C) { dataType = "int8"; dataStr = dataType; } if (dataType == 0x10) { dataType = "int16"; dataStr = dataType; } if (dataType == "") { dataType = "uint8"; dataStr = "unkn data type"; } dataYLength = form("%d", dataYLength); dataXLength = form("%d", dataXLength); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t
\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\t\n\t
\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t\t\n"); writestr(GetArrayElement(AR_LONG, arrayId, 0), "\t
\n\tno description\n\n"); } static CreateExpression(dataM, dataA) { auto fromByte, toByte, negate; negate = 0.0 - 1.0; if (form("%1.8f",dataM) == "1.0" && form("%1.8f",dataA) == "0.0") { fromByte = "expression=\"x"; toByte = "to_byte=\"x"; } else if (form("%1.8f",dataM) == "1.0" && dataA < 0.0) { fromByte = "expression=\"x" + form("%1.8f",dataA); toByte = "to_byte=\"x+" + form("%1.8f",(dataA * negate)); } else if (form("%1.8f",dataM) != "1.0" && dataA < 0.0) { fromByte = "expression=\"(x*" + form("%1.8f",dataM) + ")" + form("%1.8f",dataA); toByte = "to_byte=\"(x+" + form("%1.8f",(dataA * negate)) + ")/" + form("%1.8f",dataM); } else if (form("%1.8f",dataM) != "1.0" && form("%1.8f",dataA) == "0.0") { fromByte = "expression=\"x*" + form("%1.8f",dataM); toByte = "to_byte=\"x/" + form("%1.8f",dataM); } else { fromByte = "expression=\"(x*" + form("%1.8f",dataM) + ")+" + form("%1.8f",dataA); toByte = "to_byte=\"(x-" + form("%1.8f",dataA) + ")/" + form("%1.8f",dataM); } return fromByte + "\" " + toByte; }