shithub: rgbds

Download patch

ref: da19380cc41a61537801944205e1a178cb52459d
parent: ab47428c0e3e9fc68621a20f42bb6e7372fa3358
author: Anthony J. Bentley <[email protected]>
date: Wed Jun 19 17:19:51 EDT 2013

Add a new WRAMX section type, for banked (CGB) WRAM sections.

--- a/include/asm/mylink.h
+++ b/include/asm/mylink.h
@@ -99,7 +99,8 @@
 	SECT_VRAM,
 	SECT_CODE,
 	SECT_HOME,
-	SECT_HRAM
+	SECT_HRAM,
+	SECT_WRAMX
 };
 
 enum {
--- a/include/link/assign.h
+++ b/include/link/assign.h
@@ -6,10 +6,11 @@
 enum eBankDefine {
 	BANK_HOME = 0,
 	BANK_BSS = 512,
-	BANK_VRAM,
-	BANK_HRAM = 515
+	BANK_WRAMX,
+	BANK_VRAM = 520,
+	BANK_HRAM = 522
 };
-#define MAXBANKS	516
+#define MAXBANKS	523
 
 extern SLONG area_Avail(SLONG bank);
 extern void AssignSections(void);
--- a/include/link/mylink.h
+++ b/include/link/mylink.h
@@ -53,7 +53,8 @@
 	SECT_VRAM,
 	SECT_CODE,
 	SECT_HOME,
-	SECT_HRAM
+	SECT_HRAM,
+	SECT_WRAMX
 };
 
 struct sSection {
--- a/src/asm/gameboy/yaccprt2.y
+++ b/src/asm/gameboy/yaccprt2.y
@@ -1,4 +1,4 @@
-%token	T_SECT_BSS T_SECT_VRAM T_SECT_CODE T_SECT_HOME T_SECT_HRAM
+%token	T_SECT_BSS T_SECT_VRAM T_SECT_CODE T_SECT_HOME T_SECT_HRAM T_SECT_WRAMX
 
 %token	T_Z80_ADC T_Z80_ADD T_Z80_AND
 %token	T_Z80_BIT
--- a/src/asm/gameboy/yaccprt4.y
+++ b/src/asm/gameboy/yaccprt4.y
@@ -17,14 +17,20 @@
 					out_NewAbsSection($2,$4,-1,$8);
 				else
 					yyerror("ROM bank value $%x out of range (1 to $1ff)", $8);
+			} else if ($4 == SECT_WRAMX) {
+				if ($8 >= 1 && $8 <= 7) {
+					out_NewAbsSection($2, $4, -1, $8);
+				} else {
+					yyerror("WRAMX bank value $%x out of range (1 to 7)", $8);
+				}
 			} else if ($4 == SECT_VRAM) {
-				if ($8 >= 0 && $8 <= 1)  {
+				if ($8 >= 0 && $8 <= 1) {
 					out_NewAbsSection($2, $4, -1, $8);
 				} else {
 					yyerror("VRAM bank value $%x out of range (0 to 1)", $8);
 				}
 			} else {
-				yyerror("BANK only allowed for CODE/DATA or VRAM sections");
+				yyerror("BANK only allowed for CODE/DATA, WRAMX, or VRAM sections");
 			}
 		}
 	|	T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']'
@@ -37,6 +43,16 @@
 						yyerror("ROM bank value $%x out of range (1 to $1ff)", $11);
 				} else
 					yyerror("Address $%x not 16-bit", $6);
+			} else if ($4 == SECT_WRAMX) {
+				if ($6 >= 0 && $6 < 0x10000) {
+					if ($11 >= 1 && $11 <= 7) {
+						out_NewAbsSection($2, $4, $6, $11);
+					} else {
+						yyerror("WRAMX bank value $%x out of range (1 to 7)", $11);
+					}
+				} else {
+					yyerror("Address $%x not 16-bit", $6);
+				}
 			} else if ($4 == SECT_VRAM) {
 				if ($6 >= 0 && $6 < 0x10000) {
 					if ($11 >= 0 && $11 <= 1) {
@@ -48,7 +64,7 @@
 					yyerror("Address $%x not 16-bit", $6);
 				}
 			} else {
-				yyerror("BANK only allowed for CODE/DATA or VRAM sections");
+				yyerror("BANK only allowed for CODE/DATA, WRAMX, or VRAM sections");
 			}
 		}
 ;
@@ -59,6 +75,7 @@
 	|	T_SECT_CODE	{ $$=SECT_CODE; }
 	|	T_SECT_HOME	{ $$=SECT_HOME; }
 	|	T_SECT_HRAM	{ $$=SECT_HRAM; }
