From 2e9c68f8c37e8188bee63e7d164ee59ca6bc5d52 Mon Sep 17 00:00:00 2001 From: Sanqui Date: Mon, 28 Mar 2016 01:02:05 +0200 Subject: [PATCH 1/5] Add overlay file option to rgblink (-O) This option takes a file and places fixed sections on top of it. Should prove useful for patches and partial disassemblies. --- include/link/mylink.h | 1 + include/link/output.h | 1 + src/link/assign.c | 13 +++++++++ src/link/main.c | 10 ++++--- src/link/output.c | 61 ++++++++++++++++++++++++++++++++++++------- 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/include/link/mylink.h b/include/link/mylink.h index 707d5fbf..f9f003c9 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -10,6 +10,7 @@ extern SLONG options; #define OPT_SMALL 0x01 #define OPT_SMART_C_LINK 0x02 +#define OPT_OVERLAY 0x04 enum eRpnData { RPN_ADD = 0, diff --git a/include/link/output.h b/include/link/output.h index 7256a92c..06147cff 100644 --- a/include/link/output.h +++ b/include/link/output.h @@ -2,6 +2,7 @@ #define RGBDS_LINK_OUTPUT_H void out_Setname(char *tzOutputfile); +void out_SetOverlayname(char *tzOverlayfile); void Output(void); #endif diff --git a/src/link/assign.c b/src/link/assign.c index 1d4c1b2e..c5bd0961 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -713,6 +713,10 @@ AssignSections(void) && pSection->Type == SECT_ROMX && pSection->nOrg == -1 && pSection->nBank != -1) { /* User wants to have a say... and he's pissed */ + if (options & OPT_OVERLAY) { + errx(1, "All ROM sections must be fixed when using overlay"); + } + if (pSection->nBank >= 1 && pSection->nBank <= 511) { if ((pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], @@ -789,6 +793,9 @@ AssignSections(void) && pSection->nOrg != -1 && pSection->nBank == -1) { /* User wants to have a say... and he's back with a * vengeance */ + if (options & OPT_OVERLAY) { + errx(1, "All ROM sections must be fixed when using overlay"); + } if ((pSection->nBank = area_AllocAbsROMXAnyBank(pSection->nOrg, pSection->nByteSize)) == @@ -875,6 +882,9 @@ AssignSections(void) case SECT_WRAMX: break; case SECT_ROM0: + if (options & OPT_OVERLAY) { + errx(1, "All ROM sections must be fixed when using overlay"); + } if ((pSection->nOrg = area_Alloc(&BankFree[BANK_ROM0], pSection->nByteSize)) == -1) { @@ -884,6 +894,9 @@ AssignSections(void) pSection->oAssigned = 1; break; case SECT_ROMX: + if (options & OPT_OVERLAY) { + errx(1, "All ROM sections must be fixed when using overlay"); + } break; default: errx(1, "(INTERNAL) Unknown section type!"); diff --git a/src/link/main.c b/src/link/main.c index 8eda44a8..ab87d9cb 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -35,8 +35,8 @@ static void usage(void) { printf( -"usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile] [-p pad_value]\n" -" [-s symbol] file [...]\n"); +"usage: rgblink [-t] [-m mapfile] [-n symfile] [-O overlay] [-o outfile] \n" +" [-p pad_value] [-s symbol] file [...]\n"); exit(1); } @@ -56,7 +56,7 @@ main(int argc, char *argv[]) progname = argv[0]; - while ((ch = getopt(argc, argv, "m:n:o:p:s:t")) != -1) { + while ((ch = getopt(argc, argv, "m:n:o:O:p:s:t")) != -1) { switch (ch) { case 'm': SetMapfileName(optarg); @@ -67,6 +67,10 @@ main(int argc, char *argv[]) case 'o': out_Setname(optarg); break; + case 'O': + out_SetOverlayname(optarg); + options |= OPT_OVERLAY; + break; case 'p': fillchar = strtoul(optarg, &ep, 0); if (optarg[0] == '\0' || *ep != '\0') { diff --git a/src/link/output.c b/src/link/output.c index 95feb6de..0dee1be3 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -8,9 +8,12 @@ #include "link/assign.h" char *tzOutname; +char *tzOverlayname = NULL; + +SLONG MaxOverlayBank; void -writehome(FILE * f) +writehome(FILE * f, FILE * f_overlay) { struct sSection *pSect; UBYTE *mem; @@ -18,15 +21,20 @@ writehome(FILE * f) mem = malloc(MaxAvail[BANK_ROM0]); if (!mem) return; - - memset(mem, fillchar, MaxAvail[BANK_ROM0]); + + if (f_overlay != NULL) { + fseek(f_overlay, 0L, SEEK_SET); + fread(mem, 1, MaxAvail[BANK_ROM0], f_overlay); + } else { + memset(mem, fillchar, MaxAvail[BANK_ROM0]); + } MapfileInitBank(0); pSect = pSections; while (pSect) { if (pSect->Type == SECT_ROM0) { memcpy(mem + pSect->nOrg, pSect->pData, - pSect->nByteSize); + pSect->nByteSize); MapfileWriteSection(pSect); } pSect = pSect->pNext; @@ -39,7 +47,7 @@ writehome(FILE * f) } void -writebank(FILE * f, SLONG bank) +writebank(FILE * f, FILE * f_overlay, SLONG bank) { struct sSection *pSect; UBYTE *mem; @@ -48,14 +56,19 @@ writebank(FILE * f, SLONG bank) if (!mem) return; - memset(mem, fillchar, MaxAvail[bank]); + if (f_overlay != NULL && bank <= MaxOverlayBank) { + fseek(f_overlay, bank*0x4000, SEEK_SET); + fread(mem, 1, MaxAvail[bank], f_overlay); + } else { + memset(mem, fillchar, MaxAvail[bank]); + } MapfileInitBank(bank); pSect = pSections; while (pSect) { if (pSect->Type == SECT_ROMX && pSect->nBank == bank) { memcpy(mem + pSect->nOrg - 0x4000, pSect->pData, - pSect->nByteSize); + pSect->nByteSize); MapfileWriteSection(pSect); } pSect = pSect->pNext; @@ -73,18 +86,48 @@ out_Setname(char *tzOutputfile) tzOutname = tzOutputfile; } +void +out_SetOverlayname(char *tzOverlayfile) +{ + tzOverlayname = tzOverlayfile; +} + + void Output(void) { SLONG i; FILE *f; + FILE *f_overlay = NULL; + if ((f = fopen(tzOutname, "wb"))) { - writehome(f); + if (tzOverlayname) { + f_overlay = fopen(tzOverlayname, "rb"); + fseek(f_overlay, 0, SEEK_END); + if (ftell(f_overlay) % 0x4000 != 0) { + fprintf(stderr, "Overlay file must be aligned to 0x4000 bytes"); + exit(1); + } + MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1; + if (MaxOverlayBank < 1) { + fprintf(stderr, "Overlay file be at least 0x8000 bytes"); + exit(1); + } + if (MaxOverlayBank > MaxBankUsed) { + MaxBankUsed = MaxOverlayBank; + } + } + + writehome(f, f_overlay); for (i = 1; i <= MaxBankUsed; i += 1) - writebank(f, i); + writebank(f, f_overlay, i); fclose(f); + + if (tzOverlayname) { + fclose(f_overlay); + } } for (i = BANK_WRAM0; i < MAXBANKS; i++) { struct sSection *pSect; From 280ca83acdbe92d6c874271bfd8d93a76bddfea5 Mon Sep 17 00:00:00 2001 From: Sanqui Date: Mon, 28 Mar 2016 20:46:10 +0200 Subject: [PATCH 2/5] Fix opening nonexistent overlay files --- src/link/output.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/link/output.c b/src/link/output.c index 0dee1be3..e1fa1207 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -104,15 +104,19 @@ Output(void) if ((f = fopen(tzOutname, "wb"))) { if (tzOverlayname) { f_overlay = fopen(tzOverlayname, "rb"); + if (!f_overlay) { + fprintf(stderr, "Failed to open overlay file %s\n", tzOverlayname); + exit(1); + } fseek(f_overlay, 0, SEEK_END); if (ftell(f_overlay) % 0x4000 != 0) { - fprintf(stderr, "Overlay file must be aligned to 0x4000 bytes"); - exit(1); + fprintf(stderr, "Overlay file must be aligned to 0x4000 bytes\n"); + exit(1); } MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1; if (MaxOverlayBank < 1) { - fprintf(stderr, "Overlay file be at least 0x8000 bytes"); - exit(1); + fprintf(stderr, "Overlay file be at least 0x8000 bytes\n"); + exit(1); } if (MaxOverlayBank > MaxBankUsed) { MaxBankUsed = MaxOverlayBank; From 5a7faa7dffde60acbbf6ed9d512b19ce76fd00b1 Mon Sep 17 00:00:00 2001 From: Sanqui Date: Tue, 28 Feb 2017 18:44:12 +0100 Subject: [PATCH 3/5] Add overlay to rgblink manpage --- src/link/rgblink.1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/link/rgblink.1 b/src/link/rgblink.1 index f4a22729..d6a6975a 100644 --- a/src/link/rgblink.1 +++ b/src/link/rgblink.1 @@ -9,6 +9,7 @@ .Op Fl t .Op Fl m Ar mapfile .Op Fl n Ar symfile +.Op Fl O Ar overlayfile .Op Fl o Ar outfile .Op Fl p Ar pad_value .Op Fl s Ar symbol @@ -32,6 +33,10 @@ The arguments are as follows: Write a mapfile to the given filename. .It Fl n Ar symfile Write a symbol file to the given filename. +.It Fl O Ar overlayfile +The ROM image to overlay sections over. +When an overlay ROM is provided, all sections must be fixed. +This may be used to patch an existing binray. .It Fl o Ar outfile Write ROM image to the given filename. .It Fl p Ar pad_value From bc2f885d29905e2f4336ad042fc31c576823abb6 Mon Sep 17 00:00:00 2001 From: Sanqui Date: Thu, 2 Mar 2017 23:02:56 +0100 Subject: [PATCH 4/5] Also require ROM0 sections to be fixed when using overlay --- src/link/assign.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/link/assign.c b/src/link/assign.c index cbaa2719..b07b061f 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -259,8 +259,9 @@ AssignFloatingBankSections(enum eSectionType type) SLONG org; if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) { - if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) { - errx(1, "All ROMX sections must be fixed when using overlay"); + if (options & OPT_OVERLAY && + (pSection->Type == SECT_ROMX || pSection->Type == SECT_ROM0)) { + errx(1, "All ROM sections must be fixed when using overlay"); } pSection->nOrg = org & 0xFFFF; pSection->nBank = org >> 16; @@ -405,8 +406,9 @@ AssignSections(void) while (pSection) { if (pSection->oAssigned == 0 && pSection->nOrg != -1 && pSection->nBank == -1) { - if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) { - errx(1, "All ROMX sections must be fixed when using overlay"); + if (options & OPT_OVERLAY && + (pSection->Type == SECT_ROMX || pSection->Type == SECT_ROM0)) { + errx(1, "All ROM sections must be fixed when using overlay"); } switch (pSection->Type) { case SECT_ROMX: From 263c9222ab17a6b499b797b64d0654b0ce29d172 Mon Sep 17 00:00:00 2001 From: Sanqui Date: Mon, 13 Mar 2017 17:08:27 +0100 Subject: [PATCH 5/5] Require all sections to be fixed when using overlay --- src/link/assign.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/link/assign.c b/src/link/assign.c index b07b061f..2a97687f 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -259,9 +259,8 @@ AssignFloatingBankSections(enum eSectionType type) SLONG org; if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) { - if (options & OPT_OVERLAY && - (pSection->Type == SECT_ROMX || pSection->Type == SECT_ROM0)) { - errx(1, "All ROM sections must be fixed when using overlay"); + if (options & OPT_OVERLAY) { + errx(1, "All sections must be fixed when using overlay"); } pSection->nOrg = org & 0xFFFF; pSection->nBank = org >> 16; @@ -406,9 +405,8 @@ AssignSections(void) while (pSection) { if (pSection->oAssigned == 0 && pSection->nOrg != -1 && pSection->nBank == -1) { - if (options & OPT_OVERLAY && - (pSection->Type == SECT_ROMX || pSection->Type == SECT_ROM0)) { - errx(1, "All ROM sections must be fixed when using overlay"); + if (options & OPT_OVERLAY) { + errx(1, "All sections must be fixed when using overlay"); } switch (pSection->Type) { case SECT_ROMX: