Skip to content

Commit

Permalink
Antus/e54filevalidation (#318)
Browse files Browse the repository at this point in the history
* P04 1M to P05 now we know

* Add P08 Checksum Validation

* Add E54 File Validation

---------

Co-authored-by: antus <[email protected]>
  • Loading branch information
antuspcm and antus committed Apr 27, 2023
1 parent 89afe72 commit 12bdf35
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 37 deletions.
136 changes: 99 additions & 37 deletions Apps/PcmLibrary/Misc/FileValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,16 @@ public uint GetOsidFromImage()
osid += image[0x7FFFC - offset] << 8;
osid += image[0x7FFFD - offset] << 0;
break;

case 1024 * 1024:
osid += image[0xFFFFA] << 24;
osid += image[0xFFFFB] << 16;
osid += image[0xFFFFC] << 8;
osid += image[0xFFFFD] << 0;
break;
}
break;

case PcmType.P05:
osid += image[0xFFFFA] << 24;
osid += image[0xFFFFB] << 16;
osid += image[0xFFFFC] << 8;
osid += image[0xFFFFD] << 0;
break;

case PcmType.P08:
osid += image[0x8000] << 24;
osid += image[0x8001] << 16;
Expand Down Expand Up @@ -222,31 +222,32 @@ public uint GetOsidFromImage()
private bool ValidateChecksums()
{
bool success = true;
UInt32 tableAddress;
UInt32 tableAddress = 0;
UInt32 segments = 0;

PcmType type = this.ValidateSignatures();

switch (type)
{
// have a segment table
case PcmType.P01_P59:
tableAddress = 0x50C;
segments = 8;
break;

case PcmType.P04:
tableAddress = 0x0;
segments = 0;
break;

case PcmType.P10:
tableAddress = 0x546;
segments = 5;
break;

// has a segment table, but handled in ValidateRangeP12()
case PcmType.P12:
tableAddress = 0x0;
segments = 0;

// no segment table
case PcmType.P04:
case PcmType.P05:
case PcmType.P08:
case PcmType.E54:
break;

case PcmType.Undefined:
Expand All @@ -260,20 +261,34 @@ private bool ValidateChecksums()
switch (type)
{
case PcmType.P04:
case PcmType.P05:
this.logger.AddUserMessage("\tStart\tEnd\tStored\t\tNeeded\t\tVerdict\tSegment Name");
success &= ValidateRangeP04(true);
break;
case PcmType.P08:
this.logger.AddUserMessage("\tStart\tEnd\tStored\tNeeded\tVerdict\tSegment Name");
success &= ValidateRangeByteSum(type, 0, 0x7FFFB, 0x8004, "Whole File");
break;
case PcmType.P12:
this.logger.AddUserMessage("\tStart\tEnd\tStored\tNeeded\tVerdict\tSegment Name");
success &= ValidateRangeP12(0x922, 0x900, 0x94A, 2, "Boot Block");
success &= ValidateRangeP12(0x8022, 0, 0x804A, 2, "OS");
success &= ValidateRangeP12(0x8022, 0, 0x804A, 2, "Operating System");
success &= ValidateRangeP12(0x80C4, 0, 0x80E4, 2, "Engine Calibration");
success &= ValidateRangeP12(0x80F7, 0, 0x8117, 2, "Engine Diagnostics");
success &= ValidateRangeP12(0x812A, 0, 0x814A, 2, "Transmission Calibration");
success &= ValidateRangeP12(0x815D, 0, 0x817D, 2, "Transmission Diagnostics");
success &= ValidateRangeP12(0x805E, 0, 0x807E, 2, "Speedometer");
success &= ValidateRangeP12(0x8091, 0, 0x80B1, 2, "System");
break;
case PcmType.E54:
this.logger.AddUserMessage("\tStart\tEnd\tStored\tNeeded\tVerdict\tSegment Name");
success &= ValidateRangeWordSum(type, 0x20002, 0x6FFFF, 0x20000, "Operating System");
success &= ValidateRangeWordSum(type, 0x8002, 0x19FFF, 0x8000, "Engine Calibration");
success &= ValidateRangeWordSum(type, 0x1A002, 0x1C7FF, 0x1A000, "Engine Diagnostics");
success &= ValidateRangeWordSum(type, 0x1C002, 0x1DFFF, 0x1C000, "Fuel");
success &= ValidateRangeWordSum(type, 0x1E002, 0x1EFFF, 0x1E000 , "System");
success &= ValidateRangeWordSum(type, 0x1F002, 0x1FFEF, 0x1F000, "Speedometer");
break;

// The rest can use the generic code
default:
Expand Down Expand Up @@ -327,7 +342,7 @@ private bool ValidateChecksums()
return false;
}

success &= ValidateRange(type, startAddress, endAddress, checksumAddress, segmentName);
success &= ValidateRangeWordSum(type, startAddress, endAddress, checksumAddress, segmentName);
}
break;
}
Expand Down Expand Up @@ -429,11 +444,11 @@ private PcmType ValidateSignatures()
}
}