+	|	T_SECT_WRAMX	{ $$=SECT_WRAMX; }
 ;
 
 
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -322,6 +322,7 @@
 	{"data", T_SECT_CODE},
 	{"home", T_SECT_HOME},
 	{"hram", T_SECT_HRAM},
+	{"wramx", T_SECT_WRAMX},
 
 	{NAME_RB, T_POP_RB},
 	{NAME_RW, T_POP_RW},
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -15,9 +15,11 @@
 struct sFreeArea *BankFree[MAXBANKS];
 SLONG MaxAvail[MAXBANKS];
 SLONG MaxBankUsed;
+SLONG MaxWBankUsed;
 SLONG MaxVBankUsed;
 
 #define DOMAXBANK(x)	{if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
+#define DOMAXWBANK(x)	{if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
 #define DOMAXVBANK(x)	{if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);}
 
 SLONG 
@@ -88,6 +90,20 @@
 }
 
 SLONG
+area_AllocAbsWRAMAnyBank(SLONG org, SLONG size)
+{
+	SLONG i;
+
+	for (i = 1; i <= 7; i += 1) {
+		if (area_AllocAbs(&BankFree[BANK_WRAMX + i - 1], org, size) == org) {
+			return BANK_WRAMX + i - 1;
+		}
+	}
+
+	return -1;
+}
+
+SLONG
 area_AllocAbsVRAMAnyBank(SLONG org, SLONG size)
 {
 	if (area_AllocAbs(&BankFree[BANK_VRAM], org, size) == org) {
@@ -149,6 +165,20 @@
 	return (-1);
 }
 
+SLONG
+area_AllocWRAMAnyBank(SLONG size)
+{
+	SLONG i, org;
+
+	for (i = 1; i <= 7; i += 1) {
+		if ((org = area_Alloc(&BankFree[BANK_WRAMX + i - 1], size)) != -1) {
+			return (i << 16) | org;
+		}
+	}
+
+	return -1;
+}
+
 SLONG 
 area_AllocCODEAnyBank(SLONG size)
 {
@@ -163,6 +193,25 @@
 }
 
 struct sSection *
+FindLargestWRAM(void)
+{
+	struct sSection *pSection, *r = NULL;
+	SLONG nLargest = 0;
+
+	pSection = pSections;
+	while (pSection) {
+		if (pSection->oAssigned == 0 && pSection->Type == SECT_WRAMX) {
+			if (pSection->nByteSize > nLargest) {
+				nLargest = pSection->nByteSize;
+				r = pSection;
+			}
+		}
+		pSection = pSection->pNext;
+	}
+	return r;
+}
+
+struct sSection *
 FindLargestVRAM(void)
 {
 	struct sSection *pSection, *r = NULL;
@@ -178,7 +227,7 @@
 		}
 		pSection = pSection->pNext;
 	}
-	return (r);
+	return r;
 }
 
 struct sSection *
@@ -221,6 +270,27 @@
 	}
 }
 
