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:
@@ -10,6 +10,7 @@ struct Section {
|
|||||||
ULONG nPC;
|
ULONG nPC;
|
||||||
ULONG nOrg;
|
ULONG nOrg;
|
||||||
ULONG nBank;
|
ULONG nBank;
|
||||||
|
ULONG nAlign;
|
||||||
struct Section *pNext;
|
struct Section *pNext;
|
||||||
struct Patch *pPatches;
|
struct Patch *pPatches;
|
||||||
struct Charmap *charmap;
|
struct Charmap *charmap;
|
||||||
@@ -20,6 +21,7 @@ void out_PrepPass2(void);
|
|||||||
void out_SetFileName(char *s);
|
void out_SetFileName(char *s);
|
||||||
void out_NewSection(char *pzName, ULONG secttype);
|
void out_NewSection(char *pzName, ULONG secttype);
|
||||||
void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank);
|
void out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank);
|
||||||
|
void out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank);
|
||||||
void out_AbsByte(int b);
|
void out_AbsByte(int b);
|
||||||
void out_AbsByteGroup(char *s, int length);
|
void out_AbsByteGroup(char *s, int length);
|
||||||
void out_RelByte(struct Expression * expr);
|
void out_RelByte(struct Expression * expr);
|
||||||
|
|||||||
@@ -64,8 +64,10 @@ enum eSectionType {
|
|||||||
struct sSection {
|
struct sSection {
|
||||||
SLONG nBank;
|
SLONG nBank;
|
||||||
SLONG nOrg;
|
SLONG nOrg;
|
||||||
|
SLONG nAlign;
|
||||||
BBOOL oAssigned;
|
BBOOL oAssigned;
|
||||||
|
|
||||||
|
char *pzName;
|
||||||
SLONG nByteSize;
|
SLONG nByteSize;
|
||||||
enum eSectionType Type;
|
enum eSectionType Type;
|
||||||
UBYTE *pData;
|
UBYTE *pData;
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ void if_skip_to_endc( void )
|
|||||||
%left T_OP_MUL T_OP_DIV T_OP_MOD
|
%left T_OP_MUL T_OP_DIV T_OP_MOD
|
||||||
%left T_OP_NOT
|
%left T_OP_NOT
|
||||||
%left T_OP_DEF
|
%left T_OP_DEF
|
||||||
%left T_OP_BANK
|
%left T_OP_BANK T_OP_ALIGN
|
||||||
%left T_OP_SIN
|
%left T_OP_SIN
|
||||||
%left T_OP_COS
|
%left T_OP_COS
|
||||||
%left T_OP_TAN
|
%left T_OP_TAN
|
||||||
@@ -1113,6 +1113,10 @@ section:
|
|||||||
else
|
else
|
||||||
yyerror("Address $%x not 16-bit", $6);
|
yyerror("Address $%x not 16-bit", $6);
|
||||||
}
|
}
|
||||||
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']'
|
||||||
|
{
|
||||||
|
out_NewAlignedSection($2, $4, $8, -1);
|
||||||
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']'
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']'
|
||||||
{
|
{
|
||||||
bankrangecheck($2, $4, -1, $8);
|
bankrangecheck($2, $4, -1, $8);
|
||||||
@@ -1124,6 +1128,14 @@ section:
|
|||||||
}
|
}
|
||||||
bankrangecheck($2, $4, $6, $11);
|
bankrangecheck($2, $4, $6, $11);
|
||||||
}
|
}
|
||||||
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']' ',' T_OP_BANK '[' const ']'
|
||||||
|
{
|
||||||
|
out_NewAlignedSection($2, $4, $8, $13);
|
||||||
|
}
|
||||||
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' ',' T_OP_ALIGN '[' const ']'
|
||||||
|
{
|
||||||
|
out_NewAlignedSection($2, $4, $13, $8);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
sectiontype:
|
sectiontype:
|
||||||
|
|||||||
@@ -267,6 +267,7 @@ struct sLexInitString staticstrings[] = {
|
|||||||
{"def", T_OP_DEF},
|
{"def", T_OP_DEF},
|
||||||
|
|
||||||
{"bank", T_OP_BANK},
|
{"bank", T_OP_BANK},
|
||||||
|
{"align", T_OP_ALIGN},
|
||||||
|
|
||||||
{"round", T_OP_ROUND},
|
{"round", T_OP_ROUND},
|
||||||
{"ceil", T_OP_CEIL},
|
{"ceil", T_OP_CEIL},
|
||||||
|
|||||||
@@ -201,8 +201,7 @@ writepatch(struct Patch * pPatch, FILE * f)
|
|||||||
void
|
void
|
||||||
writesection(struct Section * pSect, FILE * f)
|
writesection(struct Section * pSect, FILE * f)
|
||||||
{
|
{
|
||||||
//printf("SECTION: %s, ID: %d\n", pSect->pzName, getsectid(pSect));
|
fputstring(pSect->pzName, f); // RGB3 addition
|
||||||
|
|
||||||
fputlong(pSect->nPC, f);
|
fputlong(pSect->nPC, f);
|
||||||
fputc(pSect->nType, f);
|
fputc(pSect->nType, f);
|
||||||
fputlong(pSect->nOrg, f);
|
fputlong(pSect->nOrg, f);
|
||||||
@@ -211,6 +210,8 @@ writesection(struct Section * pSect, FILE * f)
|
|||||||
fputlong(pSect->nBank, f);
|
fputlong(pSect->nBank, f);
|
||||||
//RGB1 addition
|
//RGB1 addition
|
||||||
|
|
||||||
|
fputlong(pSect->nAlign, f); // RGB3 addition
|
||||||
|
|
||||||
if ((pSect->nType == SECT_ROM0)
|
if ((pSect->nType == SECT_ROM0)
|
||||||
|| (pSect->nType == SECT_ROMX)) {
|
|| (pSect->nType == SECT_ROMX)) {
|
||||||
struct Patch *pPatch;
|
struct Patch *pPatch;
|
||||||
@@ -490,7 +491,7 @@ out_WriteObject(void)
|
|||||||
struct PatchSymbol *pSym;
|
struct PatchSymbol *pSym;
|
||||||
struct Section *pSect;
|
struct Section *pSect;
|
||||||
|
|
||||||
fwrite("RGB2", 1, 4, f);
|
fwrite("RGB3", 1, 4, f);
|
||||||
fputlong(countsymbols(), f);
|
fputlong(countsymbols(), f);
|
||||||
fputlong(countsections(), f);
|
fputlong(countsections(), f);
|
||||||
|
|
||||||
@@ -546,7 +547,7 @@ out_SetFileName(char *s)
|
|||||||
* Find a section by name and type. If it doesn't exist, create it
|
* Find a section by name and type. If it doesn't exist, create it
|
||||||
*/
|
*/
|
||||||
struct Section *
|
struct Section *
|
||||||
out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
|
out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank, SLONG alignment)
|
||||||
{
|
{
|
||||||
struct Section *pSect, **ppSect;
|
struct Section *pSect, **ppSect;
|
||||||
|
|
||||||
@@ -557,7 +558,8 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
|
|||||||
if (strcmp(pzName, pSect->pzName) == 0) {
|
if (strcmp(pzName, pSect->pzName) == 0) {
|
||||||
if (secttype == pSect->nType
|
if (secttype == pSect->nType
|
||||||
&& ((ULONG) org) == pSect->nOrg
|
&& ((ULONG) org) == pSect->nOrg
|
||||||
&& ((ULONG) bank) == pSect->nBank) {
|
&& ((ULONG) bank) == pSect->nBank
|
||||||
|
&& ((ULONG) alignment == pSect->nAlign)) {
|
||||||
return (pSect);
|
return (pSect);
|
||||||
} else
|
} else
|
||||||
fatalerror
|
fatalerror
|
||||||
@@ -574,6 +576,7 @@ out_FindSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
|
|||||||
pSect->nPC = 0;
|
pSect->nPC = 0;
|
||||||
pSect->nOrg = org;
|
pSect->nOrg = org;
|
||||||
pSect->nBank = bank;
|
pSect->nBank = bank;
|
||||||
|
pSect->nAlign = alignment;
|
||||||
pSect->pNext = NULL;
|
pSect->pNext = NULL;
|
||||||
pSect->pPatches = NULL;
|
pSect->pPatches = NULL;
|
||||||
pSect->charmap = NULL;
|
pSect->charmap = NULL;
|
||||||
@@ -610,7 +613,7 @@ out_SetCurrentSection(struct Section * pSect)
|
|||||||
void
|
void
|
||||||
out_NewSection(char *pzName, ULONG secttype)
|
out_NewSection(char *pzName, ULONG secttype)
|
||||||
{
|
{
|
||||||
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1));
|
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, -1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -619,7 +622,19 @@ out_NewSection(char *pzName, ULONG secttype)
|
|||||||
void
|
void
|
||||||
out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
|
out_NewAbsSection(char *pzName, ULONG secttype, SLONG org, SLONG bank)
|
||||||
{
|
{
|
||||||
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank));
|
out_SetCurrentSection(out_FindSection(pzName, secttype, org, bank, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the current section by name and type, using a given byte alignment
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
out_NewAlignedSection(char *pzName, ULONG secttype, SLONG alignment, SLONG bank)
|
||||||
|
{
|
||||||
|
if (alignment < 0 || alignment > 16) {
|
||||||
|
yyerror("Alignment must be between 0-16 bits.");
|
||||||
|
}
|
||||||
|
out_SetCurrentSection(out_FindSection(pzName, secttype, -1, bank, 1 << alignment));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const struct sSectionAttributes SECT_ATTRIBUTES[] = {
|
|||||||
case SECT_WRAMX: DOMAXWBANK(y); break; \
|
case SECT_WRAMX: DOMAXWBANK(y); break; \
|
||||||
case SECT_SRAM: DOMAXSBANK(y); break; \
|
case SECT_SRAM: DOMAXSBANK(y); break; \
|
||||||
case SECT_VRAM: DOMAXVBANK(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 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);}
|
||||||
@@ -78,45 +78,51 @@ area_Avail(SLONG bank)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SLONG
|
SLONG
|
||||||
area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
|
area_doAlloc(struct sFreeArea *pArea, SLONG org, SLONG size)
|
||||||
{
|
{
|
||||||
struct sFreeArea *pArea;
|
if (org >= pArea->nOrg && (org + size) <= (pArea->nOrg + pArea->nSize)) {
|
||||||
|
|
||||||
pArea = *ppArea;
|
|
||||||
while (pArea) {
|
|
||||||
if (org >= pArea->nOrg
|
|
||||||
&& (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
|
|
||||||
if (org == pArea->nOrg) {
|
if (org == pArea->nOrg) {
|
||||||
pArea->nOrg += size;
|
pArea->nOrg += size;
|
||||||
pArea->nSize -= size;
|
pArea->nSize -= size;
|
||||||
return 0;
|
return org;
|
||||||
} else {
|
} else {
|
||||||
if ((org + size - 1) ==
|
if ((org + size) == (pArea->nOrg + pArea->nSize)) {
|
||||||
(pArea->nOrg + pArea->nSize - 1)) {
|
|
||||||
pArea->nSize -= size;
|
pArea->nSize -= size;
|
||||||
return 0;
|
return org;
|
||||||
} else {
|
} else {
|
||||||
struct sFreeArea *pNewArea;
|
struct sFreeArea *pNewArea;
|
||||||
|
|
||||||
if ((pNewArea =
|
if ((pNewArea = malloc(sizeof(struct sFreeArea))) != NULL) {
|
||||||
malloc(sizeof(struct sFreeArea)))
|
|
||||||
!= NULL) {
|
|
||||||
*pNewArea = *pArea;
|
*pNewArea = *pArea;
|
||||||
pNewArea->pPrev = pArea;
|
pNewArea->pPrev = pArea;
|
||||||
pArea->pNext = pNewArea;
|
pArea->pNext = pNewArea;
|
||||||
pArea->nSize =
|
pArea->nSize = org - pArea->nOrg;
|
||||||
org - pArea->nOrg;
|
|
||||||
pNewArea->nOrg = org + size;
|
pNewArea->nOrg = org + size;
|
||||||
pNewArea->nSize -=
|
pNewArea->nSize -= size + pArea->nSize;
|
||||||
size + pArea->nSize;
|
return org;
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
} else {
|
||||||
err(1, NULL);
|
err(1, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SLONG
|
||||||
|
area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
|
||||||
|
{
|
||||||
|
struct sFreeArea *pArea;
|
||||||
|
|
||||||
|
pArea = *ppArea;
|
||||||
|
while (pArea) {
|
||||||
|
SLONG result = area_doAlloc(pArea, org, size);
|
||||||
|
if (result != -1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ppArea = &(pArea->pNext);
|
ppArea = &(pArea->pNext);
|
||||||
pArea = *ppArea;
|
pArea = *ppArea;
|
||||||
}
|
}
|
||||||
@@ -142,37 +148,41 @@ area_AllocAbsAnyBank(SLONG org, SLONG size, enum eSectionType type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SLONG
|
SLONG
|
||||||
area_Alloc(struct sFreeArea ** ppArea, SLONG size)
|
area_Alloc(struct sFreeArea ** ppArea, SLONG size, SLONG alignment) {
|
||||||
{
|
|
||||||
struct sFreeArea *pArea;
|
struct sFreeArea *pArea;
|
||||||
|
if (alignment < 1) {
|
||||||
|
alignment = 1;
|
||||||
|
}
|
||||||
|
|
||||||
pArea = *ppArea;
|
pArea = *ppArea;
|
||||||
while (pArea) {
|
while (pArea) {
|
||||||
if (size <= pArea->nSize) {
|
SLONG org = pArea->nOrg;
|
||||||
SLONG r;
|
if (org % alignment) {
|
||||||
|
org += alignment;
|
||||||
r = pArea->nOrg;
|
|
||||||
pArea->nOrg += size;
|
|
||||||
pArea->nSize -= size;
|
|
||||||
|
|
||||||
return (r);
|
|
||||||
}
|
}
|
||||||
|
org -= org % alignment;
|
||||||
|
|
||||||
|
SLONG result = area_doAlloc(pArea, org, size);
|
||||||
|
if (result != -1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ppArea = &(pArea->pNext);
|
ppArea = &(pArea->pNext);
|
||||||
pArea = *ppArea;
|
pArea = *ppArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SLONG
|
SLONG
|
||||||
area_AllocAnyBank(SLONG size, enum eSectionType type) {
|
area_AllocAnyBank(SLONG size, SLONG alignment, enum eSectionType type) {
|
||||||
ensureSectionTypeIsValid(type);
|
ensureSectionTypeIsValid(type);
|
||||||
|
|
||||||
SLONG startBank = SECT_ATTRIBUTES[type].bank;
|
SLONG startBank = SECT_ATTRIBUTES[type].bank;
|
||||||
SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
|
SLONG bankCount = SECT_ATTRIBUTES[type].bankCount;
|
||||||
|
|
||||||
for (int i = 0; i < bankCount; i++) {
|
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) {
|
if (org != -1) {
|
||||||
return ((startBank + i) << 16) | org;
|
return ((startBank + i) << 16) | org;
|
||||||
}
|
}
|
||||||
@@ -182,45 +192,27 @@ area_AllocAnyBank(SLONG size, enum eSectionType type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sSection *
|
struct sSection *
|
||||||
FindLargestSection(enum eSectionType type)
|
FindLargestSection(enum eSectionType type, bool bankFixed)
|
||||||
{
|
{
|
||||||
struct sSection *pSection, *r = NULL;
|
struct sSection *pSection, *r = NULL;
|
||||||
SLONG nLargest = 0;
|
SLONG nLargest = 0;
|
||||||
|
SLONG nLargestAlignment = 0;
|
||||||
|
|
||||||
pSection = pSections;
|
pSection = pSections;
|
||||||
while (pSection) {
|
while (pSection) {
|
||||||
if (pSection->oAssigned == 0 && pSection->Type == type) {
|
if (pSection->oAssigned == 0 && pSection->Type == type && (bankFixed ^ (pSection->nBank == -1))) {
|
||||||
if (pSection->nByteSize > nLargest) {
|
if (pSection->nAlign > nLargestAlignment || (pSection->nAlign == nLargestAlignment && pSection->nByteSize > nLargest)) {
|
||||||
nLargest = pSection->nByteSize;
|
nLargest = pSection->nByteSize;
|
||||||
|
nLargestAlignment = pSection->nAlign;
|
||||||
r = pSection;
|
r = pSection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pSection = pSection->pNext;
|
pSection = pSection->pNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
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
|
bool
|
||||||
VerifyAndSetBank(struct sSection *pSection)
|
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
|
void
|
||||||
AssignSections(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...
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
|
||||||
pSection = pSections;
|
AssignFixedBankSections(i);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -427,44 +436,9 @@ AssignSections(void)
|
|||||||
* sections
|
* sections
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
for (enum eSectionType i = SECT_MIN; i <= SECT_MAX; i++) {
|
||||||
pSection = pSections;
|
AssignFloatingBankSections(i);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignBankedSections(SECT_ROMX);
|
|
||||||
AssignBankedSections(SECT_VRAM);
|
|
||||||
AssignBankedSections(SECT_WRAMX);
|
|
||||||
AssignBankedSections(SECT_SRAM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ struct sSection *pLibSections = NULL;
|
|||||||
UBYTE dummymem;
|
UBYTE dummymem;
|
||||||
BBOOL oReadLib = 0;
|
BBOOL oReadLib = 0;
|
||||||
|
|
||||||
|
enum ObjectFileContents {
|
||||||
|
CONTAINS_SECTION_NAME = 1 << 0,
|
||||||
|
CONTAINS_SECTION_ALIGNMENT = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The usual byte order stuff
|
* The usual byte order stuff
|
||||||
*
|
*
|
||||||
@@ -46,21 +51,41 @@ readword(FILE * f)
|
|||||||
|
|
||||||
return (r);
|
return (r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a NULL terminated string from a file
|
* Read a NULL terminated string from a file
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
SLONG
|
SLONG
|
||||||
readasciiz(char *s, FILE * f)
|
readasciiz(char **dest, FILE *f)
|
||||||
{
|
{
|
||||||
SLONG r = 0;
|
SLONG r = 0;
|
||||||
|
|
||||||
while (((*s++) = fgetc(f)) != 0)
|
size_t bufferLength = 16;
|
||||||
|
char *start = malloc(bufferLength);
|
||||||
|
char *s = start;
|
||||||
|
|
||||||
|
if (!s) {
|
||||||
|
err(1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (((*s++) = fgetc(f)) != 0) {
|
||||||
r += 1;
|
r += 1;
|
||||||
|
|
||||||
|
if (r >= bufferLength) {
|
||||||
|
bufferLength *= 2;
|
||||||
|
start = realloc(start, bufferLength);
|
||||||
|
if (!start) {
|
||||||
|
err(1, NULL);
|
||||||
|
}
|
||||||
|
s = start + r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*dest = start;
|
||||||
return (r + 1);
|
return (r + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new section and link it into the list
|
* Allocate a new section and link it into the list
|
||||||
*
|
*
|
||||||
@@ -97,7 +122,6 @@ AllocSection(void)
|
|||||||
struct sSymbol *
|
struct sSymbol *
|
||||||
obj_ReadSymbol(FILE * f)
|
obj_ReadSymbol(FILE * f)
|
||||||
{
|
{
|
||||||
char s[256];
|
|
||||||
struct sSymbol *pSym;
|
struct sSymbol *pSym;
|
||||||
|
|
||||||
pSym = malloc(sizeof *pSym);
|
pSym = malloc(sizeof *pSym);
|
||||||
@@ -105,13 +129,7 @@ obj_ReadSymbol(FILE * f)
|
|||||||
err(1, NULL);
|
err(1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
readasciiz(s, f);
|
readasciiz(&pSym->pzName, f);
|
||||||
pSym->pzName = malloc(strlen(s) + 1);
|
|
||||||
if (!pSym->pzName) {
|
|
||||||
err(1, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(pSym->pzName, s);
|
|
||||||
if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) {
|
if ((pSym->Type = (enum eSymbolType) fgetc(f)) != SYM_IMPORT) {
|
||||||
pSym->nSectionID = readlong(f);
|
pSym->nSectionID = readlong(f);
|
||||||
pSym->nOffset = readlong(f);
|
pSym->nOffset = readlong(f);
|
||||||
@@ -130,10 +148,12 @@ obj_ReadRGB0Section(FILE * f)
|
|||||||
|
|
||||||
pSection = AllocSection();
|
pSection = AllocSection();
|
||||||
|
|
||||||
|
pSection->pzName = "";
|
||||||
pSection->nByteSize = readlong(f);
|
pSection->nByteSize = readlong(f);
|
||||||
pSection->Type = (enum eSectionType) fgetc(f);
|
pSection->Type = (enum eSectionType) fgetc(f);
|
||||||
pSection->nOrg = -1;
|
pSection->nOrg = -1;
|
||||||
pSection->nBank = -1;
|
pSection->nBank = -1;
|
||||||
|
pSection->nAlign = 1;
|
||||||
|
|
||||||
/* does the user want the -s mode? */
|
/* does the user want the -s mode? */
|
||||||
|
|
||||||
@@ -153,7 +173,6 @@ obj_ReadRGB0Section(FILE * f)
|
|||||||
|
|
||||||
SLONG nNumberOfPatches;
|
SLONG nNumberOfPatches;
|
||||||
struct sPatch **ppPatch, *pPatch;
|
struct sPatch **ppPatch, *pPatch;
|
||||||
char s[256];
|
|
||||||
|
|
||||||
fread(pSection->pData, sizeof(UBYTE),
|
fread(pSection->pData, sizeof(UBYTE),
|
||||||
pSection->nByteSize, f);
|
pSection->nByteSize, f);
|
||||||
@@ -171,14 +190,7 @@ obj_ReadRGB0Section(FILE * f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*ppPatch = pPatch;
|
*ppPatch = pPatch;
|
||||||
readasciiz(s, f);
|
readasciiz(&pPatch->pzFilename, f);
|
||||||
|
|
||||||
pPatch->pzFilename = malloc(strlen(s) + 1);
|
|
||||||
if (!pPatch->pzFilename) {
|
|
||||||
err(1, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(pPatch->pzFilename, s);
|
|
||||||
|
|
||||||
pPatch->nLineNo =
|
pPatch->nLineNo =
|
||||||
readlong(f);
|
readlong(f);
|
||||||
@@ -272,22 +284,29 @@ obj_ReadRGB0(FILE * pObjfile)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct sSection *
|
struct sSection *
|
||||||
obj_ReadRGB1Section(FILE * f)
|
obj_ReadRGBSection(FILE * f, enum ObjectFileContents contents)
|
||||||
{
|
{
|
||||||
struct sSection *pSection;
|
struct sSection *pSection;
|
||||||
|
|
||||||
pSection = AllocSection();
|
pSection = AllocSection();
|
||||||
|
|
||||||
|
if (contents & CONTAINS_SECTION_NAME) {
|
||||||
|
readasciiz(&pSection->pzName, f);
|
||||||
|
} else {
|
||||||
|
pSection->pzName = "";
|
||||||
|
}
|
||||||
|
|
||||||
pSection->nByteSize = readlong(f);
|
pSection->nByteSize = readlong(f);
|
||||||
pSection->Type = (enum eSectionType) fgetc(f);
|
pSection->Type = (enum eSectionType) fgetc(f);
|
||||||
/*
|
|
||||||
* And because of THIS new feature I'll have to rewrite loads and
|
|
||||||
* loads of stuff... oh well it needed to be done anyway
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
pSection->nOrg = readlong(f);
|
pSection->nOrg = readlong(f);
|
||||||
pSection->nBank = readlong(f);
|
pSection->nBank = readlong(f);
|
||||||
|
|
||||||
|
if (contents & CONTAINS_SECTION_ALIGNMENT) {
|
||||||
|
pSection->nAlign = readlong(f);
|
||||||
|
} else {
|
||||||
|
pSection->nAlign = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* does the user want the -s mode? */
|
/* does the user want the -s mode? */
|
||||||
|
|
||||||
if ((options & OPT_SMALL) && (pSection->Type == SECT_ROMX)) {
|
if ((options & OPT_SMALL) && (pSection->Type == SECT_ROMX)) {
|
||||||
@@ -306,7 +325,6 @@ obj_ReadRGB1Section(FILE * f)
|
|||||||
|
|
||||||
SLONG nNumberOfPatches;
|
SLONG nNumberOfPatches;
|
||||||
struct sPatch **ppPatch, *pPatch;
|
struct sPatch **ppPatch, *pPatch;
|
||||||
char s[256];
|
|
||||||
|
|
||||||
fread(pSection->pData, sizeof(UBYTE),
|
fread(pSection->pData, sizeof(UBYTE),
|
||||||
pSection->nByteSize, f);
|
pSection->nByteSize, f);
|
||||||
@@ -324,13 +342,7 @@ obj_ReadRGB1Section(FILE * f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*ppPatch = pPatch;
|
*ppPatch = pPatch;
|
||||||
readasciiz(s, f);
|
readasciiz(&pPatch->pzFilename, f);
|
||||||
pPatch->pzFilename = malloc(strlen(s) + 1);
|
|
||||||
if (!pPatch->pzFilename) {
|
|
||||||
err(1, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(pPatch->pzFilename, s);
|
|
||||||
pPatch->nLineNo = readlong(f);
|
pPatch->nLineNo = readlong(f);
|
||||||
pPatch->nOffset = readlong(f);
|
pPatch->nOffset = readlong(f);
|
||||||
pPatch->Type = (enum ePatchType) fgetc(f);
|
pPatch->Type = (enum ePatchType) fgetc(f);
|
||||||
@@ -358,7 +370,7 @@ obj_ReadRGB1Section(FILE * f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
obj_ReadRGB1(FILE * pObjfile)
|
obj_ReadRGB(FILE * pObjfile, enum ObjectFileContents contents)
|
||||||
{
|
{
|
||||||
struct sSection *pFirstSection;
|
struct sSection *pFirstSection;
|
||||||
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
||||||
@@ -385,7 +397,7 @@ obj_ReadRGB1(FILE * pObjfile)
|
|||||||
while (nNumberOfSections--) {
|
while (nNumberOfSections--) {
|
||||||
struct sSection *pNewSection;
|
struct sSection *pNewSection;
|
||||||
|
|
||||||
pNewSection = obj_ReadRGB1Section(pObjfile);
|
pNewSection = obj_ReadRGBSection(pObjfile, contents);
|
||||||
pNewSection->nNumberOfSymbols = nNumberOfSymbols;
|
pNewSection->nNumberOfSymbols = nNumberOfSymbols;
|
||||||
if (pFirstSection == NULL)
|
if (pFirstSection == NULL)
|
||||||
pFirstSection = pNewSection;
|
pFirstSection = pNewSection;
|
||||||
@@ -432,7 +444,11 @@ obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
|
|||||||
case '1':
|
case '1':
|
||||||
case '2':
|
case '2':
|
||||||
//V2 is really the same but the are new patch types
|
//V2 is really the same but the are new patch types
|
||||||
obj_ReadRGB1(pObjfile);
|
obj_ReadRGB(pObjfile, 0);
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
// V3 is very similiar, but contains section names and byte alignment
|
||||||
|
obj_ReadRGB(pObjfile, CONTAINS_SECTION_NAME | CONTAINS_SECTION_ALIGNMENT);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errx(1, "'%s' is an unsupported version", tzObjectfile);
|
errx(1, "'%s' is an unsupported version", tzObjectfile);
|
||||||
@@ -482,9 +498,9 @@ lib_ReadXLB0(FILE * f)
|
|||||||
|
|
||||||
size = file_Length(f) - 4;
|
size = file_Length(f) - 4;
|
||||||
while (size) {
|
while (size) {
|
||||||
char name[256];
|
char *name;
|
||||||
|
|
||||||
size -= readasciiz(name, f);
|
size -= readasciiz(&name, f);
|
||||||
readword(f);
|
readword(f);
|
||||||
size -= 2;
|
size -= 2;
|
||||||
readword(f);
|
readword(f);
|
||||||
@@ -492,5 +508,6 @@ lib_ReadXLB0(FILE * f)
|
|||||||
size -= readlong(f);
|
size -= readlong(f);
|
||||||
size -= 4;
|
size -= 4;
|
||||||
obj_ReadOpenFile(f, name);
|
obj_ReadOpenFile(f, name);
|
||||||
|
free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user