mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
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.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define RGBDS_LINK_OUTPUT_H
|
||||
|
||||
void out_Setname(char *tzOutputfile);
|
||||
void out_SetOverlayname(char *tzOverlayfile);
|
||||
void Output(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user