Points of Required Attention™
Please chime in on a proposed restructuring of the ROM hacking sections.
Views: 88,478,253
Main | FAQ | Uploader | IRC chat | Radio | Memberlist | Active users | Latest posts | Calendar | Stats | Online users | Search 04-24-24 05:02 PM
Guest: Register | Login

0 users currently in ROM Hacking | 2 guests | 3 bots

Main - ROM Hacking - SNES ROM Checksum New thread | New reply


PaD
Posted on 05-19-09 06:34 PM Link | Quote | ID: 107256

Newcomer
Level: 4

Posts: 1/2
EXP: 208
Next: 71

Since: 05-19-09

Last post: 5453 days
Last view: 5453 days
Hey all!

Does anyone know how the checksum in SNES ROMs works? Any documents on it?

I need to know where it is saved and how it is calculated so I don't get these "Bad Checksum" messages (by Geiger's SNES 9x debugger, dunno about other emus) all the time.
Since I'm modifying my ROM programatically I just want to include that function in my tool rather than using some external tool.

Thanks for help in advance!

Cellar Dweller
Posted on 05-19-09 06:45 PM Link | Quote | ID: 107259


Snifit
Level: 39

Posts: 157/287
EXP: 385133
Next: 19638

Since: 02-19-07
From: Arkansas

Last post: 4050 days
Last view: 3217 days
I don't know if there are any docs, but I would consult the source code for an emulator to learn about the algorithm. Just don't copy the code if you have not properly thought about the license.

blackhole89
Posted on 05-19-09 06:54 PM Link | Quote | ID: 107260


The Guardian
Moloch whose eyes are a thousand blind windows!
Level: 124

Posts: 2520/4196
EXP: 21529949
Next: 306652

Since: 02-19-07
From: Ithaca, NY, US

Last post: 469 days
Last view: 82 days



From quickly skimming Snes9x's code, I found the following relatively self-explaining routine pieces:

CalculatedSize = (totalFileSize / 0x2000) * 0x2000;

uint16 CMemory::checksum_calc_sum (uint8 *data, uint32 length)
{
uint16 sum = 0;

for (uint32 i = 0; i < length; i++)
sum += data[i];

return (sum);
}

uint16 CMemory::checksum_mirror_sum (uint8 *start, uint32 &length, uint32 mask)
{
// from NSRT
while (!(length & mask))
mask >>= 1;

uint16 part1 = checksum_calc_sum(start, mask);
uint16 part2 = 0;

uint32 next_length = length - mask;
if (next_length)
{
part2 = checksum_mirror_sum(start + mask, next_length, mask >> 1);

while (next_length < mask)
{
next_length += next_length;
part2 += part2;
}

length = mask + mask;
}

return (part1 + part2);
}

void CMemory::Checksum_Calculate (void)
{
// from NSRT
uint16 sum = 0;

if (Settings.BS && !Settings.BSXItself)
sum = checksum_calc_sum(ROM, CalculatedSize) - checksum_calc_sum(ROM + (HiROM ? 0xffb0 : 0x7fb0), 48);
else
if (Settings.SPC7110)
{
sum = checksum_calc_sum(ROM, CalculatedSize);
if (CalculatedSize == 0x300000)
sum += sum;
}
else
{
if (CalculatedSize & 0x7fff)
sum = checksum_calc_sum(ROM, CalculatedSize);
else
{
uint32 length = CalculatedSize;
sum = checksum_mirror_sum(ROM, length);
}
}

CalculatedChecksum = sum;
}


____________________



PaD
Posted on 05-19-09 10:27 PM Link | Quote | ID: 107271

Newcomer
Level: 4

Posts: 2/2
EXP: 208
Next: 71

Since: 05-19-09

Last post: 5453 days
Last view: 5453 days
Hm right, failed to figure that they're Open Source.
Thanks for help!

Main - ROM Hacking - SNES ROM Checksum New thread | New reply

Acmlmboard 2.1+4δ (2023-01-15)
© 2005-2023 Acmlm, blackhole89, Xkeeper et al.

Page rendered in 0.052 seconds. (341KB of memory used)
MySQL - queries: 47, rows: 71/71, time: 0.043 seconds.