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

This commit is contained in:
Anthony J. Bentley
2013-06-19 21:19:51 -06:00
parent ab47428c0e
commit da19380cc4
8 changed files with 201 additions and 17 deletions

View File

@@ -99,7 +99,8 @@ enum {
SECT_VRAM, SECT_VRAM,
SECT_CODE, SECT_CODE,
SECT_HOME, SECT_HOME,
SECT_HRAM SECT_HRAM,
SECT_WRAMX
}; };
enum { enum {

View File

@@ -6,10 +6,11 @@
enum eBankDefine { enum eBankDefine {
BANK_HOME = 0, BANK_HOME = 0,
BANK_BSS = 512, BANK_BSS = 512,
BANK_VRAM, BANK_WRAMX,
BANK_HRAM = 515 BANK_VRAM = 520,
BANK_HRAM = 522
}; };
#define MAXBANKS 516 #define MAXBANKS 523
extern SLONG area_Avail(SLONG bank); extern SLONG area_Avail(SLONG bank);
extern void AssignSections(void); extern void AssignSections(void);

View File

@@ -53,7 +53,8 @@ enum eSectionType {
SECT_VRAM, SECT_VRAM,
SECT_CODE, SECT_CODE,
SECT_HOME, SECT_HOME,
SECT_HRAM SECT_HRAM,
SECT_WRAMX
}; };
struct sSection { struct sSection {

View File

@@ -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_ADC T_Z80_ADD T_Z80_AND
%token T_Z80_BIT %token T_Z80_BIT

View File

@@ -17,14 +17,20 @@ section:
out_NewAbsSection($2,$4,-1,$8); out_NewAbsSection($2,$4,-1,$8);
else else
yyerror("ROM bank value $%x out of range (1 to $1ff)", $8); 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) { } else if ($4 == SECT_VRAM) {
if ($8 >= 0 && $8 <= 1) { if ($8 >= 0 && $8 <= 1) {
out_NewAbsSection($2, $4, -1, $8); out_NewAbsSection($2, $4, -1, $8);
} else { } else {
yyerror("VRAM bank value $%x out of range (0 to 1)", $8); yyerror("VRAM bank value $%x out of range (0 to 1)", $8);
} }
} else { } 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 ']' | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']'
@@ -37,6 +43,16 @@ section:
yyerror("ROM bank value $%x out of range (1 to $1ff)", $11); yyerror("ROM bank value $%x out of range (1 to $1ff)", $11);
} else } else
yyerror("Address $%x not 16-bit", $6); 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) { } else if ($4 == SECT_VRAM) {
if ($6 >= 0 && $6 < 0x10000) { if ($6 >= 0 && $6 < 0x10000) {
if ($11 >= 0 && $11 <= 1) { if ($11 >= 0 && $11 <= 1) {
@@ -48,7 +64,7 @@ section:
yyerror("Address $%x not 16-bit", $6); yyerror("Address $%x not 16-bit", $6);
} }
} else { } 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 @@ sectiontype:
| T_SECT_CODE { $$=SECT_CODE; } | T_SECT_CODE { $$=SECT_CODE; }
| T_SECT_HOME { $$=SECT_HOME; } | T_SECT_HOME { $$=SECT_HOME; }
| T_SECT_HRAM { $$=SECT_HRAM; } | T_SECT_HRAM { $$=SECT_HRAM; }
| T_SECT_WRAMX { $$=SECT_WRAMX; }
; ;

View File

@@ -322,6 +322,7 @@ struct sLexInitString staticstrings[] = {
{"data", T_SECT_CODE}, {"data", T_SECT_CODE},
{"home", T_SECT_HOME}, {"home", T_SECT_HOME},
{"hram", T_SECT_HRAM}, {"hram", T_SECT_HRAM},
{"wramx", T_SECT_WRAMX},
{NAME_RB, T_POP_RB}, {NAME_RB, T_POP_RB},
{NAME_RW, T_POP_RW}, {NAME_RW, T_POP_RW},

View File

@@ -15,9 +15,11 @@ struct sFreeArea {
struct sFreeArea *BankFree[MAXBANKS]; struct sFreeArea *BankFree[MAXBANKS];
SLONG MaxAvail[MAXBANKS]; SLONG MaxAvail[MAXBANKS];
SLONG MaxBankUsed; SLONG MaxBankUsed;
SLONG MaxWBankUsed;
SLONG MaxVBankUsed; SLONG MaxVBankUsed;
#define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);} #define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
#define DOMAXWBANK(x) {if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
#define DOMAXVBANK(x) {if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);} #define DOMAXVBANK(x) {if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);}
SLONG SLONG
@@ -87,6 +89,20 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
return (-1); return (-1);
} }
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 SLONG
area_AllocAbsVRAMAnyBank(SLONG org, SLONG size) area_AllocAbsVRAMAnyBank(SLONG org, SLONG size)
{ {
@@ -149,6 +165,20 @@ area_AllocVRAMAnyBank(SLONG size)
return (-1); 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 SLONG
area_AllocCODEAnyBank(SLONG size) area_AllocCODEAnyBank(SLONG size)
{ {
@@ -162,6 +192,25 @@ area_AllocCODEAnyBank(SLONG size)
return (-1); return (-1);
} }
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 * struct sSection *
FindLargestVRAM(void) FindLargestVRAM(void)
{ {
@@ -178,7 +227,7 @@ FindLargestVRAM(void)
} }
pSection = pSection->pNext; pSection = pSection->pNext;
} }
return (r); return r;
} }
struct sSection * struct sSection *
@@ -221,6 +270,27 @@ AssignVRAMSections(void)
} }
} }
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 void
AssignCodeSections(void) AssignCodeSections(void)
{ {
@@ -290,8 +360,13 @@ AssignSections(void)
} else if (i == BANK_BSS) { } else if (i == BANK_BSS) {
/* WRAM */ /* WRAM */
BankFree[i]->nOrg = 0xC000; BankFree[i]->nOrg = 0xC000;
BankFree[i]->nSize = 0x2000; BankFree[i]->nSize = 0x1000;
MaxAvail[i] = 0x2000; 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) { } else if (i == BANK_VRAM || i == BANK_VRAM + 1) {
/* Swappable VRAM bank */ /* Swappable VRAM bank */
BankFree[i]->nOrg = 0x8000; BankFree[i]->nOrg = 0x8000;
@@ -344,6 +419,59 @@ AssignSections(void)
pSection->oAssigned = 1; pSection->oAssigned = 1;
pSection->nBank = BANK_HRAM; pSection->nBank = BANK_HRAM;
break; 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: case SECT_VRAM:
if (pSection->nBank == -1) { if (pSection->nBank == -1) {
/* /*
@@ -383,7 +511,7 @@ AssignSections(void)
pSection->nByteSize) pSection->nByteSize)
!= pSection->nOrg) { != pSection->nOrg) {
fprintf(stderr, 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); exit(1);
} }
DOMAXVBANK(pSection-> DOMAXVBANK(pSection->
@@ -391,7 +519,7 @@ AssignSections(void)
pSection->oAssigned = 1; pSection->oAssigned = 1;
} else { } else {
fprintf(stderr, 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); exit(1);
} }
} }
@@ -505,11 +633,29 @@ AssignSections(void)
exit(1); exit(1);
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank); DOMAXVBANK(pSection->nBank);
} else { } 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 - BANK_VRAM);
exit(1); 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; pSection = pSection->pNext;
} }
@@ -549,6 +695,20 @@ AssignSections(void)
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank); 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; pSection = pSection->pNext;
} }
@@ -585,6 +745,8 @@ AssignSections(void)
break; break;
case SECT_VRAM: case SECT_VRAM:
break; break;
case SECT_WRAMX:
break;
case SECT_HOME: case SECT_HOME:
if ((pSection->nOrg = if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_HOME], area_Alloc(&BankFree[BANK_HOME],
@@ -608,6 +770,7 @@ AssignSections(void)
AssignCodeSections(); AssignCodeSections();
AssignVRAMSections(); AssignVRAMSections();
AssignWRAMSections();
} }
void void

View File

@@ -65,8 +65,8 @@ MapfileInitBank(SLONG bank)
fprintf(mf, "BSS:\n"); fprintf(mf, "BSS:\n");
else if (bank == BANK_HRAM) else if (bank == BANK_HRAM)
fprintf(mf, "HRAM:\n"); fprintf(mf, "HRAM:\n");
else if (bank == BANK_VRAM) else if (bank == BANK_VRAM || bank == BANK_VRAM + 1)
fprintf(mf, "VRAM:\n"); fprintf(mf, "VRAM Bank #%ld:\n", bank - BANK_VRAM);
} }
if (sf) { if (sf) {
sfbank = (bank >= 1 && bank <= 511) ? bank : 0; sfbank = (bank >= 1 && bank <= 511) ? bank : 0;