public ChecksumResult tdi41_2002_checksum_search(byte[] file_buffer, UInt32 file_size, bool debug)
{
UInt32 seed_1, seed_2;
UInt16 seed_1_msb, seed_1_lsb, seed_2_lsb, seed_2_msb;
UInt32 chk_oldvalue, chk_value, chk_start_addr, chk_end_addr, chk_store_addr;
chk_found = 2;
chk_fixed = 0;
chk_match = 0;
// Find seed 1
seed_1 = tdi41_2002_checksum_calculate(file_buffer, 0x14000, 0x4bffe, 0x8631, 0xefcd, 0, 0, true);
seed_1_msb = (UInt16)(seed_1 >> 16);
seed_1_lsb = (UInt16)seed_1;
// Find seed 2
seed_2 = tdi41_2002_checksum_calculate(file_buffer, 0, 0x7ffe, 0, 0, 0, 0, true);
seed_2_msb = (UInt16)(seed_2 >> 16);
seed_2_lsb = (UInt16)seed_2;
// checksum 1
chk_oldvalue = ((UInt32)file_buffer[0xffff] << 24)
+ ((UInt32)file_buffer[0xfffe] << 16)
+ ((UInt32)file_buffer[0xfffd] << 8)
+ (UInt32)file_buffer[0xfffc];
chk_value = tdi41_2002_checksum_calculate(file_buffer, 0x8000, 0xfffb, seed_2_lsb, seed_2_msb, 0x4531, 0x3550, false);
if (chk_oldvalue != chk_value)
{
file_buffer[0xfffc] = Convert.ToByte(chk_value & 0x000000ff);
file_buffer[0xfffd] = Convert.ToByte((chk_value >> 8) & 0x000000ff);
file_buffer[0xfffe] = Convert.ToByte((chk_value >> 16) & 0x000000ff);
file_buffer[0xffff] = Convert.ToByte((chk_value >> 24) & 0x000000ff);
chk_fixed++;
}
else chk_match++;
// Checksum 2
chk_oldvalue = ((UInt32)file_buffer[0x13fff] << 24)
+ ((UInt32)file_buffer[0x13ffe] << 16)
+ ((UInt32)file_buffer[0x13ffd] << 8)
+ (UInt32)file_buffer[0x13ffc];
chk_value = tdi41_2002_checksum_calculate(file_buffer, 0x10000, 0x13ffb, 0, 0, 0x8631, 0xefcd, false);
if (chk_oldvalue != chk_value)
{
file_buffer[0x13ffc] = Convert.ToByte(chk_value & 0x000000ff);
file_buffer[0x13ffd] = Convert.ToByte((chk_value >> 8) & 0x000000ff);
file_buffer[0x13ffe] = Convert.ToByte((chk_value >> 16) & 0x000000ff);
file_buffer[0x13fff] = Convert.ToByte((chk_value >> 24) & 0x000000ff);
chk_fixed++;
}
else chk_match++;
// Checksum blocks loop
chk_store_addr = 0x4fffb;
do
{
if ((file_buffer[chk_store_addr + 13] == 0x56) &&
(file_buffer[chk_store_addr + 14] == 0x34) &&
(file_buffer[chk_store_addr + 15] == 0x2e) &&
(file_buffer[chk_store_addr + 16] == 0x31))
{
// Checksum
chk_start_addr = chk_store_addr - 0x3ffb;
chk_end_addr = chk_store_addr;
chk_oldvalue = ((UInt32)file_buffer[chk_store_addr + 4] << 24)
+ ((UInt32)file_buffer[chk_store_addr + 3] << 16)
+ ((UInt32)file_buffer[chk_store_addr + 2] << 8)
+ (UInt32)file_buffer[chk_store_addr + 1];
chk_value = tdi41_2002_checksum_calculate(file_buffer, chk_start_addr, chk_end_addr, seed_1_lsb, seed_1_msb, seed_1_lsb, seed_1_msb, false);
if (chk_oldvalue != chk_value)
{
file_buffer[chk_store_addr + 1] = Convert.ToByte(chk_value & 0x000000ff);
file_buffer[chk_store_addr + 2] = Convert.ToByte((chk_value >> 8) & 0x000000ff);
file_buffer[chk_store_addr + 3] = Convert.ToByte((chk_value >> 16) & 0x000000ff);
file_buffer[chk_store_addr + 4] = Convert.ToByte((chk_value >> 24) & 0x000000ff);
chk_fixed++;
}
else chk_match++;
//Console.WriteLine("2002 start " + chk_start_addr.ToString("X8") + " - " + chk_end_addr.ToString("X8") + " store " + chk_store_addr.ToString("X8") + " file " + chk_oldvalue.ToString("X8") + " calc " + chk_value.ToString("X8"));
// Checksum
chk_start_addr = chk_store_addr + 5;
chk_end_addr = chk_store_addr + 0xb80;
chk_oldvalue = ((UInt32)file_buffer[chk_store_addr + 2948] << 24)
+ ((UInt32)file_buffer[chk_store_addr + 2947] << 16)
+ ((UInt32)file_buffer[chk_store_addr + 2946] << 8)
+ (UInt32)file_buffer[chk_store_addr + 2945];
chk_value = tdi41_2002_checksum_calculate(file_buffer, chk_start_addr, chk_end_addr, seed_1_lsb, seed_1_msb, seed_1_lsb, seed_1_msb, false);
if (chk_oldvalue != chk_value)
{
file_buffer[chk_store_addr + 2945] = Convert.ToByte(chk_value & 0x000000ff);
file_buffer[chk_store_addr + 2946] = Convert.ToByte((chk_value >> 8) & 0x000000ff);
file_buffer[chk_store_addr + 2947] = Convert.ToByte((chk_value >> 16) & 0x000000ff);
file_buffer[chk_store_addr + 2948] = Convert.ToByte((chk_value >> 24) & 0x000000ff);
chk_fixed++;
}
else chk_match++;
//Console.WriteLine("2002 start " + chk_start_addr.ToString("X8") + " - " + chk_end_addr.ToString("X8") + " store " + chk_store_addr.ToString("X8") + " file " + chk_oldvalue.ToString("X8") + " calc " + chk_value.ToString("X8"));
// Checksum
chk_start_addr = chk_store_addr + 0xb85;
chk_end_addr = chk_store_addr + 0xc000;
chk_oldvalue = ((UInt32)file_buffer[chk_store_addr + 49156] << 24)
+ ((UInt32)file_buffer[chk_store_addr + 49155] << 16)
+ ((UInt32)file_buffer[chk_store_addr + 49154] << 8)
+ (UInt32)file_buffer[chk_store_addr + 49153];
chk_value = tdi41_2002_checksum_calculate(file_buffer, chk_start_addr, chk_end_addr, seed_1_lsb, seed_1_msb, seed_1_lsb, seed_1_msb, false);
if (chk_oldvalue != chk_value)
{
file_buffer[chk_store_addr + 49153] = Convert.ToByte(chk_value & 0x000000ff);
file_buffer[chk_store_addr + 49154] = Convert.ToByte((chk_value >> 8) & 0x000000ff);
file_buffer[chk_store_addr + 49155] = Convert.ToByte((chk_value >> 16) & 0x000000ff);
file_buffer[chk_store_addr + 49156] = Convert.ToByte((chk_value >> 24) & 0x000000ff);
chk_fixed++;
}
else chk_match++;
//Console.WriteLine("2002 start " + chk_start_addr.ToString("X8") + " - " + chk_end_addr.ToString("X8") + " store " + chk_store_addr.ToString("X8") + " file " + chk_oldvalue.ToString("X8") + " calc " + chk_value.ToString("X8"));
chk_found += 3;
}
chk_store_addr += 0x10000;
} while (chk_store_addr + 5 < file_size);
Console.WriteLine("tdi41v2002_chkfixed: " + chk_fixed.ToString() + " / " + chk_found.ToString());
Console.WriteLine("tdi41v2002_chkmatch: " + chk_match.ToString() + " / " + chk_found.ToString());
if (chk_fixed == 0) return ChecksumResult.ChecksumOK;
else if (chk_match > 3) return ChecksumResult.ChecksumFail;
else if (chk_fixed >= chk_found-1) return ChecksumResult.ChecksumTypeError;
return ChecksumResult.ChecksumFail;
}