Zophar's Message Domain

Go Back   Zophar's Message Domain > Emulation Talk > Rom Hack

Reply
 
Thread Tools Display Modes
Old 10-21-2005, 02:22 AM   #1
JadussD
Senior Member
 
Join Date: Jan 2003
Posts: 2,100
Default SNES ROM Checksums.

I was reading the http://www.emulatronia.com/doctec/co...bededcartridgeSNESKart</A> document, which is excellent, except for some ambiguity on the subject of the checksum. It says that SNES ROM checksums are 16-bit, but they are obtained by adding together all the bytes in 4Mbit chunks, then adding these chunks together and taking the lower 32-bits. Obviously, the checksum cannot be 32-bits, if there is only 16-bits to store it in. What gives?

It also says some confusing things about what to do whenever the ROM size is not evenly divided by 4Mbit. So, if I have a 10Mbit ROM (Were any commercial games actually of this size or is worrying about this a waste of time?), would I have to multiply the result of the last 2Mbit by itself, or simply add 0s where the non-existant space is? The document is ambiguous on the matter. Also, could anyone tell me any games that were of a size indivisible by 4Mbit (524,288 bytes) if any?
JadussD is offline   Reply With Quote
Old 10-21-2005, 04:49 AM   #2
JadussD
Senior Member
 
Join Date: Jan 2003
Posts: 2,100
Default Re: SNES ROM Checksums.

> I was reading the SNESKart document,

One more thing. Since the checksum is contained within the ROM, how do you factor that in? Do you just skip the checksum bytes, or do you take them into the checksum as well?
JadussD is offline   Reply With Quote
Old 10-21-2005, 05:06 AM   #3
Ugly Joe
Senior Member
 
Ugly Joe's Avatar
 
Join Date: Dec 2003
Posts: 1,461
Default Re: SNES ROM Checksums.

> One more thing. Since the checksum is contained within the
> ROM, how do you factor that in? Do you just skip the
> checksum bytes, or do you take them into the checksum as
> well?

There's an offset byte (or is it bytes?) that make sure it adds up properly. Like, if your checksum is 0xFFF1, the offset would be 0x000F. That way they would add up to 0x0000 and not affect the checksum.
__________________
Ugly Joe is offline   Reply With Quote
Old 10-21-2005, 05:34 AM   #4
JadussD
Senior Member
 
Join Date: Jan 2003
Posts: 2,100
Default Re: SNES ROM Checksums.

> There's an offset byte (or is it bytes?) that make sure it
> adds up properly. Like, if your checksum is 0xFFF1, the
> offset would be 0x000F. That way they would add up to
> 0x0000 and not affect the checksum.
>

Ohh, the inverse checksum byte, that's what that's for. I was using that to detect if the game was HiROM or LoROM and if the ROM had a header by ORing the 4 places it could be...should have thought of that. Thanks!
JadussD is offline   Reply With Quote
Old 10-21-2005, 05:59 AM   #5
D--
Senior Member
 
D--'s Avatar
 
Join Date: Oct 2001
Location: Chaoyang, Beijing, China
Posts: 826
Default Re: SNES ROM Checksums.

> Ohh, the inverse checksum byte, that's what that's for. I
> was using that to detect if the game was HiROM or LoROM and
> if the ROM had a header by ORing the 4 places it could
> be...should have thought of that. Thanks!

Watch out for the beta carts. Their checksums are utterly fucked.
__________________
portfolio :: deviantArt :: 微博 :: Twitter
D-- is offline   Reply With Quote
Old 10-21-2005, 06:06 AM   #6
phonymike
Senior Member
 
Join Date: Jun 2003
Posts: 278
Default here's how you do it

it's as simple as this. take a rom, remove any header if present (the first 512 bytes, they aren't the original rom, it's added information copiers put there to store extra data about the rom.) if it's 8, 16, or 32mbit, just add all the bytes together, then AND it with 0xFFFF (to keep it 16 bits.) that is the checksum, which is the second part in the rom's actual header. then inverse the checksum and that's the compliment. so if the checksum is 0x1234 then XOR it with 0xFFFF (0x1234 ^= 0xFFFF) and your compliment is 0xEDCB.

when a raw rom is compiled before they insert the checksum, the checksum and compliment are 0x0000 and 0xFFFF so when they do calculate the checksum the resulting checksum and compliment will be the same. 0x0000 + 0xFFFF is the same as 0x1234 + 0xEDCB.

