shithub: rgbds

Download patch

ref: 7ab9742299276b89a116e51d707541723a433149
parent: 6aecf65552b1fc38910793d9829bca8e1781457a
author: Anthony J. Bentley <[email protected]>
date: Wed Jul 31 16:04:46 EDT 2013

Implement SRAM sections.

--- a/include/asm/mylink.h
+++ b/include/asm/mylink.h
@@ -100,7 +100,8 @@
 	SECT_CODE,
 	SECT_HOME,
 	SECT_HRAM,
-	SECT_WRAMX
+	SECT_WRAMX,
+	SECT_SRAM
 };
 
 enum {
--- a/include/link/assign.h
+++ b/include/link/assign.h
@@ -8,9 +8,10 @@
 	BANK_BSS = 512,
 	BANK_WRAMX,
 	BANK_VRAM = 520,
-	BANK_HRAM = 522
+	BANK_HRAM = 522,
+	BANK_SRAM = 523
 };
-#define MAXBANKS	523
+#define MAXBANKS	527
 
 extern SLONG area_Avail(SLONG bank);
 extern void AssignSections(void);
--- a/include/link/mylink.h
+++ b/include/link/mylink.h
@@ -54,7 +54,8 @@
 	SECT_CODE,
 	SECT_HOME,
 	SECT_HRAM,
-	SECT_WRAMX
+	SECT_WRAMX,
+	SECT_SRAM
 };
 
 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 T_SECT_WRAMX
+%token	T_SECT_BSS T_SECT_VRAM T_SECT_CODE T_SECT_HOME T_SECT_HRAM T_SECT_WRAMX T_SECT_SRAM
 
 %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,6 +17,12 @@
 					out_NewAbsSection($2,$4,-1,$8);
 				else
 					yyerror("ROM bank value $%x out of range (1 to $1ff)", $8);
+			} else if ($4 == SECT_SRAM) {
+				if ($8 >= 0 && $8 <= 3) {
+					out_NewAbsSection($2, $4, -1, $8);
+				} else {
+					yyerror("SRAM bank value $%x out of range (0 to 3)", $8);
+				}
 			} else if ($4 == SECT_WRAMX) {
 				if ($8 >= 1 && $8 <= 7) {
 					out_NewAbsSection($2, $4, -1, $8);
@@ -30,7 +36,7 @@
 					yyerror("VRAM bank value $%x out of range (0 to 1)", $8);
 				}
 			} else {
-				yyerror("BANK only allowed for CODE/DATA, WRAMX, or VRAM sections");
+				yyerror("BANK only allowed for CODE/DATA, WRAMX, SRAM, or VRAM sections");
 			}
 		}
 	|	T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']'
@@ -43,6 +49,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_SRAM) {
+				if ($6 >= 0 && $6 < 0x10000) {
+					if ($11 >= 0 && $11 <= 3) {
+						out_NewAbsSection($2, $4, $6, $11);
+					} else {
+						yyerror("SRAM bank value $%x out of range (0 to 3)", $11);
+					}
+				} else {
+					yyerror("Address $%x not 16-bit", $6);
+				}
 			} else if ($4 == SECT_WRAMX) {
 				if ($6 >= 0 && $6 < 0x10000) {
 					if ($11 >= 1 && $11 <= 7) {
@@ -64,7 +80,7 @@
 					yyerror("Address $%x not 16-bit", $6);
 				}
 			} else {
-				yyerror("BANK only allowed for CODE/DATA, WRAMX, or VRAM sections");
+				yyerror("BANK only allowed for CODE/DATA, WRAMX, SRAM, or VRAM sections");
 			}
 		}
 ;
@@ -76,6 +92,7 @@
 	|	T_SECT_HOME	{ $$=SECT_HOME; }
 	|	T_SECT_HRAM	{ $$=SECT_HRAM; }
 	|	T_SECT_WRAMX	{ $$=SECT_WRAMX; }
