Merge pull request #131 from Sanqui/overlay

Add overlay to rgblink
This commit is contained in:
AntonioND
2017-03-15 20:42:32 +00:00
committed by GitHub
6 changed files with 77 additions and 13 deletions

View File

@@ -10,6 +10,7 @@
extern SLONG options; extern SLONG options;
#define OPT_SMALL 0x01 #define OPT_SMALL 0x01
#define OPT_SMART_C_LINK 0x02 #define OPT_SMART_C_LINK 0x02
#define OPT_OVERLAY 0x04
enum eRpnData { enum eRpnData {
RPN_ADD = 0, RPN_ADD = 0,

View File

@@ -2,6 +2,7 @@
#define RGBDS_LINK_OUTPUT_H #define RGBDS_LINK_OUTPUT_H
void out_Setname(char *tzOutputfile); void out_Setname(char *tzOutputfile);
void out_SetOverlayname(char *tzOverlayfile);
void Output(void); void Output(void);
#endif #endif

View File

@@ -265,6 +265,9 @@ AssignFloatingBankSections(enum eSectionType type)
SLONG org; SLONG org;
if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) { if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) {
if (options & OPT_OVERLAY) {
errx(1, "All sections must be fixed when using overlay");
}
pSection->nOrg = org & 0xFFFF; pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16; pSection->nBank = org >> 16;
pSection->oAssigned = 1; pSection->oAssigned = 1;
@@ -421,6 +424,9 @@ AssignSections(void)
while (pSection) { while (pSection) {
if (pSection->oAssigned == 0 if (pSection->oAssigned == 0
&& pSection->nOrg != -1 && pSection->nBank == -1) { && pSection->nOrg != -1 && pSection->nBank == -1) {
if (options & OPT_OVERLAY) {
errx(1, "All sections must be fixed when using overlay");
}
switch (pSection->Type) { switch (pSection->Type) {
case SECT_ROMX: case SECT_ROMX:
case SECT_VRAM: case SECT_VRAM:

View File

@@ -35,8 +35,8 @@ static void
usage(void) usage(void)
{ {
printf( printf(
"usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile] [-p pad_value]\n" "usage: rgblink [-t] [-m mapfile] [-n symfile] [-O overlay] [-o outfile] \n"
" [-s symbol] file [...]\n"); " [-p pad_value] [-s symbol] file [...]\n");
exit(1); exit(1);
} }
@@ -56,7 +56,7 @@ main(int argc, char *argv[])
progname = argv[0]; 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) { switch (ch) {
case 'm': case 'm':
SetMapfileName(optarg); SetMapfileName(optarg);
@@ -67,6 +67,10 @@ main(int argc, char *argv[])
case 'o': case 'o':
out_Setname(optarg); out_Setname(optarg);
break; break;
case 'O':
out_SetOverlayname(optarg);
options |= OPT_OVERLAY;
break;
case 'p': case 'p':
fillchar = strtoul(optarg, &ep, 0); fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') { if (optarg[0] == '\0' || *ep != '\0') {

View File

@@ -8,9 +8,12 @@
#include "link/assign.h" #include "link/assign.h"
char *tzOutname; char *tzOutname;
char *tzOverlayname = NULL;
SLONG MaxOverlayBank;
void void
writehome(FILE * f) writehome(FILE * f, FILE * f_overlay)
{ {
struct sSection *pSect; struct sSection *pSect;
UBYTE *mem; UBYTE *mem;
@@ -19,7 +22,12 @@ writehome(FILE * f)
if (!mem) if (!mem)
return; return;
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]); memset(mem, fillchar, MaxAvail[BANK_ROM0]);
}
MapfileInitBank(0); MapfileInitBank(0);
pSect = pSections; pSect = pSections;
@@ -39,7 +47,7 @@ writehome(FILE * f)
} }
void void
writebank(FILE * f, SLONG bank) writebank(FILE * f, FILE * f_overlay, SLONG bank)
{ {
struct sSection *pSect; struct sSection *pSect;
UBYTE *mem; UBYTE *mem;
@@ -48,7 +56,12 @@ writebank(FILE * f, SLONG bank)
if (!mem) if (!mem)
return; return;
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]); memset(mem, fillchar, MaxAvail[bank]);
}
MapfileInitBank(bank); MapfileInitBank(bank);
pSect = pSections; pSect = pSections;
@@ -73,18 +86,52 @@ out_Setname(char *tzOutputfile)
tzOutname = tzOutputfile; tzOutname = tzOutputfile;
} }
void
out_SetOverlayname(char *tzOverlayfile)
{
tzOverlayname = tzOverlayfile;
}
void void
Output(void) Output(void)
{ {
SLONG i; SLONG i;
FILE *f; FILE *f;
FILE *f_overlay = NULL;
if ((f = fopen(tzOutname, "wb"))) { if ((f = fopen(tzOutname, "wb"))) {
writehome(f); 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\n");
exit(1);
}
MaxOverlayBank = (ftell(f_overlay) / 0x4000) - 1;
if (MaxOverlayBank < 1) {
fprintf(stderr, "Overlay file be at least 0x8000 bytes\n");
exit(1);
}
if (MaxOverlayBank > MaxBankUsed) {
MaxBankUsed = MaxOverlayBank;
}
}
writehome(f, f_overlay);
for (i = 1; i <= MaxBankUsed; i += 1) for (i = 1; i <= MaxBankUsed; i += 1)
writebank(f, i); writebank(f, f_overlay, i);
fclose(f); fclose(f);
if (tzOverlayname) {
fclose(f_overlay);
}
} }
for (i = BANK_WRAM0; i < MAXBANKS; i++) { for (i = BANK_WRAM0; i < MAXBANKS; i++) {
struct sSection *pSect; struct sSection *pSect;

View File

@@ -9,6 +9,7 @@
.Op Fl t .Op Fl t
.Op Fl m Ar mapfile .Op Fl m Ar mapfile
.Op Fl n Ar symfile .Op Fl n Ar symfile
.Op Fl O Ar overlayfile
.Op Fl o Ar outfile .Op Fl o Ar outfile
.Op Fl p Ar pad_value .Op Fl p Ar pad_value
.Op Fl s Ar symbol .Op Fl s Ar symbol
@@ -32,6 +33,10 @@ The arguments are as follows:
Write a mapfile to the given filename. Write a mapfile to the given filename.
.It Fl n Ar symfile .It Fl n Ar symfile
Write a symbol file to the given filename. 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 .It Fl o Ar outfile
Write ROM image to the given filename. Write ROM image to the given filename.
.It Fl p Ar pad_value .It Fl p Ar pad_value