mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Merge branch 'master' of github.com:rednex/rgbds into overlay
This commit is contained in:
@@ -46,7 +46,7 @@ const struct sSectionAttributes SECT_ATTRIBUTES[] = {
|
||||
case SECT_WRAMX: DOMAXWBANK(y); break; \
|
||||
case SECT_SRAM: DOMAXSBANK(y); break; \
|
||||
case SECT_VRAM: DOMAXVBANK(y); break; \
|
||||
default: errx(1, "DOMAXBANK used with invalid parameters"); break; }}
|
||||
default: break; }}
|
||||
#define DOMAXRBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
|
||||
#define DOMAXWBANK(x) {if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
|
||||
#define DOMAXSBANK(x) {if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);}
|
||||
@@ -77,6 +77,40 @@ area_Avail(SLONG bank)
|
||||
return (r);
|
||||
}
|
||||
|
||||
SLONG
|
||||
area_doAlloc(struct sFreeArea *pArea, SLONG org, SLONG size)
|
||||
{
|
||||
if (org >= pArea->nOrg && (org + size) <= (pArea->nOrg + pArea->nSize)) {
|
||||
if (org == pArea->nOrg) {
|
||||
pArea->nOrg += size;
|
||||
pArea->nSize -= size;
|
||||
return org;
|
||||
} else {
|
||||
if ((org + size) == (pArea->nOrg + pArea->nSize)) {
|
||||
pArea->nSize -= size;
|
||||
return org;
|
||||
} else {
|
||||
struct sFreeArea *pNewArea;
|
||||
|
||||
if ((pNewArea = malloc(sizeof(struct sFreeArea))) != NULL) {
|
||||
*pNewArea = *pArea;
|
||||
pNewArea->pPrev = pArea;
|
||||
pArea->pNext = pNewArea;
|
||||
pArea->nSize = org - pArea->nOrg;
|
||||
pNewArea->nOrg = org + size;
|
||||
pNewArea->nSize -= size + pArea->nSize;
|
||||
return org;
|
||||
|
||||
} else {
|
||||
err(1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
SLONG
|
||||
area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
|
||||
{
|
||||
@@ -84,39 +118,11 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
|
||||
|
||||
pArea = *ppArea;
|
||||
while (pArea) {
|
||||
if (org >= pArea->nOrg
|
||||
&& (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
|
||||
if (org == pArea->nOrg) {
|
||||
pArea->nOrg += size;
|
||||
pArea->nSize -= size;
|
||||
return 0;
|
||||
} else {
|
||||
if ((org + size - 1) ==
|
||||
(pArea->nOrg + pArea->nSize - 1)) {
|
||||
pArea->nSize -= size;
|
||||
return 0;
|
||||
} else {
|
||||
struct sFreeArea *pNewArea;
|
||||
|
||||
if ((pNewArea =
|
||||
malloc(sizeof(struct sFreeArea)))
|
||||
!= NULL) {
|
||||
*pNewArea = *pArea;
|
||||
pNewArea->pPrev = pArea;
|
||||
pArea->pNext = pNewArea;
|
||||
pArea->nSize =
|
||||
org - pArea->nOrg;
|
||||
pNewArea->nOrg = org + size;
|
||||
pNewArea->nSize -=
|
||||
size + pArea->nSize;
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
err(1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
SLONG result = area_doAlloc(pArea, org, size);
|
||||
if (result != -1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ppArea = &(pArea->pNext);
|
||||
pArea = *ppArea;
|
||||
}
|
||||
@@ -141,38 +147,42 @@ area_AllocAbsAnyBank(SLONG org, SLONG size, enum eSectionType type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
SLONG
|
||||
area_Alloc(struct sFreeArea ** ppArea, SLONG size)
|
||||
{
|
||||
SLONG
|
||||
area_Alloc(struct sFreeArea ** ppArea, SLONG size, SLONG alignment) {
|
||||
struct sFreeArea *pArea;
|
||||
|
||||
if (alignment < 1) {
|
||||
alignment = 1;
|
||||
}
|
||||
|
||||
pArea = *ppArea;
|
||||
while (pArea) {
|
||||
if (size <= pArea->nSize) {
|
||||
SLONG r;
|
||||
|
||||
r = pArea->nOrg;
|
||||
pArea->nOrg += size;
|
||||
pArea->nSize -= size;
|
||||
|
||||
return (r);
|
||||
SLONG org = pArea->nOrg;
|
||||
if (org % alignment) {
|
||||
org += alignment;
|
||||
}
|
||||
org -= org % alignment;
|
||||
|
||||
SLONG result = area_doAlloc(pArea, org, size);
|
||||
if (result != -1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ppArea = &(pArea->pNext);
|
||||
pArea = *ppArea;
|
||||
}
|
||||
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SLONG
|
||||
area_AllocAnyBank(SLONG size, enum eSectionType type) {
|
||||
area_AllocAnyBank(SLONG size, SLONG alignment, enum eSectionType type) {
|
||||
ensureSectionTypeIsValid(type);
|
||||
|
||||
SLONG startBank = SECT_ATTRIBUTES[type].bank;
|
||||
SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
|
||||
|
||||
for (int i = 0; i < bankCount; i++) {
|
||||
SLONG org = area_Alloc(&BankFree[startBank + i], size);
|
||||
SLONG org = area_Alloc(&BankFree[startBank + i], size, alignment);
|
||||
if (org != -1) {
|
||||
return ((startBank + i) << 16) | org;
|
||||
}
|
||||
@@ -182,45 +192,27 @@ area_AllocAnyBank(SLONG size, enum eSectionType type) {
|
||||
}
|
||||
|
||||
struct sSection *
|
||||
FindLargestSection(enum eSectionType type)
|
||||
FindLargestSection(enum eSectionType type, bool bankFixed)
|
||||
{
|
||||
struct sSection *pSection, *r = NULL;
|
||||
SLONG nLargest = 0;
|
||||
SLONG nLargestAlignment = 0;
|
||||
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0 && pSection->Type == type) {
|
||||
if (pSection->nByteSize > nLargest) {
|
||||
if (pSection->oAssigned == 0 && pSection->Type == type && (bankFixed ^ (pSection->nBank == -1))) {
|
||||
if (pSection->nAlign > nLargestAlignment || (pSection->nAlign == nLargestAlignment && pSection->nByteSize > nLargest)) {
|
||||
nLargest = pSection->nByteSize;
|
||||
nLargestAlignment = pSection->nAlign;
|
||||
r = pSection;
|
||||
}
|
||||
}
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
AssignBankedSections(enum eSectionType type)
|
||||
{
|
||||
ensureSectionTypeIsValid(type);
|
||||
|
||||
struct sSection *pSection;
|
||||
|
||||
while ((pSection = FindLargestSection(type))) {
|
||||
SLONG org;
|
||||
|
||||
if ((org = area_AllocAnyBank(pSection->nByteSize, type)) != -1) {
|
||||
pSection->nOrg = org & 0xFFFF;
|
||||
pSection->nBank = org >> 16;
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->Type, pSection->nBank);
|
||||
} else {
|
||||
errx(1, "Unable to place %s section anywhere",
|
||||
SECT_ATTRIBUTES[type].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
VerifyAndSetBank(struct sSection *pSection)
|
||||
@@ -237,6 +229,50 @@ VerifyAndSetBank(struct sSection *pSection)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AssignFixedBankSections(enum eSectionType type)
|
||||
{
|
||||
ensureSectionTypeIsValid(type);
|
||||
|
||||
struct sSection *pSection;
|
||||
|
||||
while ((pSection = FindLargestSection(type, true))) {
|
||||
if (VerifyAndSetBank(pSection) &&
|
||||
(pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize, pSection->nAlign)) != -1) {
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->Type, pSection->nBank);
|
||||
} else {
|
||||
errx(1, "Unable to load fixed %s section into bank $%02lX",
|
||||
SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AssignFloatingBankSections(enum eSectionType type)
|
||||
{
|
||||
ensureSectionTypeIsValid(type);
|
||||
|
||||
struct sSection *pSection;
|
||||
|
||||
while ((pSection = FindLargestSection(type, false))) {
|
||||
SLONG org;
|
||||
|
||||
if ((org = area_AllocAnyBank(pSection->nByteSize, pSection->nAlign, type)) != -1) {
|
||||
if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) {
|
||||
errx(1, "All ROMX sections must be fixed when using overlay");
|
||||
}
|
||||
pSection->nOrg = org & 0xFFFF;
|
||||
pSection->nBank = org >> 16;
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->Type, pSection->nBank);
|
||||
} else {
|
||||
errx(1, "Unable to place %s section anywhere",
|
||||
SECT_ATTRIBUTES[type].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AssignSections(void)
|
||||
{
|
||||
@@ -353,38 +389,11 @@ AssignSections(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Next, let's assign all the bankfixed ONLY ROMX sections...
|
||||
* Next, let's assign all the bankfixed ONLY sections...
|
||||
*
|
||||
*/
|
||||
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->nOrg == -1 && pSection->nBank != -1) {
|
||||
if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) {
|
||||
errx(1, "All ROMX sections must be fixed when using overlay");
|
||||
}
|
||||
switch (pSection->Type) {
|
||||
case SECT_ROMX:
|
||||
case SECT_SRAM:
|
||||
case SECT_VRAM:
|
||||
case SECT_WRAMX:
|
||||
if (VerifyAndSetBank(pSection) &&
|
||||
(pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) != -1) {
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->Type, pSection->nBank);
|
||||
} else {
|
||||
errx(1, "Unable to load fixed %s section into bank $%02lX",
|
||||
SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank);
|
||||
}
|
||||
break;
|
||||
|
||||
default: // Handle other sections later
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pSection = pSection->pNext;
|
||||
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
|
||||
AssignFixedBankSections(i);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -397,8 +406,8 @@ AssignSections(void)
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->nOrg != -1 && pSection->nBank == -1) {
|
||||
if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) {
|
||||
errx(1, "All ROMX sections must be fixed when using overlay");
|
||||
}
|
||||
errx(1, "All ROMX sections must be fixed when using overlay");
|
||||
}
|
||||
switch (pSection->Type) {
|
||||
case SECT_ROMX:
|
||||
case SECT_VRAM:
|
||||
@@ -427,44 +436,9 @@ AssignSections(void)
|
||||
* sections
|
||||
*
|
||||
*/
|
||||
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0) {
|
||||
if (pSection->Type == SECT_ROMX && options & OPT_OVERLAY) {
|
||||
errx(1, "All ROMX sections must be fixed when using overlay");
|
||||
}
|
||||
switch (pSection->Type) {
|
||||
case SECT_WRAM0:
|
||||
case SECT_HRAM:
|
||||
case SECT_ROM0:
|
||||
pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank;
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[pSection->nBank],
|
||||
pSection->nByteSize)) == -1) {
|
||||
errx(1, "%s section too large", SECT_ATTRIBUTES[pSection->Type].name);
|
||||
}
|
||||
pSection->oAssigned = 1;
|
||||
break;
|
||||
|
||||
case SECT_SRAM:
|
||||
case SECT_VRAM:
|
||||
case SECT_WRAMX:
|
||||
case SECT_ROMX:
|
||||
break;
|
||||
|
||||
default:
|
||||
errx(1, "(INTERNAL) Unknown section type!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSection = pSection->pNext;
|
||||
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
|
||||
AssignFloatingBankSections(i);
|
||||
}
|
||||
|
||||
AssignBankedSections(SECT_ROMX);
|
||||
AssignBankedSections(SECT_VRAM);
|
||||
AssignBankedSections(SECT_WRAMX);
|
||||
AssignBankedSections(SECT_SRAM);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user