Refactor section assignment in linker

Deduplicates and generalises a lot of code in assign.c:

- Replace area_AllocAbs*AnyBank() with area_AllocAbsAnyBank() function
that accepts a section type parameter
- Replace area_Alloc*AnyBank() with area_AllocAnyBank()
- Replace FindLargest*() with FindLargestSection()
- Replace Assign*Sections() with AssignBankedSections()
- Add VerifyAndSetBank(), which enables bank checks (and addition with
BANK_*) to be centralised
- Refactor the initialisation of AssignSections(), removing some magic
numbers and only setting MaxAvail[i] once
- Overhaul the duplicated cases throughout AssignSections()
This commit is contained in:
Ben10do
2017-01-25 19:21:05 +00:00
parent 547abfefc1
commit 420ea638a7
2 changed files with 173 additions and 601 deletions

View File

@@ -5,13 +5,26 @@
enum eBankDefine { enum eBankDefine {
BANK_ROM0 = 0, BANK_ROM0 = 0,
BANK_ROMX,
BANK_WRAM0 = 512, BANK_WRAM0 = 512,
BANK_WRAMX, BANK_WRAMX,
BANK_VRAM = 520, BANK_VRAM = 520,
BANK_HRAM = 522, BANK_HRAM = 522,
BANK_SRAM = 523 BANK_SRAM = 523
}; };
#define MAXBANKS 527
enum eBankCount {
BANK_COUNT_ROM0 = 1,
BANK_COUNT_ROMX = 511,
BANK_COUNT_WRAM0 = 1,
BANK_COUNT_WRAMX = 7,
BANK_COUNT_VRAM = 2,
BANK_COUNT_HRAM = 1,
BANK_COUNT_SRAM = 4
};
#define MAXBANKS (BANK_COUNT_ROM0 + BANK_COUNT_ROMX + BANK_COUNT_WRAM0 + BANK_COUNT_WRAMX \
+ BANK_COUNT_VRAM + BANK_COUNT_HRAM + BANK_COUNT_SRAM)
extern SLONG area_Avail(SLONG bank); extern SLONG area_Avail(SLONG bank);
extern void AssignSections(void); extern void AssignSections(void);

View File

