Binary header and checksum?
Peter Jakacki
Posts: 10,193
I want to dump an Intel hex dump of my Tachyon image with all the extensions loaded but when I convert the hex file to binary on the PC the Spin tool rejects it with a bad checksum message. I thought I calculated the Spin tool's checksum correctly but here's my Forth code if someone can look over it or see where I went wrong. Thanks
[B][COLOR=#000000][FONT=Ubuntu Mono]BYTE cksum[/FONT][/COLOR][/B] [B][COLOR=#000000][FONT=Ubuntu Mono]pub [/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono][B]FIXCKSUM[/B][/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono] ( src cnt -- )[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] 2DUP + DUP 8 W! 8 + $0A W! \ vbase = end; dbase = end+8[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] $0A W@ 4 + $0E W! \ dcurr = dbase+4[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] cksum C~ 5 C~ \ zero our cksum and the header's checksum [/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] ADO I C@ cksum C+! LOOP \ add up all the bytes in memory[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] $14 cksum C@ - 5 C! \ adjust and update header's checksum [/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] ;[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono]\ Dump memory in Intel hex format so that a binary can be created on a PC [/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono]\ but calculate the checksum of a Propeller binary image first[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono]: [/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono][B]IDUMP[/B][/FONT][/COLOR][COLOR=#000000][FONT=Ubuntu Mono] ( src cnt --- )[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] 2DUP FIXCKSUM[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] ADO cksum C~ \ Proceed with Intel hex dump[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] CR ":" EMIT[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] #16 DUP cksum C+! .BYTE[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] I $FF AND cksum C+! [/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] I 8 SHR $FF AND cksum C+![/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] I $FFFF AND .WORD[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] 0 .BYTE I #16 [/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] ADO I C@ DUP cksum C+! .BYTE LOOP[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] cksum C@ NEGATE .BYTE[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] #16 +LOOP[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] CR ." :00000001FF" CR[/FONT][/COLOR] [COLOR=#000000][FONT=Ubuntu Mono] ;[/FONT][/COLOR][/B]
Comments
Anyway, for reference this is the code I worked from:
Is this information located somewhere? The binary files that are compiled by the Spin tool don't include the extra longs so why would they need to be there etc etc Subtracting from whatever was at location 5 doesn't seem to make any sense plus the C code seems to indicate that it just overwrites it with --> hdr.chksum = SPIN_TARGET_CHECKSUM - chksum
All the compiled binaries I have looked at just end with the Spin bytecodes and do not include the $FFF9FFFFs
Anyway the FIXCKSUM Forth code is short and concise and also commented.
Clear the cksum byte and also clear the byte at location 5
cksum C~ 5 C~ \ zero our cksum and the header's checksum
This line just sits in the loop indexing from the "src" or 0 in this case for "cnt" bytes or the total length of the binary.
ADO I C@ cksum C+! LOOP \ add up all the bytes in memory to cksum
and here we subtracted from the "magic" $14 and stored the byte at location 5
$14 cksum C@ - 5 C! \ adjust and update header's checksum
You have to subtract your computed sum plus $14 from location 5 so that the checksum will be zero. If you had already zeroed out location 5 then you just need to put -(sum+$14) at that location.
To keep it simple this is the Spin tool generated binary for a null program with a single pub declaration and no code.
00 1B B7 00 00 6A 10 00 1C 00 24 00 18 00 28 00 0C 00 02 00 08 00 00 00 32 00 00 00
Notice the checksum of $6A and the code ends at $001B so vbase is $001C. This checksum is checked by the Spin tool if you try to load a binary file and bombs out there if it's incorrect so it doesn't even get to be loaded.
EDIT: So 6A is correct since the sum is 14. So what does your forth code generate? Is it 96, which would be cksum - $14?
hdr.chksum = SPIN_TARGET_CHECKSUM - chksum
Where SPIN_TARGET_CHECKSUM is equal to $14.
00 1B B7 00 00 6A 10 00 1C 00 24 00 18 00 28 00 0C 00 02 00 08 00 00 00 32 00 00 00
If I add it on the handy dandy Windows calculator I get $14. If you zeroed out byte 5 first you would get $14-$6A = $AA. $14 - $AA = $6A. It's pretty basic math. There must be a bug in your forth code.
The bytes in each line of the hex file must sum up to zero, so the checksum byte at the end of the line is the negative of the sum of all the previous bytes in the row. As an example, the last byte in the final record is FF, or -1, since the previous bytes add up to 1.
All I have been asking is WHERE is this information about the Prop's binary format and checksum method?
Parallax can't be expected to think of everything people want to know!
-Phil
So where are all these past Prop champs? Whatever happened to deSilva and many others? (I do remember he was copping it a bit hard for his direct manner).
Parallax™ Propeller Binary Format.pdf