Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
I'm hoping someone can clarify for me how the header checksum is calculated. The wiki has this to say:
Contains an 8 bit checksum across the cartridge header bytes 0134-014C. The checksum is calculated as follows:
x=0:FOR i=0134h TO 014Ch:x=x-MEM[i]-1:NEXT
The lower 8 bits of the result must be the same than the value in this entry. The GAME WON'T WORK if this checksum is incorrect.
I'm not sure what that code means. Looks like it's just looping over the checksum data, but what is MEM[i]?
I'm sure it's pretty simple but I can't make heads or tails of it! Thanks!
Offline
MEM[i] corresponds to the value stored at the address i. So basically it contains successively the value stored at 0x0134, 0x0135, etc...
If you prefer in C code, this would be something like :
unsigned char x=0; unsigned short *p=0x0134; for(i=0;i!=0x19;i++){ x=x-p[i]-1; }
And then you compare the value of x with the header checksum at address 0x014D.
Last edited by Xephyr (2015-12-03 03:46:42)
Offline
The assembly code responsible for this
; At this point, HL is assumed to be $0134 LD B,$19 ; $00f1 LD A,B ; $00f3 Addr_00F4: ADD (HL) ; $00f4 INC HL ; $00f5 DEC B ; $00f6 JR NZ, Addr_00F4 ; $00f7 ADD (HL) ; $00f9 JR NZ,$fe ; $00fa ; if $19 + bytes from $0134-$014D don't add to $00 ; ... lock up
First it loads $19 into B as a countdown counter saying that a total of $19 bytes should be added together. But then it also loads that value into A, the accumulator, which gives the checksum a start value of $19. Then the bytes in $0134-$014C are added up. Lastly, the byte at $014D (the checksum byte) is added, and the result is expected to be 0. Note that 8 bit math is being used and anything that carries over to bits above 8 bits will be ignored.
Offline
What is going on with the header checksum might make more sense if you analyze it bit by bit. To calculate the header checksum, simply invert the bits in each byte and add all the the inverted bytes up, starting with byte 134 and ending with byte 14C.
For example, lets say you wanted to calculate the checksum of the bytes 78 and 4C. These bytes would be represented in binary as:
0111 1000
0110 1100
So, first invert them:
1000 0111
1001 0011
And add them up:
0001 1010
So the resulting checksum would be 1A
Now, this is why.
The formula is start with zero, then subtract the value of the byte you are on, then subtract 1 from that result.
0 - 9 could be rewritten as 0 + (-9)
To get the twos compliment negative of a number, one can simply invert all the bits, and then add 1 to the result
So, instead of subtracting the byte, you could instead say the formula is start with zero, then add the inverse of the byte plus 1, and then subtract 1 from the result
You can simply to start with zero, then add the inverse of each byte.
I hope this might be more clear to someone else who is wondering what is going on here.
Offline
Thanks for the info everyone!
Here's a little thing electrosheep and I have been working on. It's an online tool to create a gameboy rom that has the Nintendo logo replaced with whatever logo you draw! It won't boot on a real gameboy, but it will show the logo you draw as it scrolls down and then hang there. Not super useful but kind of fun!
So check it out at: http://catskull.net/GB-Logo-Generator/
Code is up at: https://github.com/catskull/GB-Logo-Generator
Offline