+	|	T_SECT_SRAM	{ $$=SECT_SRAM; }
 ;
 
 
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -323,6 +323,7 @@
 	{"home", T_SECT_HOME},
 	{"hram", T_SECT_HRAM},
 	{"wramx", T_SECT_WRAMX},
+	{"sram", T_SECT_SRAM},
 
 	{NAME_RB, T_POP_RB},
 	{NAME_RW, T_POP_RW},
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -16,10 +16,12 @@
 SLONG MaxAvail[MAXBANKS];
 SLONG MaxBankUsed;
 SLONG MaxWBankUsed;
+SLONG MaxSBankUsed;
 SLONG MaxVBankUsed;
 
 #define DOMAXBANK(x)	{if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
 #define DOMAXWBANK(x)	{if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
+#define DOMAXSBANK(x)	{if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);}
 #define DOMAXVBANK(x)	{if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);}
 
 SLONG 
@@ -90,6 +92,19 @@
 }
 
 SLONG
+area_AllocAbsSRAMAnyBank(SLONG org, SLONG size)
+{
+	int i;
+	for (i = 0; i < 4; ++i) {
+		if (area_AllocAbs(&BankFree[BANK_SRAM + i], org, size) == org) {
+			return BANK_SRAM + i;
+		}
+	}
+
+	return -1;
+}
+
+SLONG
 area_AllocAbsWRAMAnyBank(SLONG org, SLONG size)
 {
 	SLONG i;
@@ -166,6 +181,19 @@
 }
 
 SLONG
+area_AllocSRAMAnyBank(SLONG size)
+{
+	SLONG i, org;
+	for (i = 0; i < 4; ++i) {
+		if ((org = area_Alloc(&BankFree[BANK_SRAM + i], size)) != -1) {
+			return (i << 16) | org;
+		}
+	}
+
+	return -1;
+}
+
+SLONG
 area_AllocWRAMAnyBank(SLONG size)
 {
 	SLONG i, org;
@@ -231,6 +259,25 @@
 }
 
 struct sSection *
+FindLargestSRAM(void)
+{
+	struct sSection *pSection, *r = NULL;
+	SLONG nLargest = 0;
+
+	pSection = pSections;
+	while (pSection) {
+		if (pSection->oAssigned == 0 && pSection->Type == SECT_SRAM) {
+			if (pSection->nByteSize > nLargest) {
+				nLargest = pSection->nByteSize;
+				r = pSection;
+			}
+		}
+		pSection = pSection->pNext;
+	}
+	return r;
+}
+
+struct sSection *
 FindLargestCode(void)
 {
 	struct sSection *pSection, *r = NULL;
@@ -271,6 +318,27 @@
 }
 
 void
