// gcc -o ss_pbin_patch ss_pbin_patch.c
// version 1.1
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <byteswap.h>
#define ENTRY_OFFSET 0x068c8
#define STORY_OFFSET 0x10a7a
#define PATCH_OFFSET 0x9ddd0
#define PBIN_OFFSET 0x9e000
char entry_code[] = {
0x4e, 0xf9, 0x00, 0x09, 0xdd, 0xd0, 0x4e, 0x71
};
char story_code[] = {
0x60, 0x0e
};
char patch_code[] = {
0x48, 0xe7, 0xe0, 0xc0, 0x4a, 0x2d, 0x7d, 0x83, 0x67, 0x1e, 0x43, 0xfa, 0x02,
0x24, 0x20, 0x19, 0x58, 0x89, 0x53, 0x40, 0x20, 0x19, 0xb1, 0xd9, 0x67, 0x06,
0x51, 0xc8, 0xff, 0xf8, 0x60, 0x08, 0xd0, 0xbc, 0x00, 0x09, 0xe0, 0x00, 0x20,
0x40, 0x43, 0xed, 0x18, 0x8e, 0x4e, 0xf8, 0x68, 0xd0
};
int main(int argc, char **argv) {
FILE *pbin, *rom;
uint32_t num_patches;
uint32_t data32;
uint16_t data16;
int32_t i, j;
if(argc < 3) {
printf("ss_pbin_patch <pbin> <rom>\n");
return 1;
}
pbin = fopen(argv[1], "r");
if(!pbin) {
printf("Error: unable to open %s for reading.\n", argv[1]);
return 1;
}
rom = fopen(argv[2], "r+");
if(!rom) {
printf("Error: unable to open %s for writing.\n", argv[2]);
return 1;
}
// header part of pbin needs to be 32bit swapped
fseek(rom, PBIN_OFFSET, SEEK_SET);
fread(&num_patches, sizeof(uint32_t), 1, pbin);
printf("Number of patches: %d\n", num_patches);
fseek(pbin, 0, SEEK_SET);
for(i = 0; i < (num_patches * 2) + 2;i++) {
fread(&data32, sizeof(data32), 1, pbin);
data32 = bswap_32(data32);
fwrite(&data32, sizeof(data32), 1, rom);
}
// data part of pbin needs to be 16bit swapped
while(fread(&data16, sizeof(data16), 1, pbin) == 1) {
data16 = bswap_16(data16);
fwrite(&data16, sizeof(data16), 1, rom);
}
fseek(rom, ENTRY_OFFSET, SEEK_SET);
fwrite(&entry_code, sizeof(entry_code), 1, rom);
fseek(rom, STORY_OFFSET, SEEK_SET);
fwrite(&story_code, sizeof(story_code), 1, rom);
fseek(rom, PATCH_OFFSET, SEEK_SET);
fwrite(&patch_code, sizeof(patch_code), 1, rom);
fclose(pbin);
fclose(rom);
}