Files
2025-07-29 11:18:41 +02:00

104 lines
2.2 KiB
C

/*
* injector <input.bin> <patch.hex> <output.bin>
* e.g.: ./injector image.bin patch.hex image_patched.bin
*/
#include <stdio.h>
#include <stdlib.h>
#define OFFSET 2
// Use a 4MB buffer, the same as the flash rom size
#define BUFFER_SIZE 0x400000
unsigned char buffer[BUFFER_SIZE];
FILE *inptr, *outptr, *patchptr;
int bank = 0;
int main(int argc, char **argv)
{
char * line = NULL;
size_t len = 0;
unsigned int addr, value;
if (argc != 4) {
printf("I only work with 3 arguments\n");
return 5;
}
inptr = fopen(argv[1], "rb");
if (inptr == NULL) {
printf("Cannot open %s\n", argv[1]);
return 5;
}
fseek(inptr, 0L, SEEK_END);
size_t filesize = ftell(inptr);
rewind(inptr);
printf("Input file size: %ld\n", filesize);
if (filesize > BUFFER_SIZE) {
printf("File too large.\n");
return 5;
}
size_t bytes_read = fread(buffer, 1, sizeof(buffer), inptr);
printf("Bytes read: %ld\n", bytes_read);
if (bytes_read != filesize) {
printf("Error reading input file.\n");
return 5;
}
fclose(inptr);
patchptr = fopen(argv[2], "r");
if (patchptr == NULL) {
printf("Cannot open %s\n", argv[1]);
return 5;
}
size_t l;
int patches = 0;
while ((l = getline(&line, &len, patchptr)) != -1) {
// printf("Retrieved line of length %zu:\n", l);
sscanf(line, "%x: %x", &addr, &value);
if (addr < 0x4000)
addr += OFFSET;
if (addr >= 0xff00) { // A bank change
bank = value % 64;
bank = bank == 1 ? 0 : bank;
printf("Switching to bank: %d\n", bank);
continue;
}
if (addr < filesize) {
patches++;
if (bank) {
buffer[addr + (bank-1) * 0xc000] = value;
printf("%s gives %x <- %x\n", line, addr + (bank-1) * 0xc000, value);
} else {
buffer[addr] = value;
}
// printf("%s gives %x <- %x\n", line, addr, value);
} else {
printf("Cannot patch: %s\n", line);
}
}
printf("Patched %d bytes.\n", patches);
fclose(patchptr);
if (line)
free(line);
outptr = fopen(argv[3], "wb");
if (outptr == NULL) {
printf("Cannot open %s\n", argv[1]);
return 5;
}
size_t written = fwrite(buffer, 1, filesize, outptr);
if (written != filesize) {
printf("Error writing output file.\n");
return 5;
}
fclose(outptr);
return 0;
}