#include <stdio.h>
#include <stdlib.h>


#pragma pack(1)
struct smd_header {
	unsigned char num_blocks; 	// the number of 16K blocks
	unsigned char reserved1;   	// always 0x03
	unsigned char split_indicator;
	unsigned char reserved2[5]; 	// always 0x00
	unsigned char reserved3;	// always 0xAA
	unsigned char reserved4;	// always 0xBB
	unsigned char reserved5;	// always 0x06
	unsigned char padding[501];	// all set to 0x00
};

void smd2bin(char *inblk, char *outblk);
char header_is_ok(struct smd_header *header);


char header_is_ok(struct smd_header *header)
{
//	if (header->reserved1!=0x03) { return 0; }
	if (header->reserved3!=0xAA) { return 0; }
	if (header->reserved4!=0xBB) { return 0; }
	if (header->reserved5!=0x06) { return 0; }

	return 1;
}

int main(int argc, char **argv)
{
	FILE *infile, *outfile;
	struct smd_header file_header;
	int res, i;
	int bytes;	
	
	if (argc<3) {
		printf("Usage: ./smd2bin in_file out_file\n");
		return -1;
	}

	infile = fopen(argv[1], "r");
	if (infile==NULL) {
		perror("fopen in_file\n");
		return -1;
	}
	outfile = fopen(argv[2], "w");
	if (outfile==NULL) {
		perror("fopen out_file\n");
		fclose(infile);
		return -1;
	}

	res = fread(&file_header, sizeof(struct smd_header), 1, infile);
	if (res!=1) {
		perror("could not read header");
		fclose(infile);
		fclose(outfile);
		return -1;
	}
	if (!header_is_ok(&file_header)) {
		printf("Bad file header. Not a smd file or file is corrupted\n");
		return -1;
	}
	printf("File has %d 16K blocks\n", file_header.num_blocks);	
	bytes=0;
	for (i=0; i<file_header.num_blocks; i++)
	{
		unsigned char smd_block[16384];
		unsigned char raw_block[16384];
		res = fread(smd_block, 16384, 1, infile);
		if (feof(infile)) { break; }
		if (res!=1) { break; }

		smd2bin(smd_block, raw_block);
		fwrite(raw_block, 16384, 1, outfile);
		bytes+=16384;
	}
	printf("Wrote %d Bytes (%d Kb)\n", bytes, bytes/1024);
		
	fclose(outfile);
	fclose(infile);

	return 0;
}

/* Adapted from pseudocode found in smdform.txt:
 *
 * Super Magic Driver file format information
 * by Charles MacDonald
 * http://cgfm2.emuviews.com */
void smd2bin(char *inblk, char *outblk)
{
	int n;

	for (n=0; n<0x2000; n++)
	{
		outblk[n*2] = inblk[0x2000+n];
		outblk[n*2+1] = inblk[n];
	}
}
