This was posted a long time ago, so here it is again:
Note:The last 4-bytes (flash checksum) is quite complicated, and it's not included here.
PPM Checksums Algorithm
by Ice Draagon <
[email protected]>
July 2001
Conventions used in this document:
Strings are enclosed in {} or " "
Hex values begin with "x" like in x02E5
Null-terminated strings are indicated by StrZ at
end of identifier.
base32(PPM1) returns a 32bit value like x00320000
offset(MCUChecksum) returns a 32bit value like x00000022
word(MCUChecksum) returns a 16bit value like x02E5
dword(FlashChecksum) returns a 32bit value like x35A003CC
24bit(StartMCU) returns a 24bit value like x200024
Underscore between hex means "to" like in x002C_x002F,
it means values from x002C to x002F.
2-digit numbers found at end of identifiers (like the 16 in Chksum16)
denotes value type (Chksum16 is a 16bit value like x02E5)
Chksum16 is a 16bit checksum obtained by adding 16bit values.
Example:
Offset Word
x320034 x1234
x320036 x1122
Chksum16 x2356
Chksum32 is a 32bit checksum obtained by adding 32bit values.
Example:
Offset DWord
x320034 x12345678
x320038 x11223344
Chksum32 x234589BC
Searching for PPM Block checksums:
PPM1:
Set base32=x00320000
or use search string {xFFFF,"PPM",x00}.
base32=offset({xFFFF,"PPM",x00})+2
BOPPM1...........base32
Chksum32.........base32+x002C
ddChkSum32.......dword(Chksum32) ; base32+x002C_x002F
PPMLength32......base32+x0030
ddPPMLen32.......dword(PPMLength32) ; base32+x0030_x0033
BChkSum32........PPMLength32
EChkSum32........BChkSum32+ddPPMLen32-4 ; less 4 bytes (length of ddChkSum32)
EOPPM1...........EChkSum32
Set PPMx.........PPM1
Set EOPPMx.......EOPPM1
PPMx:
Set PPMBlockEndString={x0000,x0000,x0000,x0010,x0000,x0000,x0000,x0000}
base32=EOPPMx+1
or use PPMBlockEndString after base32(PPMx)
base32=offset(PPMBlockEndString)+16
If dword(base32)=x00000000 then
end PPM block search
Else
BOPPMx........base32
Chksum32......base32
ddChksum32....dword(Chksum32)
PPMLength32...base32+4
ddPPMLen32....dword(PPMLength32)
BChkSum32.....PPMLength32
EChkSum32.....BChkSum32+PPMLength32-4 ; less 4 bytes (length of ddChkSum32)
EOPPMx........EChkSum32
EndIf
Loop to PPMx until PPM block search ends
PPM Blocks:
PPM1.............PPM Version
PPM2.............GSM Code Version
PPM3.............Fonts
PPM4.............Language Text Version
PPM5.............Language Array Order/Index
PPM6.............Tone Pack Version
PPM7.............Mobile Network Codes
PPM8.............Language Packs
PPM1 Block contents: *PPM Version
(Note, null-terminated strings are indicated by StrZ at
end of identifier)
base32..............offset(PPM1)
PPMHeaderStrZ.......(base32)_(base32+3)
PPMVerStrZ..........(base32+4)_(base32+35)
Reserve1............(base32+36)_(base32+39) {xFFFF,xFF00}
PPMPackStrZ.........(base32+40)_(base32+41)
Reserve2............(base32+42)_(base32+43) {xFFFF}
Chksum32............(base32+44)_(base32+47)
PPMLength32.........(base32+48)_(base32+51) *Starting from offset(Chksum32)
LangPackVerStrZ.....(base32+52)_(base32+63)
BOSectUnk1..........(base32+63)_(base32+67) {x0000,x0001}
SectionLength32.....(base32+68)_(base32+71) *Starting from offset(BOSectUnk1)
Unk2Str.............(base32+72)_(base32+75) *In 6210v301C "A13C"
SectionContents.....(base32+76)_(offset(BOSectUnk1)+SectionLength32)
EOSection...........(base32+76)+(offset(BOSectUnk1)+SectionLength32)
PPMBlockEndString...(offset(EOSection)+1)_((offset(EOSection)+1)+16)
PPM2 Block contents: *GSM Code version
base32..............offset(PPM2)
Chksum32............(base32)_(base32+3)
PPMLength32.........(base32+4)_(base32+7) *Starting from offset(Chksum32)
GSMCodeVerStrZ......(base32+8)_(base32+19)
BOSectUnk1..........(base32+20)_(base32+23) {x0000,x0001}
SectionLength32.....(base32+24)_(base32+27) *Starting from offset(BOSectUnk1)
Unk2Str.............(base32+28)_(base32+31) *In 6210v301C "A13C"
SectionContents.....(base32+32)_(offset(BOSectUnk1)+SectionLength32)
EOSection...........(base32+32)+(offset(BOSectUnk1)+SectionLength32)
PPMBlockEndString...(offset(EOSection)+1)_((offset(EOSection)+1)+16)
PPM3 Block contents: *Fonts
base32..............offset(PPM3)
Chksum32............(base32)_(base32+3)
PPMLength32.........(base32+4)_(base32+7) *Starting from offset(Chksum32)
FontStrZ............(base32+8)_(base32+19)
BOSectUnk1..........(base32+20)_(base32+23) {x0000,x0001}
SectionLength32.....(base32+24)_(base32+27) *Starting from offset(BOSectUnk1)
Unk2Str.............(base32+28)_(base32+31) {x0000,x0000}
SectionContents.....(base32+32)_(offset(BOSectUnk1)+SectionLength32)
EOSection...........(base32+32)+(offset(BOSectUnk1)+SectionLength32)
PPMBlockEndString...(offset(EOSection)+1)_((offset(EOSection)+1)+16)
PPM4 Block contents: *Language Text Version
base32..............offset(PPM4)
Chksum32............(base32)_(base32+3)
PPMLength32.........(base32+4)_(base32+7) *Starting from offset(Chksum32)
TextVerStrZ.........(base32+8)_(base32+19)
Set EOSectx.........(base32+20)
PPM4Sections:
BOSectx.............(EOSectx)
If word(BOSectx)=(x0000) then
*Check for PPMBlockEndString
If found(PPMBlockEndString) then PPM4 Block ends
Else
If word(BOSectx)=(xFFFF) then
EOSectx=EOSectx+2
Loop to PPM4Sections
EndIf
EndIf
LangIndex...........(BOSectx)_(BOSectx+3) *See notes after this block
SectxLen32..........(BOSectx+4)_(BOSectx+7) *Starting from BOSectx
LangCode............(BOSectx+8)_(BOSectx+11) *See notes after this block
SectxContents.......(BOSectx+12)_(BOSectx+SectxLen32)
EOSectx.............(BOSectx+12)+(BOSectx+SectxLen32)
SectxContents (COMM lang code not included):
base32..............offset(SectxContents)
BOTypex.............(base32)_(base32+3) Coding type (0800 0000 - ansi, 8800 0000 - unicode)
BOLangx.............base32+4)
Repeat
Get byte from offset
Check if byte=xFF, if TRUE then break
byte..............length of string (1-based)
End
BOStringsx..........right after the xFF marker
BOEOStringsx........xFF filler, since length must be divisible by 4.
Loop to PPM4Sections until PPMBlockEndString is encountered
Notes:
LangIndex........LangCode
x0000,x0033......COMM - common to all (don't modify)
x0000,x0002......GERM
x0000,x0001......ENGL
x0000,x000D......TURK
x0000,x0005......SPAN
x0000,x0003......FREN