+void
+AssignWRAMSections(void)
+{
+	struct sSection *pSection;
+
+	while ((pSection = FindLargestWRAM())) {
+		SLONG org;
+
+		if ((org = area_AllocWRAMAnyBank(pSection->nByteSize)) != -1) {
+			pSection->nOrg = org & 0xFFFF;
+			pSection->nBank = org >> 16;
+			pSection->oAssigned = 1;
+			DOMAXWBANK(pSection->nBank);
+		} else {
+			fprintf(stderr,
+			    "Unable to place WRAMX section anywhere\n");
+			exit(1);
+		}
+	}
+}
+
 void 
 AssignCodeSections(void)
 {
@@ -290,8 +360,13 @@
 		} else if (i == BANK_BSS) {
 			/* WRAM */
 			BankFree[i]->nOrg = 0xC000;
-			BankFree[i]->nSize = 0x2000;
-			MaxAvail[i] = 0x2000;
+			BankFree[i]->nSize = 0x1000;
+			MaxAvail[i] = 0x1000;
+		} else if (i >= BANK_WRAMX && i <= BANK_WRAMX + 6) {
+			/* Swappable VRAM bank */
+			BankFree[i]->nOrg = 0xD000;
+			BankFree[i]->nSize = 0x1000;
+			MaxAvail[i] = 0x1000;
 		} else if (i == BANK_VRAM || i == BANK_VRAM + 1) {
 			/* Swappable VRAM bank */
 			BankFree[i]->nOrg = 0x8000;
@@ -344,6 +419,59 @@
 				pSection->oAssigned = 1;
 				pSection->nBank = BANK_HRAM;
 				break;
+			case SECT_WRAMX:
+				if (pSection->nBank == -1) {
+					/*
+					 * User doesn't care which bank.
+					 * Therefore he must here be specifying
+					 * position within the bank.
+					 * Defer until later.
+					 */
+					;
+				} else {
+					/*
+					 * User specified which bank to use.
+					 * Does he also care about position
+					 * within the bank?
+					 */
+					if (pSection->nOrg == -1) {
+						/*
+						 * Nope, any position will do
+						 * Again, we'll do that later
+						 *
+						 */
+						;
+					} else {
+						/*
+						 * Bank and position within the
+						 * bank are hardcoded.
+						 */
+
+						if (pSection->nBank >= 1
+						    && pSection->nBank <= 7) {
+							pSection->nBank +=
+							    BANK_WRAMX;
+							if (area_AllocAbs
+							    (&BankFree
+							    [pSection->nBank],
+							    pSection->nOrg,
+							    pSection->nByteSize)
+							    != pSection->nOrg) {
+								fprintf(stderr,
+"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
+								exit(1);
+							}
+							DOMAXWBANK(pSection->
+							    nBank);
+							pSection->oAssigned = 1;
+						} else {
+							fprintf(stderr,
+"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
+							exit(1);
+						}
+					}
+				}
+				break;
 			case SECT_VRAM:
 				if (pSection->nBank == -1) {
 					/*
@@ -383,7 +511,7 @@
 							    pSection->nByteSize)
 							    != pSection->nOrg) {
 								fprintf(stderr,
-"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank - BANK_VRAM);
+"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
 								exit(1);
 							}
 							DOMAXVBANK(pSection->
@@ -391,7 +519,7 @@
 							pSection->oAssigned = 1;
 						} else {
 							fprintf(stderr,
-"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank - BANK_VRAM);
+"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
 							exit(1);
 						}
 					}
@@ -505,11 +633,29 @@
 					exit(1);
 				}
 				pSection->oAssigned = 1;
-				DOMAXBANK(pSection->nBank);
+				DOMAXVBANK(pSection->nBank);
 			} else {
 				fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank - BANK_VRAM);
 				exit(1);
 			}
+		} else if (pSection->oAssigned == 0
+		    && pSection->Type == SECT_WRAMX
+		    && pSection->nOrg == -1 && pSection->nBank != -1) {
+			pSection->nBank += BANK_WRAMX;
+			/* User wants to have a say... and he's pissed */
+			if (pSection->nBank >= BANK_WRAMX && pSection->nBank <= BANK_WRAMX + 6) {
+				if ((pSection->nOrg =
+					area_Alloc(&BankFree[pSection->nBank],
+					    pSection->nByteSize)) == -1) {
+					fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
+					exit(1);
+				}
+				pSection->oAssigned = 1;
+				DOMAXWBANK(pSection->nBank);
+			} else {
+				fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
+				exit(1);
+			}
 		}
 		pSection = pSection->pNext;
 	}
@@ -549,6 +695,20 @@
 			}
 			pSection->oAssigned = 1;
 			DOMAXVBANK(pSection->nBank);
+		} else if (pSection->oAssigned == 0
+		    && pSection->Type == SECT_WRAMX
+		    && pSection->nOrg != -1 && pSection->nBank == -1) {
+			/* User wants to have a say... and he's back with a
+			 * vengeance */
+			if ((pSection->nBank =
+				area_AllocAbsWRAMAnyBank(pSection->nOrg,
+				    pSection->nByteSize)) ==
+			    -1) {
+				fprintf(stderr, "Unable to load fixed WRAMX section at $%lX into any bank\n", pSection->nOrg);
+				exit(1);
+			}
+			pSection->oAssigned = 1;
+			DOMAXWBANK(pSection->nBank);
 		}
 		pSection = pSection->pNext;
 	}
@@ -585,6 +745,8 @@
 				break;
 			case SECT_VRAM:
 				break;
+			case SECT_WRAMX:
+				break;
 			case SECT_HOME:
 				if ((pSection->nOrg =
 					area_Alloc(&BankFree[BANK_HOME],
@@ -608,6 +770,7 @@
 
 	AssignCodeSections();
 	AssignVRAMSections();
+	AssignWRAMSections();
 }
 
 void 
--- a/src/link/mapfile.c
+++ b/src/link/mapfile.c
@@ -65,8 +65,8 @@
 			fprintf(mf, "BSS:\n");
 		else if (bank == BANK_HRAM)
 			fprintf(mf, "HRAM:\n");
-		else if (bank == BANK_VRAM)
-			fprintf(mf, "VRAM:\n");
+		else if (bank == BANK_VRAM || bank == BANK_VRAM + 1)
+			fprintf(mf, "VRAM Bank #%ld:\n", bank - BANK_VRAM);
 	}
 	if (sf) {
 		sfbank = (bank >= 1 && bank <= 511) ? bank : 0;