+AssignSRAMSections(void)
+{
+	struct sSection *pSection;
+
+	while ((pSection = FindLargestSRAM())) {
+		SLONG org;
+
+		if ((org = area_AllocSRAMAnyBank(pSection->nByteSize)) != -1) {
+			pSection->nOrg = org & 0xFFFF;
+			pSection->nBank = org >> 16;
+			pSection->oAssigned = 1;
+			DOMAXSBANK(pSection->nBank);
+		} else {
+			fprintf(stderr,
+			    "Unable to place SRAM section anywhere\n");
+			exit(1);
+		}
+	}
+}
+
+void
 AssignWRAMSections(void)
 {
 	struct sSection *pSection;
@@ -362,8 +430,13 @@
 			BankFree[i]->nOrg = 0xC000;
 			BankFree[i]->nSize = 0x1000;
 			MaxAvail[i] = 0x1000;
+		} else if (i >= BANK_SRAM && i <= BANK_SRAM + 3) {
+			/* Swappable SRAM bank */
+			BankFree[i]->nOrg = 0xA000;
+			BankFree[i]->nSize = 0x2000;
+			MaxAvail[i] = 0x2000;
 		} else if (i >= BANK_WRAMX && i <= BANK_WRAMX + 6) {
-			/* Swappable VRAM bank */
+			/* Swappable WRAM bank */
 			BankFree[i]->nOrg = 0xD000;
 			BankFree[i]->nSize = 0x1000;
 			MaxAvail[i] = 0x1000;
@@ -419,6 +492,59 @@
 				pSection->oAssigned = 1;
 				pSection->nBank = BANK_HRAM;
 				break;
+			case SECT_SRAM:
+				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 >= 0
+						    && pSection->nBank <= 3) {
+							pSection->nBank +=
+							    BANK_SRAM;
+							if (area_AllocAbs
+							    (&BankFree
+							    [pSection->nBank],
+							    pSection->nOrg,
+							    pSection->nByteSize)
+							    != pSection->nOrg) {
+								fprintf(stderr,
+"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
+								exit(1);
+							}
+							DOMAXVBANK(pSection->
+							    nBank);
+							pSection->oAssigned = 1;
+						} else {
+							fprintf(stderr,
+"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
+							exit(1);
+						}
+					}
+				}
+				break;
 			case SECT_WRAMX:
 				if (pSection->nBank == -1) {
 					/*
@@ -621,6 +747,24 @@
 				exit(1);
 			}
 		} else if (pSection->oAssigned == 0
+		    && pSection->Type == SECT_SRAM
+		    && pSection->nOrg == -1 && pSection->nBank != -1) {
+			pSection->nBank += BANK_SRAM;
+			/* User wants to have a say... and he's pissed */
+			if (pSection->nBank >= BANK_SRAM && pSection->nBank <= BANK_SRAM + 3) {
+				if ((pSection->nOrg =
+					area_Alloc(&BankFree[pSection->nBank],
+					    pSection->nByteSize)) == -1) {
+					fprintf(stderr, "Unable to load fixed SRAM section into bank $%02lX\n", pSection->nBank);
+					exit(1);
+				}
+				pSection->oAssigned = 1;
+				DOMAXSBANK(pSection->nBank);
+			} else {
+				fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
+				exit(1);
+			}
+		} else if (pSection->oAssigned == 0
 		    && pSection->Type == SECT_VRAM
 		    && pSection->nOrg == -1 && pSection->nBank != -1) {
 			pSection->nBank += BANK_VRAM;
@@ -629,13 +773,13 @@
 				if ((pSection->nOrg =
 					area_Alloc(&BankFree[pSection->nBank],
 					    pSection->nByteSize)) == -1) {
-					fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank - BANK_VRAM);
+					fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
 					exit(1);
 				}
 				pSection->oAssigned = 1;
 				DOMAXVBANK(pSection->nBank);
 			} else {
-				fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank - BANK_VRAM);
+				fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
 				exit(1);
 			}
 		} else if (pSection->oAssigned == 0
@@ -696,6 +840,20 @@
 			pSection->oAssigned = 1;
 			DOMAXVBANK(pSection->nBank);
 		} else if (pSection->oAssigned == 0
+		    && pSection->Type == SECT_SRAM
+		    && pSection->nOrg != -1 && pSection->nBank == -1) {
+			/* User wants to have a say... and he's back with a
+			 * vengeance */
+			if ((pSection->nBank =
+				area_AllocAbsSRAMAnyBank(pSection->nOrg,
+				    pSection->nByteSize)) ==
+			    -1) {
+				fprintf(stderr, "Unable to load fixed SRAM section at $%lX into any bank\n", pSection->nOrg);
+				exit(1);
+			}
+			pSection->oAssigned = 1;
+			DOMAXSBANK(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
@@ -743,6 +901,8 @@
 				pSection->nBank = BANK_HRAM;
 				pSection->oAssigned = 1;
 				break;
+			case SECT_SRAM:
+				break;
 			case SECT_VRAM:
 				break;
 			case SECT_WRAMX:
@@ -771,6 +931,7 @@
 	AssignCodeSections();
 	AssignVRAMSections();
 	AssignWRAMSections();
+	AssignSRAMSections();
 }
 
 void