bryc
3/16/2015 - 3:55 PM

legend of zelda (nes) sram checksum updater/checker

legend of zelda (nes) sram checksum updater/checker

/*
	zelschk
 	legend of zelda (nes) sram checksum updater/checker
 	16/03/2015 - bryc
*/

#include <stdio.h>

unsigned char data[8192];
FILE *fp;

int sumBytes(int start, int len)
{
	int i   = 0,
		sum = 0;

	for(i = start; i < start + len; i++)
	{
		sum += data[i];
	}

	return sum;
}

int readSRAM(char *argv[])
{
	unsigned int chk1 = (data[0x524] << 8) + data[0x525];
	unsigned int chk2 = (data[0x526] << 8) + data[0x527];
	unsigned int chk3 = (data[0x528] << 8) + data[0x529];

	unsigned int sum1 = 0;
	unsigned int sum2 = 0;
	unsigned int sum3 = 0;

	sum1 += sumBytes(0x2, 8);
	sum1 += sumBytes(0x1A, 40);
	sum1 += sumBytes(0x92, 384);
	sum1 += sumBytes(0x512, 1);
	sum1 += sumBytes(0x515, 1);
	sum1 += sumBytes(0x518, 1);
	sum1 += sumBytes(0x51B, 1);

	sum2 += sumBytes(0xA, 8);
	sum2 += sumBytes(0x42, 40);
	sum2 += sumBytes(0x212, 384);
	sum2 += sumBytes(0x513, 1);
	sum2 += sumBytes(0x516, 1);
	sum2 += sumBytes(0x519, 1);
	sum2 += sumBytes(0x51C, 1);

	sum3 += sumBytes(0x12, 8);
	sum3 += sumBytes(0x6A, 40);
	sum3 += sumBytes(0x392, 384);
	sum3 += sumBytes(0x514, 1);
	sum3 += sumBytes(0x517, 1);
	sum3 += sumBytes(0x51A, 1);
	sum3 += sumBytes(0x51D, 1);

	sum1 &= 0xFFFF;
	sum2 &= 0xFFFF;
	sum3 &= 0xFFFF;

	printf("%s\n----\n", argv[1]);
	printf("FILE: %X, %X, %X\n", chk1, chk2, chk3);
	printf("CALC: %X, %X, %X\n", sum1, sum2, sum3);

	if(chk1 != sum1 || chk2 != sum2 || chk3 != sum3)
	{
		data[0x524] = sum1 >> 8;
		data[0x525] = sum1 & 0xFF;
		data[0x526] = sum2 >> 8;
		data[0x527] = sum2 & 0xFF;
		data[0x528] = sum3 >> 8;
		data[0x529] = sum3 & 0xFF;

		printf("----\nINFO: Invalid checksum found. Repairing.\n");

		fp = fopen(argv[1], "wb");
		fwrite(data, sizeof(data), 1, fp);
		fclose(fp);
	}
}

int main(int argc, char *argv[])
{
	if(argv[1] && argc == 2)
	{
		fp = fopen(argv[1], "rb");
		if(fp)
		{
			fread(data, sizeof(data), 1, fp);
			readSRAM(argv);
			fclose(fp);
		}
		else
		{
			printf("ERROR: Can't open file \"%s\"\n", argv[1]);
		}
	}
	else
	{
		printf("zelschk - legend of zelda (nes) sram checksum updater/checker\n\nUSAGE: zelschk file\n");
	}
	return 0;
}