// P04 512Kb
this.logger.AddDebugMessage("Trying P04 1Mb");
// P05 1Mb
this.logger.AddDebugMessage("Trying P05 1Mb");
if ((image[0xFFFFE] == 0xA5) && (image[0xFFFFF] == 0x5A))
{
return PcmType.P04;
return PcmType.P05;
}

this.logger.AddDebugMessage("Trying P12 1Mb");
Expand Down Expand Up @@ -466,9 +481,48 @@ private void PrintHeader()
}

/// <summary>
/// Validate a range.
/// Validate a range (8 bit bytes).
/// </summary>
private bool ValidateRangeByteSum(PcmType type, UInt32 start, UInt32 end, UInt32 storage, string description)
{
UInt16 storedChecksum = (UInt16)((this.image[storage] << 8) + this.image[storage + 1]);
UInt16 computedChecksum = 0;

for (UInt32 address = start; address <= end; address ++)
{
switch (type)
{
case PcmType.P08:
if (address == 0x4000)
{
address = 0x8010;
}

break;
}

computedChecksum += this.image[address];
}

bool verdict = storedChecksum == computedChecksum;

string error = string.Format(
"\t{0:X5}\t{1:X5}\t{2:X4}\t{3:X4}\t{4:X4}\t{5}",
start,
end,
storedChecksum,
computedChecksum,
verdict ? "Good" : "BAD",
description);

this.logger.AddUserMessage(error);
return verdict;
}

/// <summary>
/// Validate a range (16 bit words, 2's compliment).
/// </summary>
private bool ValidateRange(PcmType type, UInt32 start, UInt32 end, UInt32 storage, string description)
private bool ValidateRangeWordSum(PcmType type, UInt32 start, UInt32 end, UInt32 storage, string description)
{
UInt16 storedChecksum = (UInt16)((this.image[storage] << 8) + this.image[storage + 1]);
UInt16 computedChecksum = 0;
Expand All @@ -477,6 +531,26 @@ private bool ValidateRange(PcmType type, UInt32 start, UInt32 end, UInt32 storag
{
switch (type)
{
case PcmType.P01_P59:
if (address == 0x500)
{
address = 0x502;
}

if (address == 0x4000)
{
address = 0x20000;
}
break;

case PcmType.P08:
if (address == 0x4000)
{
address = 0x8010;
}

break;

case PcmType.P10:
switch (address)
{
Expand All @@ -493,18 +567,6 @@ private bool ValidateRange(PcmType type, UInt32 start, UInt32 end, UInt32 storag
break;
}
break;

case PcmType.P01_P59:
if (address == 0x500)
{
address = 0x502;
}

if (address == 0x4000)
{
address = 0x20000;
}
break;
}

UInt16 value = (UInt16)(this.image[address] << 8);
Expand Down Expand Up @@ -592,7 +654,7 @@ private bool ValidateRangeP12(UInt32 segment, UInt32 offset, UInt32 index, UInt3
}

/// <summary>
/// Validate a range for P04. Support 256, 512, 1024K images
/// Validate a range for P04 and P05. Support 256, 512, 1024K images
/// Early 512KB bins dont have a param block. This code is called with skipparamblock=true
/// If the first attempt fails it is re-entrant with skipparamblock=false to try again
/// </summary>
Expand All @@ -605,7 +667,7 @@ private bool ValidateRangeP04(bool skipparamblock)
UInt32 sumaddr = 0;

// Thanks Joukoy for Universal Patcher and the idea to use a pattern search for the P04 sum address.
// Working for all tested 1024K
// Working for all tested 1024K (P05)
if (image.Length == 1024 * 1024)
{
for (UInt32 i = start; i < end; i++)
Expand Down Expand Up @@ -698,7 +760,7 @@ private bool ValidateRangeP04(bool skipparamblock)
address += 0x4; // Some 98 have a different sig and dont include the osid
}
break;
case 1024 * 1024:
case 1024 * 1024: // P05
if (address == 0x4000)
{
address += 0xC000;
Expand Down
1 change: 1 addition & 0 deletions Apps/PcmLibrary/Misc/PcmInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public enum PcmType
Undefined = 0, // required for failed osid test on binary file
P01_P59,
P04,
P05,
P08,
P10,
P12,
Expand Down

0 comments on commit 12bdf35

Please sign in to comment.