psxsdk/tools/exefixup.c

205 lines
4.9 KiB
C

/*
* exefixup.c v0.02.1 Andrew Kieschnick <andrewk@mail.utexas.edu>
* (v0.02.1): Giuseppe Gatta <tails92@gmail.com>
*
* v0.02.1 changes: removed warnings
*
* displays PS-X EXE header information
* offers to fix incorrect t_size
* offers to pad to 2048-byte boundary for cd-rom use
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
unsigned int char2int(unsigned char *foo)
{
return foo[3]*16777216 + foo[2]*65536 + foo[1]*256 + foo[0];
}
void int2char(unsigned int foo, unsigned char *bar)
{
bar[3]=foo>>24;
bar[2]=foo>>16;
bar[1]=foo>>8;
bar[0]=foo;
}
void usage(void)
{
printf("Usage: exefixup <filename>\n\n");
printf("\t<filename>\ta PS-X EXE file\n\n");
printf("\tdisplays EXE header\n");
printf("\toffers to correct a wrong t_size\n");
printf("\toffers to pad to 2048-byte boundary\n\n");
exit(0);
}
int main(int argc, char *argv[])
{
FILE *exe;
FILE *out;
unsigned char data[9];
char filename[256];
int i;
unsigned int header_data[12];
unsigned int size;
unsigned int padsize;
signed char yesno='Z';
printf("exefixup v0.02.1 Andrew Kieschnick <andrewk@mail.utexas.edu>\n\n");
if (argc!=2)
usage();
strncpy(filename,argv[1],256);
exe=fopen(filename, "r");
strcat(filename, "-fixed"); /* output filename is same as input filename, but with -fix appended */
if (!exe)
{
printf("ERROR: Can't open %s\n",filename);
exit(-1);
}
for(i=0;i<8;i++)
fscanf(exe, "%c", &data[i]);
data[8]=0;
if (strncmp((char*)data, "PS-X EXE", 8))
{
printf("ERROR: Not a PS-X EXE file\n");
exit(-1);
}
for(i=0;i<12;i++)
{
fscanf(exe, "%c", &data[0]);
fscanf(exe, "%c", &data[1]);
fscanf(exe, "%c", &data[2]);
fscanf(exe, "%c", &data[3]);
header_data[i]=char2int(data);
}
printf("id\tPS-X EXE\n");
printf("text\t0x%.8x\n", header_data[0]);
printf("data\t0x%.8x\n", header_data[1]);
printf("pc0\t0x%.8x\n", header_data[2]);
printf("gp0\t0x%.8x\n", header_data[3]);
printf("t_addr\t0x%.8x\n", header_data[4]);
printf("t_size\t0x%.8x\n", header_data[5]);
printf("d_addr\t0x%.8x\n", header_data[6]);
printf("d_size\t0x%.8x\n", header_data[7]);
printf("b_addr\t0x%.8x\n", header_data[8]);
printf("b_size\t0x%.8x\n", header_data[9]);
printf("s_addr\t0x%.8x\n", header_data[10]);
printf("s_size\t0x%.8x\n\n", header_data[11]);
fseek(exe, 0, SEEK_END);
size=ftell(exe)-2048;
padsize=2048-(size%2048);
if (padsize!=2048)
{
printf("WARNING: EXE size is not a multiple of 2048!\n");
while ((yesno!='Y')&&(yesno!='N'))
{
printf("Write a padded EXE (to %s) ? ",filename);
scanf("%c%*c", &yesno);
yesno=toupper(yesno);
}
if (yesno=='Y')
{
out = fopen(filename, "w");
header_data[5]=size+padsize;
fprintf(out, "PS-X EXE");
for(i=0;i<12;i++)
{
int2char(header_data[i], data);
fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
}
fseek(exe, 56, SEEK_SET);
for(i=0;i<size+1992;i++)
{
fscanf(exe, "%c", &data[0]);
fprintf(out, "%c", data[0]);
}
for(i=0;i<padsize;i++)
fprintf(out, "%c", 0);
size=header_data[5];
fclose(out);
}
}
yesno='Z';
if (size!=header_data[5])
{
printf("WARNING: EXE header t_size does not match filesize-2048\n");
printf("EXE header:\t 0x%.8x bytes\n", header_data[5]);
printf("filesize-2048:\t 0x%.8x bytes\n", size);
while ((yesno!='Y')&&(yesno!='N'))
{
printf("Write a corrected EXE (to %s) ? ",filename);
scanf("%c%*c", &yesno);
yesno=toupper(yesno);
}
if (yesno=='Y')
{
out = fopen(filename, "w");
fprintf(out, "PS-X EXE");
for(i=0;i<5;i++)
{
int2char(header_data[i], data);
fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
}
int2char(size, data);
fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
for(i=6;i<12;i++)
{
int2char(header_data[i], data);
fprintf(out, "%c%c%c%c", data[0], data[1], data[2], data[3]);
}
fseek(exe, 56, SEEK_SET);
for(i=0;i<size+1992;i++)
{
fscanf(exe, "%c", &data[0]);
fprintf(out, "%c", data[0]);
}
fclose(out);
}
}
fclose(exe);
return 0;
}