Skip to content

Instantly share code, notes, and snippets.

@superctr
Last active December 8, 2016 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superctr/ac8b07d950f5aea6d83cb1b76594508f to your computer and use it in GitHub Desktop.
Save superctr/ac8b07d950f5aea6d83cb1b76594508f to your computer and use it in GitHub Desktop.
opl2to4
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
/*
convert opl2 commands to opl4 commands
*/
void cni(uint8_t** dest, void* src, int size)
{
memcpy(*dest,src,size);
*dest += size;
}
int main(int argc, char* argv [])
{
if(argc<2)
{
printf("Usage: <file> <destination file>\n");
exit(EXIT_FAILURE);
}
char* file1 = argv[1];
char* file2 = argv[1];
if(argv[2] != NULL)
file2 = argv[2];
int res;
FILE* sourcefile;
sourcefile = fopen(file1,"rb");
if(!sourcefile)
{
printf("Could not open %s\n",file1);
exit(EXIT_FAILURE);
}
fseek(sourcefile,0,SEEK_END);
unsigned long sourcefile_size = ftell(sourcefile);
rewind(sourcefile);
uint8_t* source = (uint8_t*)malloc(sourcefile_size);
uint8_t* dest = (uint8_t*)malloc(sourcefile_size*2);
res = fread(source,1,sourcefile_size,sourcefile);
if(res != sourcefile_size)
{
printf("Reading error\n");
exit(EXIT_FAILURE);
}
fclose(sourcefile);
/////////////////////////////////////////////////////////
uint8_t *srcptr, *destptr = dest, *looppos = source, *endptr = source+sourcefile_size-5;
int chipcommands = 0, chip2commands = 0, endofdata = 0;
unsigned long i;
int channel=0, addr=0, value=0, badflag=0, badchannel=0;
looppos += (*(uint32_t*)(source+0x1c)) + 0x1c;
srcptr = source + (*(uint32_t*)(source+0x34)) + 0x34;
int cpsize=srcptr-source, skip;
cni(&destptr,source,cpsize);
uint8_t expansion_reg = 0;
while((srcptr < endptr) && !endofdata)
{
if(srcptr == looppos)
*(uint32_t*)(dest+0x1c) = (destptr-dest)-0x1c;
uint8_t d = (*srcptr);
uint8_t cmd = *(srcptr+1);
uint8_t data1 = *(srcptr+2);
uint8_t data2 = *(srcptr+3);
//printf("%08x = %02x, %08x\n",srcptr-source,d,destptr-dest);
if(d==0x66)
endofdata = 1;
else if(d==0x5a || d==0x5e || d==0x5f)
{
*destptr++ = 0xd0;
*destptr++ = d==0x5f ? 0x01 : 0x00;
if(cmd == 0x05)
{
expansion_reg |= data1;
*destptr++ = 0x05;
*destptr++ = expansion_reg;
//printf("Expansion reg: %02x\n",expansion_reg);
}
else
cni(&destptr,srcptr+1,2);
srcptr+=3;
chipcommands++;
}
else if(d==0xd0)
{
if(cmd < 0x02 && data1 == 0x05)
{
expansion_reg |= data2;
*destptr++ = 0xd0;
*destptr++ = 0x00;
*destptr++ = 0x05;
*destptr++ = expansion_reg;
//printf("Expansion reg: %02x\n",expansion_reg);
}
else
cni(&destptr,srcptr,4);
srcptr+=4;
chip2commands++;
}
else if (d==0x67)
{
skip = *(uint32_t*)(srcptr+3) & 0x0FFFFFFF;
cni(&destptr,srcptr,skip+7);
srcptr += skip+7;
}
else if(d == 0x4f || d == 0x50 || (d>=0x30 && d<0x40))
{
cni(&destptr,srcptr,2);
srcptr+=2;
}
else if((d>0x50 && d<0x62) || (d>=0xa0 && d<0xc0))
{
cni(&destptr,srcptr,3);
srcptr+=3;
}
else if(d>=0xc0 && d<0xe0)
{
cni(&destptr,srcptr,4);
srcptr+=4;
}
else if(d>=0xe0 && d<0xe3)
{
cni(&destptr,srcptr,5);
srcptr+=5;
}
else
{
cni(&destptr,srcptr,1);
srcptr++;
}
}
printf("changed %d OPL2/OPL3 commands, %d OPL4 commands\n",chipcommands,chip2commands);
*(uint32_t*)(dest+0x60) = 33868800;
uint32_t id3offset = *(uint32_t*)(source+0x14);
if(id3offset>0)
*(uint32_t*)(dest+0x14) = (destptr-dest)-0x13;
cni(&destptr,srcptr, sourcefile_size-(srcptr-source));
*(uint32_t*)(dest+0x04) = (destptr-dest)-0x04;
FILE *destfile;
destfile = fopen(file2,"wb");
if(!destfile)
{
printf("Could not open %s\n",file2);
exit(EXIT_FAILURE);
}
for(i=0;i<(destptr-dest);i++)
{
putc(*(dest+i),destfile);
}
fclose(destfile);
printf("wrote %lu bytes to %s\n",i,file2);
free(dest);
free(source);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment