/* 08/07/01 Console app to patch Codewarrior PS-X EXE's to run on emulators etc, based on the code from Andrew Kieschnick's eco2exe. The patching adds two mips jump instructions at the end of the file, the first is an address in system memory, the second is the exe's start address. The first address is jumped to at the start of program execution, when it returns the original start address is executed. The pc0 and t_size values are altered accordingly */ /* includes */ #include "windows.h" #include "stdio.h" #include "string.h" #include "conio.h" int Openfile(int argc, char *fname); /* globals */ FILE *file_p; char str[8]; struct { unsigned long pc0, dummy, start_addr, size; }data; struct { unsigned long sysjump, nop, oldpc0, nop2; }mips = {0x0C00400C}; /* jal 0x80010030 */ void main(int argc, char *argv[]) { printf("\t\tCodeWarrior PS-X EXE File Patcher\n"); if(Openfile(argc, argv[1])) /* attempt to open file */ { fseek(file_p, 16, SEEK_SET); /* seek to pc0 */ /* read in required values, we don't need 2nd */ fread(&data, 4, 4, file_p); mips.oldpc0 = data.pc0; /* keep original start address */ data.pc0 = data.start_addr + data.size; /* new code added at end of exe */ data.size += 16; /* exe size increased */ /* write new pc0 and size back to file */ fseek(file_p, 16, SEEK_SET); fwrite(&data, 4, 4, file_p); /* add jump address instructions to exe end */ fseek(file_p, 0, SEEK_END); /* create instruction to jump to original start address */ mips.oldpc0 = 0x08000000 + ((mips.oldpc0&0x03ffffff)>>2); fwrite(&mips, 4, 4, file_p); printf("File patched.\n"); fclose(file_p); Sleep(1500); } } /* attempt to open file, check it's a CW exe */ int Openfile(int argc, char *fname) { if(argc == 2) { if(file_p = fopen(fname, "rb+")) { fread(str, 1, 4, file_p); /* read in PS-X at start of exe */ if(!strcmp(str, "PS-X")) return 1; else { printf("Not a PS-X EXE file.\n"); fclose(file_p); } } else printf("Cannot open file.\n"); } else printf("Syntax: cwpatch \n"); while(!kbhit()) Sleep(100); return 0; }