@@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include "extern/err.h" #include "extern/err.h"
#include "link/mylink.h" #include "link/mylink.h"
@@ -13,6 +14,14 @@ struct sFreeArea {
struct sFreeArea *pPrev, *pNext; struct sFreeArea *pPrev, *pNext;
}; };
struct sSectionAttributes {
const char *name;
SLONG bank;
SLONG offset; // bank + offset = bank originally stored in a section struct
SLONG minBank;
SLONG bankCount;
};
struct sFreeArea *BankFree[MAXBANKS]; struct sFreeArea *BankFree[MAXBANKS];
SLONG MaxAvail[MAXBANKS]; SLONG MaxAvail[MAXBANKS];
SLONG MaxBankUsed; SLONG MaxBankUsed;
@@ -20,11 +29,37 @@ SLONG MaxWBankUsed;
SLONG MaxSBankUsed; SLONG MaxSBankUsed;
SLONG MaxVBankUsed; SLONG MaxVBankUsed;
#define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);} const enum eSectionType SECT_MIN = SECT_WRAM0;
const enum eSectionType SECT_MAX = SECT_SRAM;
const struct sSectionAttributes SECT_ATTRIBUTES[] = {
{"WRAM0", BANK_WRAM0, 0, 0, BANK_COUNT_WRAM0},
{"VRAM", BANK_VRAM, 0, 0, BANK_COUNT_VRAM},
{"ROMX", BANK_ROMX, -1, 1, BANK_COUNT_ROMX},
{"ROM0", BANK_ROM0, 0, 0, BANK_COUNT_ROM0},
{"HRAM", BANK_HRAM, 0, 0, BANK_COUNT_HRAM},
{"WRAMX", BANK_WRAMX, 0, 0, BANK_COUNT_WRAMX},
{"SRAM", BANK_SRAM, 0, 0, BANK_COUNT_SRAM}
};
#define DOMAXBANK(x, y) {switch (x) { \
case SECT_ROMX: DOMAXRBANK(y); break; \
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; }}
#define DOMAXRBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
#define DOMAXWBANK(x) {if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);} #define DOMAXWBANK(x) {if( (x)>MaxWBankUsed ) MaxWBankUsed=(x);}
#define DOMAXSBANK(x) {if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);} #define DOMAXSBANK(x) {if( (x)>MaxSBankUsed ) MaxSBankUsed=(x);}
#define DOMAXVBANK(x) {if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);} #define DOMAXVBANK(x) {if( (x)>MaxVBankUsed ) MaxVBankUsed=(x);}
void
ensureSectionTypeIsValid(enum eSectionType type)
{
if (type < SECT_MIN || type > SECT_MAX) {
errx(1, "(INTERNAL) Invalid section type found.");
}
}
SLONG SLONG
area_Avail(SLONG bank) area_Avail(SLONG bank)
{ {
@@ -54,12 +89,12 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
if (org == pArea->nOrg) { if (org == pArea->nOrg) {
pArea->nOrg += size; pArea->nOrg += size;
pArea->nSize -= size; pArea->nSize -= size;
return (org); return 0;
} else { } else {
if ((org + size - 1) == if ((org + size - 1) ==
(pArea->nOrg + pArea->nSize - 1)) { (pArea->nOrg + pArea->nSize - 1)) {
pArea->nSize -= size; pArea->nSize -= size;
return (org); return 0;
} else { } else {
struct sFreeArea *pNewArea; struct sFreeArea *pNewArea;
@@ -75,7 +110,7 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
pNewArea->nSize -= pNewArea->nSize -=
size + pArea->nSize; size + pArea->nSize;
return (org); return 0;
} else { } else {
err(1, NULL); err(1, NULL);
} }
@@ -86,62 +121,26 @@ area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
pArea = *ppArea; pArea = *ppArea;
} }
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; return -1;
} }
SLONG SLONG
area_AllocAbsWRAMAnyBank(SLONG org, SLONG size) area_AllocAbsAnyBank(SLONG org, SLONG size, enum eSectionType type)
{ {
SLONG i; ensureSectionTypeIsValid(type);
for (i = 1; i <= 7; i += 1) { SLONG startBank = SECT_ATTRIBUTES[type].bank;
if (area_AllocAbs(&BankFree[BANK_WRAMX + i - 1], org, size) == org) { SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
return BANK_WRAMX + i - 1;
for (int i = 0; i < bankCount; i++) {
if (area_AllocAbs(&BankFree[startBank + i], org, size) != -1) {
return startBank + i;
} }
} }
return -1; return -1;
} }
SLONG
area_AllocAbsVRAMAnyBank(SLONG org, SLONG size)
{
if (area_AllocAbs(&BankFree[BANK_VRAM], org, size) == org) {
return BANK_VRAM;
}
if (area_AllocAbs(&BankFree[BANK_VRAM + 1], org, size) == org) {
return BANK_VRAM + 1;
}
return -1;
}
SLONG
area_AllocAbsROMXAnyBank(SLONG org, SLONG size)
{
SLONG i;
for (i = 1; i <= 511; i += 1) {
if (area_AllocAbs(&BankFree[i], org, size) == org)
return (i);
}
return (-1);
}
SLONG SLONG
area_Alloc(struct sFreeArea ** ppArea, SLONG size) area_Alloc(struct sFreeArea ** ppArea, SLONG size)
{ {
@@ -166,67 +165,31 @@ area_Alloc(struct sFreeArea ** ppArea, SLONG size)
} }
SLONG SLONG
area_AllocVRAMAnyBank(SLONG size) area_AllocAnyBank(SLONG size, enum eSectionType type) {
{ ensureSectionTypeIsValid(type);
SLONG i, org;
for (i = BANK_VRAM; i <= BANK_VRAM + 1; i += 1) { SLONG startBank = SECT_ATTRIBUTES[type].bank;
if ((org = area_Alloc(&BankFree[i], size)) != -1) SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
return ((i << 16) | org);
}
return (-1); for (int i = 0; i < bankCount; i++) {
} SLONG org = area_Alloc(&BankFree[startBank + i], size);
if (org != -1) {
SLONG return ((startBank + i) << 16) | org;
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; 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_AllocROMXAnyBank(SLONG size)
{
SLONG i, org;
for (i = 1; i <= 511; i += 1) {
if ((org = area_Alloc(&BankFree[i], size)) != -1)
return ((i << 16) | org);
}
return (-1);
}
struct sSection * struct sSection *
FindLargestWRAM(void) FindLargestSection(enum eSectionType type)
{ {
struct sSection *pSection, *r = NULL; struct sSection *pSection, *r = NULL;
SLONG nLargest = 0; SLONG nLargest = 0;
pSection = pSections; pSection = pSections;
while (pSection) { while (pSection) {
if (pSection->oAssigned == 0 && pSection->Type == SECT_WRAMX) { if (pSection->oAssigned == 0 && pSection->Type == type) {
if (pSection->nByteSize > nLargest) { if (pSection->nByteSize > nLargest) {
nLargest = pSection->nByteSize; nLargest = pSection->nByteSize;
r = pSection; r = pSection;
@@ -237,138 +200,40 @@ FindLargestWRAM(void)
return r; return r;
} }
struct sSection *
FindLargestVRAM(void)
{
struct sSection *pSection, *r = NULL;
SLONG nLargest = 0;
pSection = pSections;
while (pSection) {
if (pSection->oAssigned == 0 && pSection->Type == SECT_VRAM) {
if (pSection->nByteSize > nLargest) {
nLargest = pSection->nByteSize;
r = pSection;
}
}
pSection = pSection->pNext;
}
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)
{
struct sSection *pSection, *r = NULL;
SLONG nLargest = 0;
pSection = pSections;
while (pSection) {
if (pSection->oAssigned == 0 && pSection->Type == SECT_ROMX) {
if (pSection->nByteSize > nLargest) {
nLargest = pSection->nByteSize;
r = pSection;
}
}
pSection = pSection->pNext;
}
return (r);
}
void void
AssignVRAMSections(void) AssignBankedSections(enum eSectionType type)
{ {
ensureSectionTypeIsValid(type);
struct sSection *pSection; struct sSection *pSection;
while ((pSection = FindLargestVRAM())) { while ((pSection = FindLargestSection(type))) {
SLONG org; SLONG org;
if ((org = area_AllocVRAMAnyBank(pSection->nByteSize)) != -1) { if ((org = area_AllocAnyBank(pSection->nByteSize, type)) != -1) {
pSection->nOrg = org & 0xFFFF; pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16; pSection->nBank = org >> 16;
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank); DOMAXBANK(pSection->Type, pSection->nBank);
} else { } else {
errx(1, "Unable to place VRAM section anywhere"); errx(1, "Unable to place %s section anywhere",
SECT_ATTRIBUTES[type].name);
} }
} }
} }
void bool
AssignSRAMSections(void) VerifyAndSetBank(struct sSection *pSection)
{ {
struct sSection *pSection; ensureSectionTypeIsValid(pSection->Type);
while ((pSection = FindLargestSRAM())) { if (pSection->nBank >= SECT_ATTRIBUTES[pSection->Type].minBank
SLONG org; && pSection->nBank < SECT_ATTRIBUTES[pSection->Type].minBank + SECT_ATTRIBUTES[pSection->Type].bankCount) {
pSection->nBank += SECT_ATTRIBUTES[pSection->Type].bank + SECT_ATTRIBUTES[pSection->Type].offset;
return true;
if ((org = area_AllocSRAMAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16;
pSection->nBank += BANK_SRAM;
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else { } else {
errx(1, "Unable to place SRAM section anywhere"); return false;
}
}
}
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->nBank += BANK_WRAMX - 1;
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
errx(1, "Unable to place WRAMX section anywhere");
}
}
}
void
AssignCodeSections(void)
{
struct sSection *pSection;
while ((pSection = FindLargestCode())) {
SLONG org;
if ((org = area_AllocROMXAnyBank(pSection->nByteSize)) != -1) {
pSection->nOrg = org & 0xFFFF;
pSection->nBank = org >> 16;
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
} else {
errx(1, "Unable to place ROMX section anywhere");
}
} }
} }
@@ -392,17 +257,15 @@ AssignSections(void)
err(1, NULL); err(1, NULL);
} }
if (i == 0) { if (i == BANK_ROM0) {
/* ROM0 bank */ /* ROM0 bank */
BankFree[i]->nOrg = 0x0000; BankFree[i]->nOrg = 0x0000;
if (options & OPT_SMALL) { if (options & OPT_SMALL) {
BankFree[i]->nSize = 0x8000; BankFree[i]->nSize = 0x8000;
MaxAvail[i] = 0x8000;
} else { } else {
BankFree[i]->nSize = 0x4000; BankFree[i]->nSize = 0x4000;
MaxAvail[i] = 0x4000;
} }
} else if (i >= 1 && i <= 511) { } else if (i >= BANK_ROMX && i < BANK_ROMX + BANK_COUNT_ROMX) {
/* Swappable ROM bank */ /* Swappable ROM bank */
BankFree[i]->nOrg = 0x4000; BankFree[i]->nOrg = 0x4000;
/* /*
@@ -411,37 +274,34 @@ AssignSections(void)
*/ */
if (options & OPT_SMALL) { if (options & OPT_SMALL) {
BankFree[i]->nSize = 0; BankFree[i]->nSize = 0;
MaxAvail[i] = 0;
} else { } else {
BankFree[i]->nSize = 0x4000; BankFree[i]->nSize = 0x4000;
MaxAvail[i] = 0x4000;
} }
} else if (i == BANK_WRAM0) { } else if (i == BANK_WRAM0) {
/* WRAM */ /* WRAM */
BankFree[i]->nOrg = 0xC000; BankFree[i]->nOrg = 0xC000;
BankFree[i]->nSize = 0x1000; BankFree[i]->nSize = 0x1000;
MaxAvail[i] = 0x1000; } else if (i >= BANK_SRAM && i < BANK_SRAM + BANK_COUNT_SRAM) {
} else if (i >= BANK_SRAM && i <= BANK_SRAM + 3) {
/* Swappable SRAM bank */ /* Swappable SRAM bank */
BankFree[i]->nOrg = 0xA000; BankFree[i]->nOrg = 0xA000;
BankFree[i]->nSize = 0x2000; BankFree[i]->nSize = 0x2000;
MaxAvail[i] = 0x2000; } else if (i >= BANK_WRAMX && i < BANK_WRAMX + BANK_COUNT_WRAMX) {
} else if (i >= BANK_WRAMX && i <= BANK_WRAMX + 6) {
/* Swappable WRAM bank */ /* Swappable WRAM bank */
BankFree[i]->nOrg = 0xD000; BankFree[i]->nOrg = 0xD000;
BankFree[i]->nSize = 0x1000; BankFree[i]->nSize = 0x1000;
MaxAvail[i] = 0x1000; } else if (i >= BANK_VRAM && i < BANK_VRAM + BANK_COUNT_VRAM) {
} else if (i == BANK_VRAM || i == BANK_VRAM + 1) {
/* Swappable VRAM bank */ /* Swappable VRAM bank */
BankFree[i]->nOrg = 0x8000; BankFree[i]->nOrg = 0x8000;
BankFree[i]->nSize = 0x2000; BankFree[i]->nSize = 0x2000;
MaxAvail[i] = 0x2000;
} else if (i == BANK_HRAM) { } else if (i == BANK_HRAM) {
/* HRAM */ /* HRAM */
BankFree[i]->nOrg = 0xFF80; BankFree[i]->nOrg = 0xFF80;
BankFree[i]->nSize = 0x007F; BankFree[i]->nSize = 0x007F;
MaxAvail[i] = 0x007F; } else {
errx(1, "(INTERNAL) Unknown bank type!");
} }
MaxAvail[i] = BankFree[i]->nSize;
BankFree[i]->pPrev = NULL; BankFree[i]->pPrev = NULL;
BankFree[i]->pNext = NULL; BankFree[i]->pNext = NULL;
} }
@@ -460,242 +320,32 @@ AssignSections(void)
switch (pSection->Type) { switch (pSection->Type) {
case SECT_WRAM0: case SECT_WRAM0:
if (area_AllocAbs
(&BankFree[BANK_WRAM0], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
errx(1,
"Unable to load fixed WRAM0 "
"section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_WRAM0;
break;
case SECT_HRAM: case SECT_HRAM:
if (area_AllocAbs
(&BankFree[BANK_HRAM], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
errx(1, "Unable to load fixed HRAM "
"section at $%lX", pSection->nOrg);
}
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) {
errx(1,
"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
errx(1,
"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
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 >= 0
&& pSection->nBank <= 6) {
pSection->nBank +=
BANK_WRAMX;
if (area_AllocAbs
(&BankFree
[pSection->nBank],
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
errx(1,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXWBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
errx(1,
"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
break;
case SECT_VRAM:
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 <= 1) {
pSection->nBank +=
BANK_VRAM;
if (area_AllocAbs
(&BankFree
[pSection->nBank],
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
errx(1,
"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
errx(1,
"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
break;
case SECT_ROM0: case SECT_ROM0:
if (area_AllocAbs pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank;
(&BankFree[BANK_ROM0], pSection->nOrg, if (area_AllocAbs(&BankFree[pSection->nBank], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) { pSection->nByteSize) == -1) {
errx(1, "Unable to load fixed ROM0 " errx(1, "Unable to load fixed %s section at $%lX",
"section at $%lX", pSection->nOrg); SECT_ATTRIBUTES[pSection->Type].name,
pSection->nOrg);
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
pSection->nBank = BANK_ROM0;
break; break;
case SECT_SRAM:
case SECT_WRAMX:
case SECT_VRAM:
case SECT_ROMX: case SECT_ROMX:
if (pSection->nBank == -1) { if (pSection->nBank != -1 && pSection->nOrg != -1) {
/* if (VerifyAndSetBank(pSection) &&
* User doesn't care which bank, so he must want to area_AllocAbs(&BankFree[pSection->nBank], pSection->nOrg, pSection->nByteSize) != -1) {
* decide which position within that bank. DOMAXBANK(pSection->Type, pSection->nBank);
* We'll do that at a later stage when the really
* hardcoded things are allocated
*
*/
} else {
/*
* User wants to decide which bank we use
* Does he care about the position as well?
*
*/
if (pSection->nOrg == -1) {
/*
* Nope, any position will do
* Again, we'll do that later
*
*/
} else {
/*
* How hardcore can you possibly get? Why does
* he even USE this package? Yeah let's just
* direct address everything, shall we?
* Oh well, the customer is always right
*
*/
if (pSection->nBank >= 1
&& pSection->nBank <= 511) {
if (area_AllocAbs
(&BankFree
[pSection->nBank],
pSection->nOrg,
pSection->
nByteSize) !=
pSection->nOrg) {
errx(1,
"Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXBANK(pSection->
nBank);
pSection->oAssigned = 1; pSection->oAssigned = 1;
} else { } else {
errx(1, errx(1,
"Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank); "Unable to load fixed %s section at $%lX in bank $%02lX", SECT_ATTRIBUTES[pSection->Type].name, pSection->nOrg, pSection->nBank);
} }
} }
}
break; break;
} }
} }
@@ -710,70 +360,27 @@ AssignSections(void)
pSection = pSections; pSection = pSections;
while (pSection) { while (pSection) {
if (pSection->oAssigned == 0 if (pSection->oAssigned == 0
&& pSection->Type == SECT_ROMX
&& pSection->nOrg == -1 && pSection->nBank != -1) { && pSection->nOrg == -1 && pSection->nBank != -1) {
/* User wants to have a say... and he's pissed */ switch (pSection->Type) {
if (pSection->nBank >= 1 && pSection->nBank <= 511) { case SECT_ROMX:
if ((pSection->nOrg = case SECT_SRAM:
area_Alloc(&BankFree[pSection->nBank], case SECT_VRAM:
pSection->nByteSize)) == -1) { case SECT_WRAMX:
errx(1, if (VerifyAndSetBank(pSection) &&
"Unable to load fixed ROMX section into bank $%02lX", pSection->nBank); (pSection->nOrg = area_Alloc(&BankFree[pSection->nBank], pSection->nByteSize)) != -1) {
}
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank); DOMAXBANK(pSection->Type, pSection->nBank);
} else { } else {
errx(1, "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank); errx(1, "Unable to load fixed %s section into bank $%02lX",
SECT_ATTRIBUTES[pSection->Type].name, pSection->nBank);
} }
} else if (pSection->oAssigned == 0 break;
&& pSection->Type == SECT_SRAM
&& pSection->nOrg == -1 && pSection->nBank != -1) { default: // Handle other sections later
pSection->nBank += BANK_SRAM; break;
/* 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) {
errx(1, "Unable to load fixed SRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_VRAM
&& pSection->nOrg == -1 && pSection->nBank != -1) {
pSection->nBank += BANK_VRAM;
/* User wants to have a say... and he's pissed */
if (pSection->nBank >= BANK_VRAM && pSection->nBank <= BANK_VRAM + 1) {
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
} else {
errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} 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) {
errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
} }
} }
pSection = pSection->pNext; pSection = pSection->pNext;
} }
@@ -785,58 +392,27 @@ AssignSections(void)
pSection = pSections; pSection = pSections;
while (pSection) { while (pSection) {
if (pSection->oAssigned == 0 if (pSection->oAssigned == 0
&& pSection->Type == SECT_ROMX
&& pSection->nOrg != -1 && pSection->nBank == -1) { && pSection->nOrg != -1 && pSection->nBank == -1) {
/* User wants to have a say... and he's back with a switch (pSection->Type) {
* vengeance */ case SECT_ROMX:
case SECT_VRAM:
case SECT_SRAM:
case SECT_WRAMX:
if ((pSection->nBank = if ((pSection->nBank =
area_AllocAbsROMXAnyBank(pSection->nOrg, area_AllocAbsAnyBank(pSection->nOrg, pSection->nByteSize,
pSection->nByteSize)) == pSection->Type)) == -1) {
-1) { errx(1, "Unable to load fixed %s section at $%lX into any bank",
errx(1, "Unable to load fixed ROMX section at $%lX into any bank", pSection->nOrg); SECT_ATTRIBUTES[pSection->Type].name, pSection->nOrg);
} }
pSection->oAssigned = 1; pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank); DOMAXBANK(pSection->Type, pSection->nBank);
} else if (pSection->oAssigned == 0 break;
&& pSection->Type == SECT_VRAM
&& pSection->nOrg != -1 && pSection->nBank == -1) { default: // Handle other sections later
/* User wants to have a say... and he's back with a break;
* vengeance */
if ((pSection->nBank =
area_AllocAbsVRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
errx(1, "Unable to load fixed VRAM section at $%lX into any bank", pSection->nOrg);
} }
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) {
errx(1, "Unable to load fixed SRAM section at $%lX into any bank", pSection->nOrg);
}
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
* vengeance */
if ((pSection->nBank =
area_AllocAbsWRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
errx(1, "Unable to load fixed WRAMX section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} }
pSection = pSection->pNext; pSection = pSection->pNext;
} }
@@ -851,40 +427,23 @@ AssignSections(void)
if (pSection->oAssigned == 0) { if (pSection->oAssigned == 0) {
switch (pSection->Type) { switch (pSection->Type) {
case SECT_WRAM0: case SECT_WRAM0:
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_WRAM0],
pSection->nByteSize)) == -1) {
errx(1, "WRAM0 section too large");
}
pSection->nBank = BANK_WRAM0;
pSection->oAssigned = 1;
break;
case SECT_HRAM: case SECT_HRAM:
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_HRAM],
pSection->nByteSize)) == -1) {
errx(1, "HRAM section too large");
}
pSection->nBank = BANK_HRAM;
pSection->oAssigned = 1;
break;
case SECT_SRAM:
break;
case SECT_VRAM:
break;
case SECT_WRAMX:
break;
case SECT_ROM0: case SECT_ROM0:
pSection->nBank = SECT_ATTRIBUTES[pSection->Type].bank;
if ((pSection->nOrg = if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_ROM0], area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) { pSection->nByteSize)) == -1) {
errx(1, "ROM0 section too large"); errx(1, "%s section too large", SECT_ATTRIBUTES[pSection->Type].name);
} }
pSection->nBank = BANK_ROM0;
pSection->oAssigned = 1; pSection->oAssigned = 1;
break; break;
case SECT_SRAM:
case SECT_VRAM:
case SECT_WRAMX:
case SECT_ROMX: case SECT_ROMX:
break; break;
default: default:
errx(1, "(INTERNAL) Unknown section type!"); errx(1, "(INTERNAL) Unknown section type!");
break; break;
@@ -893,10 +452,10 @@ AssignSections(void)
pSection = pSection->pNext; pSection = pSection->pNext;
} }
AssignCodeSections(); AssignBankedSections(SECT_ROMX);
AssignVRAMSections(); AssignBankedSections(SECT_VRAM);
AssignWRAMSections(); AssignBankedSections(SECT_WRAMX);
AssignSRAMSections(); AssignBankedSections(SECT_SRAM);
} }
void void