shithub: rgbds

Download patch

ref: 9193710ff90fc2183a9079bea917b4be6b5edfc3
parent: 947d767c6487bbb131fa038ecc287ceb4c620fc5
parent: 263c9222ab17a6b499b797b64d0654b0ce29d172
author: AntonioND <[email protected]>
date: Wed Mar 15 16:42:32 EDT 2017

Merge pull request #131 from Sanqui/overlay

Add overlay to rgblink

--- 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
@@ -258,7 +258,7 @@
 AssignFloatingBankSections(enum eSectionType type)
 {
 	ensureSectionTypeIsValid(type);
-
+	
 	struct sSection *pSection;
 
 	while ((pSection = FindLargestSection(type, false))) {
@@ -265,6 +265,9 @@
 		SLONG org;
 
 		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->nBank = org >> 16;
 			pSection->oAssigned = 1;
@@ -421,6 +424,9 @@
 	while (pSection) {
 		if (pSection->oAssigned == 0
 			&& pSection->nOrg != -1 && pSection->nBank == -1) {
+			if (options & OPT_OVERLAY) {
+				errx(1, "All sections must be fixed when using overlay");
+			}
 			switch (pSection->Type) {
 			case SECT_ROMX:
 			case SECT_VRAM:
--- 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,51 @@
 }
 
 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");
+			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)
-			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;
--- 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 @@
 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