mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
104 lines
2.2 KiB
C
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;
|
|
}
|