/* Here's a little program to take a DX7 patch file whose header and checksum
 * have been stripped off, and replace them.
 *
 * This program has NOT been tested extensively and is NOT robust.
 * It works ONLY if the original file size is 4096 bytes.
 * It is specifically written for files in the ucsd.edu DX7 patch archive.
 *
 * You might need to change the "r" and "w" in the fopen() calls in AddIt()
 * to "rb" and "wb" for computers (like the IBM PC) that need special
 * handling for binary vs. text files.
 *
 * Dan Barrett, barrett@cs.jhu.edu, Public Domain.
 *
 * Usage:  addit oldfile newfile
 */

#include <stdio.h>

typedef unsigned char UBYTE;
 
#define DX_FILESIZE	4096L	/* Size of the patch file. */
#define	EOX		0xF7	/* End of system exclusive. */
#define HEADER_SIZE	6	/* Size of system exclusive header. */

UBYTE header[HEADER_SIZE] = { 0xF0, 67, 0, 9, 16, 0 };

UBYTE MakeChecksum();
void AddIt(), Update();

	
main(argc,argv)
int argc; char *argv[];
{
	if (argc != 3)
	{
		fprintf(stderr, "Syntax:  %s oldfile newfile\n", argv[0]);
		exit(1);
	}
	else
		AddIt(argv[1], argv[2]);

	exit(0);
}

	
UBYTE MakeChecksum(patchData)
/* Given your array of patch data, compute and return the checksum. */
UBYTE patchData[];
{
	UBYTE sum;
	int i;

	sum = 0;
	for (i=0; i<DX_FILESIZE; i++)
		sum = (sum + patchData[i]) % (1 << 8);
	printf ("Checksum is %02X\n", (UBYTE)((1 << 8) - sum));

	return((UBYTE)((1 << 8) - sum));
}


void AddIt(oldfilename, newfilename)
char *oldfilename, *newfilename;
{
	FILE *old, *new;

	if ((old = fopen(oldfilename, "r")) == NULL)
	{
		fprintf(stderr, "Cannot open %s\n", oldfilename);
		exit(1);
	}
	else if ((new = fopen(newfilename, "w")) == NULL)
	{
		fprintf(stderr, "Cannot write %s\n", newfilename);
		fclose(old);
		exit(1);
	}
	else
	{
		Update(old, new);
		fclose(new);
		fclose(old);
	}
}


void Update(old, new)
FILE *old, *new;
{
	int i, c;
	UBYTE data[DX_FILESIZE];

	for (i=0; i<HEADER_SIZE; i++)	/* Write header to newfile. */
		putc(header[i], new);

	i = 0;
	while ((c = getc(old)) != EOF)	/* Copy old file to new. */
	{
		data[i++] = (UBYTE)c;
		putc(c, new);
	}

	putc(MakeChecksum(data), new);
	putc((UBYTE)0xF7, new);
}
