Implement floating bank in linker script

Turns out that we can solve being unable to choose a bank to change
the PC of, by simply refusing to choose!
This commit is contained in:
ISSOtm
2024-08-14 02:16:13 +02:00
committed by Eldred Habert
parent e45a422da3
commit 28733fe312
3 changed files with 58 additions and 15 deletions

View File

@@ -86,6 +86,22 @@ If the bank has never been active thus far, the
.Dq current address .Dq current address
defaults to the beginning of the bank defaults to the beginning of the bank
.Pq e.g. Ad $4000 No for Ic ROMX No sections . .Pq e.g. Ad $4000 No for Ic ROMX No sections .
.Pp
Instead of giving a bank number, the keyword
.Ic FLOATING
can be used instead; this sets the type of the subsequent sections without binding them to a particular bank.
(If the type only allows a single bank, e.g.
.Ic ROM0 ,
then
.Ic FLOATING
is valid but redundant and has no effect.)
Since no particular section is active, the
.Dq current address
is made floating (as if by a
.Ql Ic FLOATING
directive), and
.Ic ORG
is not allowed.
.It Changing the current address .It Changing the current address
A bank must be active for any of these directives to be used. A bank must be active for any of these directives to be used.
.Pp .Pp
@@ -104,6 +120,7 @@ causes all sections between it and the next
.Ic ORG .Ic ORG
or bank specification to be placed at addresses automatically determined by or bank specification to be placed at addresses automatically determined by
.Nm . .Nm .
.Pq It is, however, compatible with Ic ALIGN No below.
.Pp .Pp
.Ql Ic ALIGN Ar addr , Ar offset .Ql Ic ALIGN Ar addr , Ar offset
increases the increases the

View File

@@ -35,6 +35,7 @@
static void includeFile(std::string &&path); static void includeFile(std::string &&path);
static void incLineNo(); static void incLineNo();
static void setFloatingSectionType(SectionType type);
static void setSectionType(SectionType type); static void setSectionType(SectionType type);
static void setSectionType(SectionType type, uint32_t bank); static void setSectionType(SectionType type, uint32_t bank);
static void setAddr(uint32_t addr); static void setAddr(uint32_t addr);
@@ -111,6 +112,9 @@ directive:
| sect_type number { | sect_type number {
setSectionType($1, $2); setSectionType($1, $2);
} }
| sect_type FLOATING {
setFloatingSectionType($1);
}
| FLOATING { | FLOATING {
makeAddrFloating(); makeAddrFloating();
} }
@@ -388,6 +392,20 @@ static void setActiveTypeAndIdx(SectionType type, uint32_t idx) {
} }
} }
static void setFloatingSectionType(SectionType type) {
if (nbbanks(type) == 1) {
setActiveTypeAndIdx(type, 0); // There is only a single bank anyway, so just set the index to 0.
} else {
activeType = type;
activeBankIdx = UINT32_MAX;
// Force PC to be floating for this kind of section.
// Because we wouldn't know how to index into `curAddr[activeType]`!
isPcFloating = true;
floatingAlignMask = 0;
floatingAlignOffset = 0;
}
}
static void setSectionType(SectionType type) { static void setSectionType(SectionType type) {
auto const &context = lexerStack.back(); auto const &context = lexerStack.back();
@@ -433,6 +451,10 @@ static void setAddr(uint32_t addr) {
scriptError(context, "Cannot set the current address: no memory region is active"); scriptError(context, "Cannot set the current address: no memory region is active");
return; return;
} }
if (activeBankIdx == UINT32_MAX) {
scriptError(context, "Cannot set the current address: the bank is floating");
return;
}
auto &pc = curAddr[activeType][activeBankIdx]; auto &pc = curAddr[activeType][activeBankIdx];
auto const &typeInfo = sectionTypeInfo[activeType]; auto const &typeInfo = sectionTypeInfo[activeType];
@@ -627,6 +649,9 @@ static void placeSection(std::string const &name, bool isOptional) {
); );
} }
if (activeBankIdx == UINT32_MAX) {
section->isBankFixed = false;
} else {
uint32_t bank = activeBankIdx + typeInfo.firstBank; uint32_t bank = activeBankIdx + typeInfo.firstBank;
if (section->isBankFixed && bank != section->bank) { if (section->isBankFixed && bank != section->bank) {
scriptError( scriptError(
@@ -641,6 +666,7 @@ static void placeSection(std::string const &name, bool isOptional) {
} }
section->isBankFixed = true; section->isBankFixed = true;
section->bank = bank; section->bank = bank;
}
if (!isPcFloating) { if (!isPcFloating) {
uint16_t &org = curAddr[activeType][activeBankIdx]; uint16_t &org = curAddr[activeType][activeBankIdx];

View File

@@ -1,3 +1,3 @@
error: script-syntax-error.link(2): syntax error, unexpected ORG, expecting newline or OPTIONAL error: script-syntax-error.link(2): syntax error, unexpected ORG, expecting newline or OPTIONAL
error: script-syntax-error.link(5): syntax error, unexpected string, expecting newline or number error: script-syntax-error.link(5): syntax error, unexpected string, expecting newline or FLOATING or number
Linking failed with 2 errors Linking failed with 2 errors