ref: da19380cc41a61537801944205e1a178cb52459d
parent: ab47428c0e3e9fc68621a20f42bb6e7372fa3358
author: Anthony J. Bentley <anthony@cathet.us>
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;
--
⑨