mirror of
https://github.com/rdolbeau/VintageBusFPGA_Common.git
synced 2026-04-11 22:52:59 +00:00
start mering patcher
This commit is contained in:
41
RomPatcher/IIsiRemoveChecksumCheck/Makefile
Normal file
41
RomPatcher/IIsiRemoveChecksumCheck/Makefile
Normal file
@@ -0,0 +1,41 @@
|
||||
RETRO68=/home/dolbeau/Retro68/build/toolchain
|
||||
AS=${RETRO68}/bin/m68k-apple-macos-as
|
||||
CC=${RETRO68}/bin/m68k-apple-macos-gcc
|
||||
LD=${RETRO68}/bin/m68k-apple-macos-ld
|
||||
STRIP=${RETRO68}/bin/m68k-apple-macos-strip
|
||||
OBJCOPY=${RETRO68}/bin/m68k-apple-macos-objcopy
|
||||
NM=${RETRO68}/bin/m68k-apple-macos-nm
|
||||
|
||||
HOSTCC=gcc
|
||||
HOSTCFLAGS=-O2
|
||||
|
||||
ARCHFLAGS=-march=68020 -mcpu=68020
|
||||
CFLAGS=-O2 -mpcrel
|
||||
|
||||
GENLINK=../patcher/genlink
|
||||
PATCHER=../patcher/patcher
|
||||
|
||||
all: IIsi.ROM
|
||||
|
||||
show: rompatch.elf
|
||||
$(NM) $< | sort
|
||||
|
||||
IIsi.ROM: ../IIsi.ROM rompatch.raw input.txt
|
||||
/bin/cp ../IIsi.ROM IIsi.ROM
|
||||
${PATCHER} -i rompatch.raw -p IIsi.ROM -d input.txt
|
||||
|
||||
linker.ld: input.txt rompatch.s
|
||||
${GENLINK} -d $< >| $@
|
||||
$(shell for X in `grep .section rompatch.s | awk '{ print $$2 }' `; do grep -q $$X linker.ld || echo " $$X has no entry in linker.ld" && /bin/false; done)
|
||||
|
||||
rompatch.o: rompatch.s
|
||||
${AS} ${ARCHFLAGS} $< -o $@ -a > rompatch.l
|
||||
|
||||
rompatch.elf: linker.ld rompatch.o ${CSRC:.c=.o} # linker script must be first
|
||||
${LD} -o $@ -T $^
|
||||
|
||||
rompatch.raw: rompatch.elf
|
||||
${OBJCOPY} $^ $@ --input-target=elf32-m68k --output-target=binary
|
||||
|
||||
clean:
|
||||
rm -f res.inc ${CSRC_ASM} *.o rompatch.srec rompatch.raw rompatch.dir rompatch.l VidRom*.s
|
||||
1
RomPatcher/IIsiRemoveChecksumCheck/input.txt
Normal file
1
RomPatcher/IIsiRemoveChecksumCheck/input.txt
Normal file
@@ -0,0 +1 @@
|
||||
0x0464e2, 10, removecheksumcheck
|
||||
12
RomPatcher/IIsiRemoveChecksumCheck/rompatch.s
Normal file
12
RomPatcher/IIsiRemoveChecksumCheck/rompatch.s
Normal file
@@ -0,0 +1,12 @@
|
||||
.section .text.removecheksumcheck
|
||||
|
||||
nops:
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
.section .text.returnremovecheksumcheck
|
||||
|
||||
.end
|
||||
50
RomPatcher/patcher/Makefile
Normal file
50
RomPatcher/patcher/Makefile
Normal file
@@ -0,0 +1,50 @@
|
||||
PATCHERSRC=patcher.c
|
||||
PATCHEROBJ=$(PATCHERSRC:.cpp=.o)
|
||||
PATCHERDEP=$(PATCHERSRC:.cpp=.d)
|
||||
GENLINKSRC=genlink.c
|
||||
GENLINKOBJ=$(GENLINKSRC:.cpp=.o)
|
||||
GENLINKDEP=$(GENLINKSRC:.cpp=.d)
|
||||
OOBJ=parser_par.o parser_lex.o
|
||||
LEX=flex
|
||||
YACC=bison -d #--report-file=bison.log --report=all
|
||||
CC=gcc
|
||||
CFLAGS=-O2
|
||||
|
||||
all: patcher genlink
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $< -c -o $@
|
||||
|
||||
patcher: $(PATCHEROBJ) $(OOBJ)
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
|
||||
genlink: $(GENLINKOBJ) $(OOBJ)
|
||||
$(CC) $(CFLAGS) $^ -o $@
|
||||
|
||||
parser_par.h: parser_par.o
|
||||
|
||||
parser_par.o: parser_par.y
|
||||
$(YACC) -o $(<:%.y=%.c) $<
|
||||
$(CC) $(CFLAGS) $(<:%.y=%.c) -c -o $@
|
||||
|
||||
parser_lex.o: parser_lex.l parser_par.h
|
||||
$(LEX) -o $(<:%.l=%.c) $<
|
||||
$(CC) $(CFLAGS) $(<:%.l=%.c) -c -o $@
|
||||
|
||||
%.d: %.cpp
|
||||
$(CXX) -MM $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(PATCHEROBJ) patcher
|
||||
|
||||
veryclean:
|
||||
rm -f $(PATCHEROBJ) patcher *~ parser_lex.c parser_par.c *.d
|
||||
|
||||
ultraclean:
|
||||
rm -f $(PATCHEROBJ) patcher *~ parser_lex.c parser_par.c *.d *.scala
|
||||
|
||||
|
||||
## avoid builtin rule for .o
|
||||
.SUFFIXES:
|
||||
SUFFIXES :=
|
||||
%.o:
|
||||
76
RomPatcher/patcher/genlink.c
Normal file
76
RomPatcher/patcher/genlink.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "parser.h"
|
||||
#include "parser_par.h"
|
||||
|
||||
extern FILE *yyin, *yyout;
|
||||
extern int yydebug;
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char* descfile = NULL;
|
||||
FILE *myfile;
|
||||
int c;
|
||||
azone zones[32];
|
||||
int nz = 0, i;
|
||||
|
||||
while ((c = getopt(argc, argv, "d:")) != -1) {
|
||||
switch(c) {
|
||||
default:
|
||||
fprintf(stderr, "oups : %c\n", c);
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
descfile = strndup(optarg, 512);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (descfile == NULL) {
|
||||
fprintf(stderr, "no desc\n");
|
||||
exit(-4);
|
||||
}
|
||||
|
||||
{
|
||||
myfile = fopen(descfile, "r");
|
||||
if (!myfile) {
|
||||
fprintf(stderr, "no desc file\n");
|
||||
exit(-5);
|
||||
}
|
||||
yyin = myfile;
|
||||
yyparse(zones, &nz);
|
||||
|
||||
fclose(myfile);
|
||||
|
||||
fprintf(stderr, "Found %d entries\n", nz);
|
||||
}
|
||||
|
||||
fprintf(stdout,
|
||||
"OUTPUT_FORMAT(\"elf32-m68k\");\n"
|
||||
"SECTIONS {\n"
|
||||
" .text : {\n");
|
||||
|
||||
for (i = 0 ; i < nz; i++) {
|
||||
fprintf(stdout, " . = 0x%06x;\n", zones[i].address);
|
||||
fprintf(stdout, " *(.text.%s)\n", zones[i].name);
|
||||
if (zones[i].size > 0) {
|
||||
fprintf(stdout, " . = 0x%06x;\n", zones[i].address + zones[i].size);
|
||||
fprintf(stdout, " *(.text.return%s)\n", zones[i].name);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
fprintf(stdout, " }\n}\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
10
RomPatcher/patcher/parser.h
Normal file
10
RomPatcher/patcher/parser.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef __PATCHER_H__
|
||||
#define __PATCHER_H__
|
||||
|
||||
typedef struct {
|
||||
unsigned long address;
|
||||
unsigned long size;
|
||||
char* name;
|
||||
} azone;
|
||||
|
||||
#endif // __PATCHER_H__
|
||||
34
RomPatcher/patcher/parser_lex.l
Normal file
34
RomPatcher/patcher/parser_lex.l
Normal file
@@ -0,0 +1,34 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2023 Romain Dolbeau <romain@dolbeau.org>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parser.h"
|
||||
#include "parser_par.h"
|
||||
%}
|
||||
|
||||
DIGIT [0-9]
|
||||
HEXPREFIX "0x"
|
||||
HEXDIGIT [0-9a-fA-F]
|
||||
SPACE [ \t]
|
||||
FCHARNAME [[:alpha:]]
|
||||
CHARNAME [[:alnum:]_]
|
||||
|
||||
%%
|
||||
|
||||
{HEXPREFIX}{HEXDIGIT}{HEXDIGIT}* { yylval.num = strtol(yytext, NULL, 16); return NUM; }
|
||||
|
||||
{DIGIT}{DIGIT}* { yylval.num = strtol(yytext, NULL, 10); return NUM; }
|
||||
|
||||
{FCHARNAME}{CHARNAME}* { yylval.string = strdup(yytext); return NAME; }
|
||||
|
||||
, { return yytext[0]; }
|
||||
|
||||
\n { return yytext[0]; }
|
||||
|
||||
{SPACE}+ { }
|
||||
|
||||
%%
|
||||
46
RomPatcher/patcher/parser_par.y
Normal file
46
RomPatcher/patcher/parser_par.y
Normal file
@@ -0,0 +1,46 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2023 Romain Dolbeau <romain@dolbeau.org>
|
||||
* MIT License
|
||||
* See the LICENSE file at the top level of this software distribution for details.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define YYDEBUG 1
|
||||
#include "parser.h"
|
||||
%}
|
||||
|
||||
%parse-param {azone *zones} {int *nz}
|
||||
|
||||
%union
|
||||
{
|
||||
unsigned long num;
|
||||
char* string;
|
||||
}
|
||||
|
||||
%token <num> NUM
|
||||
%token <num> NAME
|
||||
|
||||
%%
|
||||
input: /* empty */ { }
|
||||
| zone input { }
|
||||
;
|
||||
|
||||
zone:
|
||||
NUM ',' NUM ',' NAME { /* printf("0x%08lx %ld\n", $1, $3); */ zones[*nz].address = $1; zones[*nz].size = $3; zones[*nz].name = $5; (*nz)++; }
|
||||
| '\n'
|
||||
;
|
||||
%%
|
||||
|
||||
int
|
||||
yyerror(char *s)
|
||||
{
|
||||
fprintf(stderr, "error: %s\n", s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap(void)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
146
RomPatcher/patcher/patcher.c
Normal file
146
RomPatcher/patcher/patcher.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "parser.h"
|
||||
#include "parser_par.h"
|
||||
|
||||
extern FILE *yyin, *yyout;
|
||||
extern int yydebug;
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char* descfile = NULL;
|
||||
char* patchedfile = NULL;
|
||||
char* inputfile = NULL;
|
||||
FILE *myfile;
|
||||
int c;
|
||||
azone zones[32];
|
||||
int nz = 0, i;
|
||||
unsigned long j;
|
||||
char *input;
|
||||
size_t input_size;
|
||||
char *patched;
|
||||
size_t patched_size;
|
||||
|
||||
while ((c = getopt(argc, argv, "d:i:p:")) != -1) {
|
||||
switch(c) {
|
||||
default:
|
||||
fprintf(stderr, "oups : %c\n", c);
|
||||
exit(-1);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
descfile = strndup(optarg, 512);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
inputfile = strndup(optarg, 512);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
patchedfile = strndup(optarg, 512);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (descfile == NULL) {
|
||||
fprintf(stderr, "no desc\n");
|
||||
exit(-4);
|
||||
}
|
||||
if (inputfile == NULL) {
|
||||
fprintf(stderr, "no input\n");
|
||||
exit(-2);
|
||||
}
|
||||
if (patchedfile == NULL) {
|
||||
fprintf(stderr, "nothing to patch\n");
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
myfile = fopen(descfile, "r");
|
||||
if (!myfile) {
|
||||
fprintf(stderr, "no desc file\n");
|
||||
exit(-5);
|
||||
}
|
||||
yyin = myfile;
|
||||
yyparse(zones, &nz);
|
||||
|
||||
fclose(myfile);
|
||||
|
||||
fprintf(stdout, "Found %d entries\n", nz);
|
||||
}
|
||||
|
||||
{
|
||||
int fd;
|
||||
fd = open(inputfile, O_RDONLY | O_EXCL);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "no input file\n");
|
||||
exit(-6);
|
||||
}
|
||||
struct stat statbuf;
|
||||
int err = fstat(fd, &statbuf);
|
||||
if (err < 0){
|
||||
fprintf(stderr, "no input file stat\n");
|
||||
close(fd);
|
||||
exit(-7);
|
||||
}
|
||||
input_size = statbuf.st_size;
|
||||
input = mmap(NULL, input_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (input == MAP_FAILED){
|
||||
fprintf(stderr, "no input file map (%p for %s %zd: %d / %s)\n", input, inputfile, input_size, errno, strerror(errno));
|
||||
close(fd);
|
||||
exit(-8);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
{
|
||||
int fd;
|
||||
fd = open(patchedfile, O_RDWR | O_EXCL);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "no patched file\n");
|
||||
exit(-6);
|
||||
}
|
||||
struct stat statbuf;
|
||||
int err = fstat(fd, &statbuf);
|
||||
if (err < 0){
|
||||
fprintf(stderr, "no patched file stat\n");
|
||||
close(fd);
|
||||
exit(-7);
|
||||
}
|
||||
|
||||
patched_size = statbuf.st_size;
|
||||
patched = mmap(NULL, patched_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (patched == MAP_FAILED){
|
||||
fprintf(stderr, "no patched file map\n");
|
||||
close(fd);
|
||||
exit(-8);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
for (i = 0 ; i < nz; i++) {
|
||||
if (zones[i].size > 0) {
|
||||
fprintf(stdout, "Patching [%08p:%08p[ (%s)\n", (void*)zones[i].address, (void*)(zones[i].address + zones[i].size), zones[i].name);
|
||||
for (j = zones[i].address; j < zones[i].address + zones[i].size; j++) {
|
||||
patched[j] = input[j];
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout, "Not patching [%08p[ (%s)\n", (void*)zones[i].address, zones[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
munmap(input, input_size);
|
||||
munmap(patched, patched_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user