From 7ab9742299276b89a116e51d707541723a433149 Mon Sep 17 00:00:00 2001 From: "Anthony J. Bentley" Date: Wed, 31 Jul 2013 20:04:46 -0600 Subject: [PATCH] Implement SRAM sections. --- include/asm/mylink.h | 3 +- include/link/assign.h | 5 +- include/link/mylink.h | 3 +- src/asm/gameboy/yaccprt2.y | 2 +- src/asm/gameboy/yaccprt4.y | 21 ++++- src/asm/globlex.c | 1 + src/link/assign.c | 167 ++++++++++++++++++++++++++++++++++++- 7 files changed, 192 insertions(+), 10 deletions(-) diff --git a/include/asm/mylink.h b/include/asm/mylink.h index 1b6d93e0..8cdad6ef 100644 --- a/include/asm/mylink.h +++ b/include/asm/mylink.h @@ -100,7 +100,8 @@ enum { SECT_CODE, SECT_HOME, SECT_HRAM, - SECT_WRAMX + SECT_WRAMX, + SECT_SRAM }; enum { diff --git a/include/link/assign.h b/include/link/assign.h index 076801c7..4ba6882d 100644 --- a/include/link/assign.h +++ b/include/link/assign.h @@ -8,9 +8,10 @@ enum eBankDefine { 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); diff --git a/include/link/mylink.h b/include/link/mylink.h index 2999a1a4..8f44dcc7 100644 --- a/include/link/mylink.h +++ b/include/link/mylink.h @@ -54,7 +54,8 @@ enum eSectionType { SECT_CODE, SECT_HOME, SECT_HRAM, - SECT_WRAMX + SECT_WRAMX, + SECT_SRAM }; struct sSection { diff --git a/src/asm/gameboy/yaccprt2.y b/src/asm/gameboy/yaccprt2.y index 906b399d..0adede2e 100644 --- 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 diff --git a/src/asm/gameboy/yaccprt4.y b/src/asm/gameboy/yaccprt4.y index 0e28d5cb..3e0d3b86 100644 --- a/src/asm/gameboy/yaccprt4.y +++ b/src/asm/gameboy/yaccprt4.y @@ -17,6 +17,12 @@ section: 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 @@ section: 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 @@ section: 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 @@ section: 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 @@ sectiontype: | T_SECT_HOME { $$=SECT_HOME; } | T_SECT_HRAM { $$=SECT_HRAM; } | T_SECT_WRAMX { $$=SECT_WRAMX; } + | T_SECT_SRAM { $$=SECT_SRAM; } ; diff --git a/src/asm/globlex.c b/src/asm/globlex.c index 41332008..21a95dde 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -323,6 +323,7 @@ struct sLexInitString staticstrings[] = { {"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}, diff --git a/src/link/assign.c b/src/link/assign.c index 2ca05aea..00e6303d 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -16,10 +16,12 @@ struct sFreeArea *BankFree[MAXBANKS]; 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 @@ -89,6 +91,19 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size) return (-1); } +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) { @@ -165,6 +180,19 @@ area_AllocVRAMAnyBank(SLONG size) return (-1); } +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) { @@ -230,6 +258,25 @@ FindLargestVRAM(void) return r; } +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) { @@ -270,6 +317,27 @@ AssignVRAMSections(void) } } +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) { @@ -362,8 +430,13 @@ AssignSections(void) 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 @@ AssignSections(void) 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) { /* @@ -620,6 +746,24 @@ AssignSections(void) fprintf(stderr, "Unable to load fixed CODE/DATA section into bank $%02lX\n", pSection->nBank); 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) { @@ -629,13 +773,13 @@ AssignSections(void) 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 @@ -695,6 +839,20 @@ AssignSections(void) } 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) { @@ -743,6 +901,8 @@ AssignSections(void) pSection->nBank = BANK_HRAM; pSection->oAssigned = 1; break; + case SECT_SRAM: + break; case SECT_VRAM: break; case SECT_WRAMX: @@ -771,6 +931,7 @@ AssignSections(void) AssignCodeSections(); AssignVRAMSections(); AssignWRAMSections(); + AssignSRAMSections(); } void