Created
January 3, 2024 02:29
-
-
Save x27/637c2a5d4ff813c86c84243cc2f100ca to your computer and use it in GitHub Desktop.
Extract Main CPU firmware from ICOM IC-R8600 firmware bundle (1.01-1.35 USA and non-USA versions)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Extract Main CPU firmware from ICOM IC-R8600 firmware bundle (1.01-1.35 USA and non-USA versions) | |
/// non-USA versions: | |
/// https://www.icomjapan.com/support/firmware_driver/?product=IC-R8600(EUR)&frm_type=Firmware&old=true | |
/// USA versions: | |
/// https://www.icomjapan.com/support/firmware_driver/?product=IC-R8600&frm_type=Firmware&old=true | |
/// </summary> | |
/// <param name="bundle">Firmware bundle</param> | |
/// <returns>Unpacked data</returns> | |
static byte[] MainCpuFirmwareExtract(byte[] bundle) | |
{ | |
const uint SIGNATURE = 0x88118833; // for r8600 | |
const int START_FIRMWARE_OFFSET = 0x10040; // for r8600 | |
const int START_DICTIONARY_OFFSET = 0xfee; | |
var signature = BitConverter.ToUInt32(bundle, 0); | |
if (signature != SIGNATURE) | |
throw new Exception($"Wrong signature: 0x{signature:X}!"); | |
var dict = new byte[0x1000]; | |
var dictOffset = START_DICTIONARY_OFFSET; | |
var dst = new byte[BitConverter.ToInt32(bundle, START_FIRMWARE_OFFSET)]; | |
var dstOffset = 0; | |
var srcOffset = START_FIRMWARE_OFFSET + 4; | |
try | |
{ | |
while(true) | |
{ | |
var cmdBits = (int)bundle[srcOffset++]; | |
for(var i=0; i<8; i++) | |
{ | |
// raw data | |
if ((cmdBits & 1) == 1) | |
{ | |
dst[dstOffset++] = bundle[srcOffset]; | |
dict[dictOffset++] = bundle[srcOffset++]; | |
dictOffset %= 0x1000; | |
} | |
// dict data | |
else | |
{ | |
var index = (int)bundle[srcOffset++]; | |
var len = (int)bundle[srcOffset++]; | |
index = index | ((len & 0xf0) << 4); | |
len = (len & 0xf) + 2; | |
for(var j=0; j<=len; j++) | |
{ | |
var value = dict[(index + j) % 0x1000]; | |
dst[dstOffset++] = value; | |
dict[dictOffset++] = value; | |
dictOffset %= 0x1000; | |
} | |
} | |
cmdBits >>= 1; | |
} | |
} | |
} | |
catch(IndexOutOfRangeException) | |
{ | |
return dstOffset != dst.Length+1 ? null : dst; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment