/* WilChkSm.c - a checksum calculator for Williams ROM images */
/* Version 1.1 7-FEB-95 */
/* Copyright © 1995 Sean Riddle */
/* Freely distributable on any medium given all copyrights are retained */
/* by the author and no charge greater than $7.00 is made for obtaining */
/* this software */
/* Please send all bug reports and update ideas to: */
/* sriddle@ionet.net */
/* latest version at: */
/* Please don't hurl on my URL! */
/* usage: WilChkSm */
/* This program takes a Williams ROM image and calculates the checksum */
/* for each ROM. It then compares each checksum to the checksum table */
/* and reports any errors. The ROM image can be a single file that's */
/* 65536 bytes long, or twelve 4096-byte files, representing each ROM. */
/* The 12 files must be named .nn, where nn goes from 01 through 12. */
/* NOTE: the range 9000-CFFF should be all FFs. This is RAM and I/O. */
/* WilChkSm has been tested on the games Stargate, Robotron, Joust, */
/* Bubbles and Sinistar */
/* history: */
/* 2/7/95 - slight changes to work with Sinistar.xx files - there are */
/* fewer than 12 of these. */
#include
#include
#include
void main(int argc, char *argv[]) {
FILE *fp;
char *buffer;
char sum;
int r,x,y;
int chksumoff=0;
char file[256];
int loop;
int noerror=1;
if(argc==2) {
if(!(buffer=malloc(65536)))
printf("no memory for ROM buffer\n");
else {
for(x=0;x<65535;x++)
buffer[x]=-1;
loop=0;
if(fp=fopen(argv[1],"rb")) {
fread(buffer,65536,1,fp);
fclose(fp);
loop=-1;
} else {
for(x=1;(x<13);x++) {
if(x<10)
y=x;
else
y=x+4;
sprintf(file,"%s.%02.2d",argv[1],x);
if(fp=fopen(file,"rb")) {
fread(&buffer[(y-1)*4096],4096,1,fp);
fclose(fp);
loop=1;
}
}
}
if(loop) {
printf("%s",argv[1]);
if(loop!=-1)
printf(".??");
printf("\n");
for(x=65535;x>30;x--) { /* find checksum table */
if((buffer[x]==(char)0xf0)&&(buffer[x-2]==(char)0xe0)&&
(buffer[x-4]==(char)0xd0)&&(buffer[x-6]==(char)0xc0)&&
(buffer[x-8]==(char)0xb0)&&(buffer[x-10]==(char)0xa0)&&
(buffer[x-12]==(char)0x90)&&(buffer[x-14]==(char)0x80)&&
(buffer[x-16]==0x70)&&(buffer[x-18]==0x60)&&
(buffer[x-20]==0x50)&&(buffer[x-22]==0x40)&&
(buffer[x-24]==0x30)&&(buffer[x-26]==0x20)&&
(buffer[x-28]==0x10)&&(buffer[x-30]==0x00)) {
chksumoff=x-30;
x=0;
}
}
printf("Checksum offset=%X\n",chksumoff);
for(r=0;r<16;r++) { /* calculate checksum for each ROM */
sum=0;
for(x=4096*r;x<4096+4096*r;x++)
sum+=buffer[x];
if(loop!=-1)
printf("%s.%02.2d: ",argv[1],r);
printf("%X000-%XFFF: calc=%02.2hX, known=%02.2hX",r,r,
(unsigned char)sum,(unsigned char)buffer[chksumoff+r*2+1]);
if(sum!=buffer[chksumoff+r*2+1]) {
printf("<--- checksum error!");
noerror=0;
}
printf("\n");
}
if(noerror)
printf("No errors found\n");
} else
printf("Can't open file `%s'\n",argv[1]);
}
} else
printf("Usage: `%s '\n",argv[0]);
free(buffer);
}