Last active
December 8, 2016 09:55
-
-
Save superctr/ac8b07d950f5aea6d83cb1b76594508f to your computer and use it in GitHub Desktop.
opl2to4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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