/*--------------------------------------------------------------------*/
/* RAM-CART to XEX - (c) GienekP                                      */
/*--------------------------------------------------------------------*/
#include <stdio.h>
/*--------------------------------------------------------------------*/
#define BANKSIZE (16*1024)
/*--------------------------------------------------------------------*/
void prepareInfo(FILE *file)
{
	const unsigned char init[]={
		0xFF,0xFF	// DOS Header		
		};
	fwrite(init,sizeof(unsigned char),sizeof(init),file);
}
/*--------------------------------------------------------------------*/
void newBank(FILE *file, unsigned int bank)
{
	unsigned char config[10]={0x00,0xD5,0x01,0xD5,0xFF,0xFF,0x00,0x08,0xFF,0xBF};
	unsigned int D500,D501;
	D500=(((bank&0x3F)<<2)|0x03);
	D501=((bank>>6)&0xFF);
	config[4]=D500;
	config[5]=D501;
	fwrite(config,sizeof(unsigned char),sizeof(config),file);
}
/*--------------------------------------------------------------------*/
void clearBuf(unsigned char *buf, unsigned int size)
{
	unsigned int i;
	for (i=0; i<size; i++) {buf[i]=0xFF;};
};
/*--------------------------------------------------------------------*/
void ramcart2xex(const char *fin, const char *fout)
{
	unsigned int i,fsize,bsize;
	unsigned char buf[BANKSIZE];
    FILE *fi,*fo;
    fi=fopen(fin,"rb");
    if (fi)
    {
		printf("Open \"%s\"\n",fin);
		fseek(fi,0,SEEK_END);
		fsize=ftell(fi);
		bsize=(fsize/BANKSIZE)+1;
		printf("Input size: %i bytes\n",fsize);
		printf("No banks[16kB]: %i\n",bsize);
		fseek(fi,0,0);
		fo=fopen(fout,"wb");
		if (fo)
		{
			printf("XEX \"%s\"\n",fout);
			prepareInfo(fo);
			for (i=0; i<bsize; i++)
			{
				newBank(fo,i);
				clearBuf(buf,BANKSIZE);
				fread(buf,sizeof(unsigned char),BANKSIZE,fi);
				fwrite(buf,sizeof(unsigned char),BANKSIZE,fo);	
			};
			fclose(fo);
		};
		fclose(fi);
	};
}
/*--------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
	printf("RAM-CART image to XEX - (c) GienekP\n");
	switch (argc)
	{
		case 3:
		{
			ramcart2xex(argv[1],argv[2]);
		} break;
		default:
		{
			printf("use:\n");
			printf("   ramcart2xex ramcartimage.raw output.xex\n");	
		} break;
	};
	return 0;
}
/*--------------------------------------------------------------------*/