now if you have a rom not 8, 16, or 32mbits, you add up 8mbit sections, and the last section that's less than 8mbit you simply double until it is 8mbit. so a 12mbit rom, you add the first 8mbits byte by byte together. then add the next 4mbit byte by byte together, then double the number for the last part. or if you wish duplicate the last 4mbits onto itself, then add it all together byte by byte. so 24mbits = 8mbit + 8mbit + (8mbit x 2.) since there is no 4th section of 8mbits, you fake it by taking the 3rd section of 8mbits and duplicating it.

4mbit rom = checksum of 4mbits * 2
8mbit rom = checksum
12mbit rom = checksum of first 8mbits + checksum of remaining 4mbits * 2
16mbit rom = checksum
20mbit rom = checksum of first 16mbits + checksum of remaining 4mbits * 2
24mbit rom = checksum of first 16mbits + checksum of remaining 8mbits * 2
28 mbit rom = checksum of first 16mbits + checksum of remaining 8mbits * 2 (yeah it doesn't cover the very last 4mbits as far as I know.)
32mbit rom = checksum

this is as much as I know. since there is no commercial 28mbit rom (they mine as well pay for 32mbit mask rom) then I don't know if it's done this way. try it out, it'd be a simple c program to make, and compare how different rom tools and emulators calculate such things. also, ToP is 48mbit, which is actually a 32mbit and a separate 16mbit rom combined into one file. one of the roms has a checksum for that rom only, the other one doesn't have a checksum written for itself. so it can be handled in different ways.

again the checksum is the nintendo standard, so you must not have a copier header on the rom (copiers obviously are not nintendo standards.)
phonymike is offline   Reply With Quote
Old 10-21-2005, 06:52 AM   #7
JadussD
Senior Member
 
Join Date: Jan 2003
Posts: 2,100
Default Re: here's how you do it

> 4mbit rom = checksum of 4mbits * 2

Alright, thanks a lot for that reply that was very helpful, but I think you're wrong about one thing, because I just plain added up all the bytes in F-Zero without multiplying by 2, and the program spit out the same checksum that's in the ROM. I'm thinking that it has to be divisible by 4Mbit, not 8Mbit like you said, which is what the SNES Kart document seemed to be getting at, although I wasn't sure. I'm going to try out the Ms. PacMan ROM, which I think was 2Mbit and see if multiplying by 2 gives the correct checksum. Anyways, thanks!
JadussD is offline   Reply With Quote
Old 10-21-2005, 05:13 PM   #8
KingMike
Regular Member
 
Join Date: Aug 2005
Posts: 41
Default 10mbit

> 10Mbit ROM (Were any commercial games actually of this size
> or is worrying about this a waste of time?)

Aladdin, Equinox, Jinsei Game (The Game of Life) 1/2 are a few I know of. Odd thing about Equinox is that the Japanese version (Solstice 2) is 8mbit, yet the extra 2mbit in the US ROM image seems completely empty. Didn't look at the PAL version, though.

Also, SGB is 2mbit if you want another odd size ROM example.
KingMike is offline   Reply With Quote
Old 10-21-2005, 08:02 PM   #9
D--
Senior Member
 
D--'s Avatar
 
Join Date: Oct 2001
Location: Chaoyang, Beijing, China
Posts: 826
Default Re: 10mbit

> Aladdin, Equinox, Jinsei Game (The Game of Life) 1/2 are a
> few I know of. Odd thing about Equinox is that the Japanese
> version (Solstice 2) is 8mbit, yet the extra 2mbit in the US
> ROM image seems completely empty. Didn't look at the PAL
> version, though.

What did they report in their headers for ROM size?
__________________
portfolio :: deviantArt :: 微博 :: Twitter
D-- is offline   Reply With Quote
Old 10-22-2005, 06:07 AM   #10
D--
Senior Member
 
D--'s Avatar
 
Join Date: Oct 2001
Location: Chaoyang, Beijing, China
Posts: 826
Default Re: here's how you do it

> it's as simple as this. take a rom, remove any header if present (the first 512 bytes, they aren't the original rom, it's added information copiers put there to store extra data about the rom.) if it's 8, 16, or 32mbit, just add all the bytes together, then AND it with 0xFFFF (to keep it 16 bits.) that is the checksum, which is the second part in the rom's actual header. then inverse the checksum and that's the compliment. so if the checksum is 0x1234 then XOR it with 0xFFFF (0x1234 ^= 0xFFFF) and your compliment is 0xEDCB.

Do you have a code snippet for this? I'm trying to understand how this works and am just not getting it from your description. How is this different from CRC16 with the last banks mirrored out to make 4/8/16/32Mbit?
__________________
portfolio :: deviantArt :: 微博 :: Twitter
D-- is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 06:18 AM.

Contact Us - Zophar's Domain - Archive - Top

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.