ref: 2e9c68f8c37e8188bee63e7d164ee59ca6bc5d52
parent: 2ea2e47231bb98437dfa00908a65ca3052275f42
author: Sanqui <[email protected]>
date: Sun Mar 27 21:02:05 EDT 2016
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.
--- 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,
--- 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
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -713,6 +713,10 @@
&& 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 @@
&& 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 @@
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 @@
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!");
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -35,8 +35,8 @@
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 @@
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);
@@ -66,6 +66,10 @@
break;
case 'o':
out_Setname(optarg);
+ break;
+ case 'O':
+ out_SetOverlayname(optarg);
+ options |= OPT_OVERLAY;
break;
case 'p':
fillchar = strtoul(optarg, &ep, 0);
--- 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,8 +21,13 @@
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;
@@ -26,7 +34,7 @@
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 @@
}
void
-writebank(FILE * f, SLONG bank)
+writebank(FILE * f, FILE * f_overlay, SLONG bank)
{
struct sSection *pSect;
UBYTE *mem;
@@ -48,7 +56,12 @@
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;
@@ -55,7 +68,7 @@
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;
@@ -74,17 +87,47 @@
}
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;