mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 10:42:07 +00:00
Make RGBLINK able to link SDCC object files
This requires a LOT of tricky code, mostly due to the format itself being, er, not the most straightforward. Everything is converted to existing RGBLINK concepts (sections, patches, etc.), so the core code is essentially unchanged. (A couple of genuine RGBLINK bugs were uncovered along the way, so some of the core code *is* changed, notably regarding `SECTION FRAGMENT`s.) All of this code was clean-roomed, so SDCC's GPLv2 license does not apply.
This commit is contained in:
@@ -365,8 +365,7 @@ static enum LinkerScriptParserState parserState = PARSER_FIRSTTIME;
|
||||
|
||||
struct SectionPlacement *script_NextSection(void)
|
||||
{
|
||||
static struct SectionPlacement section;
|
||||
static enum SectionType type;
|
||||
static struct SectionPlacement placement;
|
||||
static uint32_t bank;
|
||||
static uint32_t bankID;
|
||||
|
||||
@@ -380,7 +379,7 @@ struct SectionPlacement *script_NextSection(void)
|
||||
curaddr[i][b] = startaddr[i];
|
||||
}
|
||||
|
||||
type = SECTTYPE_INVALID;
|
||||
placement.type = SECTTYPE_INVALID;
|
||||
|
||||
parserState = PARSER_LINESTART;
|
||||
}
|
||||
@@ -392,15 +391,15 @@ struct SectionPlacement *script_NextSection(void)
|
||||
bool hasArg;
|
||||
uint32_t arg;
|
||||
|
||||
if (type != SECTTYPE_INVALID) {
|
||||
if (curaddr[type][bankID] > endaddr(type) + 1)
|
||||
if (placement.type != SECTTYPE_INVALID) {
|
||||
if (curaddr[placement.type][bankID] > endaddr(placement.type) + 1)
|
||||
errx("%s(%" PRIu32 "): Sections would extend past the end of %s ($%04" PRIx16 " > $%04" PRIx16 ")",
|
||||
linkerScriptName, lineNo, typeNames[type],
|
||||
curaddr[type][bankID], endaddr(type));
|
||||
if (curaddr[type][bankID] < startaddr[type])
|
||||
linkerScriptName, lineNo, typeNames[placement.type],
|
||||
curaddr[placement.type][bankID], endaddr(placement.type));
|
||||
if (curaddr[placement.type][bankID] < startaddr[placement.type])
|
||||
errx("%s(%" PRIu32 "): PC underflowed ($%04" PRIx16 " < $%04" PRIx16 ")",
|
||||
linkerScriptName, lineNo,
|
||||
curaddr[type][bankID], startaddr[type]);
|
||||
curaddr[placement.type][bankID], startaddr[placement.type]);
|
||||
}
|
||||
|
||||
switch (parserState) {
|
||||
@@ -431,21 +430,21 @@ struct SectionPlacement *script_NextSection(void)
|
||||
case TOKEN_STRING:
|
||||
parserState = PARSER_LINEEND;
|
||||
|
||||
if (type == SECTTYPE_INVALID)
|
||||
if (placement.type == SECTTYPE_INVALID)
|
||||
errx("%s(%" PRIu32 "): Didn't specify a location before the section",
|
||||
linkerScriptName, lineNo);
|
||||
|
||||
section.section =
|
||||
placement.section =
|
||||
sect_GetSection(token->attr.string);
|
||||
if (!section.section)
|
||||
if (!placement.section)
|
||||
errx("%s(%" PRIu32 "): Unknown section \"%s\"",
|
||||
linkerScriptName, lineNo,
|
||||
token->attr.string);
|
||||
section.org = curaddr[type][bankID];
|
||||
section.bank = bank;
|
||||
placement.org = curaddr[placement.type][bankID];
|
||||
placement.bank = bank;
|
||||
|
||||
curaddr[type][bankID] += section.section->size;
|
||||
return §ion;
|
||||
curaddr[placement.type][bankID] += placement.section->size;
|
||||
return &placement;
|
||||
|
||||
case TOKEN_COMMAND:
|
||||
case TOKEN_BANK:
|
||||
@@ -466,35 +465,35 @@ struct SectionPlacement *script_NextSection(void)
|
||||
arg = hasArg ? token->attr.number : 0;
|
||||
|
||||
if (tokType == TOKEN_COMMAND) {
|
||||
if (type == SECTTYPE_INVALID)
|
||||
if (placement.type == SECTTYPE_INVALID)
|
||||
errx("%s(%" PRIu32 "): Didn't specify a location before the command",
|
||||
linkerScriptName, lineNo);
|
||||
if (!hasArg)
|
||||
errx("%s(%" PRIu32 "): Command specified without an argument",
|
||||
linkerScriptName, lineNo);
|
||||
|
||||
processCommand(attr.command, arg, &curaddr[type][bankID]);
|
||||
processCommand(attr.command, arg, &curaddr[placement.type][bankID]);
|
||||
} else { /* TOKEN_BANK */
|
||||
type = attr.secttype;
|
||||
placement.type = attr.secttype;
|
||||
/*
|
||||
* If there's only one bank,
|
||||
* specifying the number is optional.
|
||||
*/
|
||||
if (!hasArg && nbbanks(type) != 1)
|
||||
if (!hasArg && nbbanks(placement.type) != 1)
|
||||
errx("%s(%" PRIu32 "): Didn't specify a bank number",
|
||||
linkerScriptName, lineNo);
|
||||
else if (!hasArg)
|
||||
arg = bankranges[type][0];
|
||||
else if (arg < bankranges[type][0])
|
||||
arg = bankranges[placement.type][0];
|
||||
else if (arg < bankranges[placement.type][0])
|
||||
errx("%s(%" PRIu32 "): specified bank number is too low (%" PRIu32 " < %" PRIu32 ")",
|
||||
linkerScriptName, lineNo,
|
||||
arg, bankranges[type][0]);
|
||||
else if (arg > bankranges[type][1])
|
||||
arg, bankranges[placement.type][0]);
|
||||
else if (arg > bankranges[placement.type][1])
|
||||
errx("%s(%" PRIu32 "): specified bank number is too high (%" PRIu32 " > %" PRIu32 ")",
|
||||
linkerScriptName, lineNo,
|
||||
arg, bankranges[type][1]);
|
||||
arg, bankranges[placement.type][1]);
|
||||
bank = arg;
|
||||
bankID = arg - bankranges[type][0];
|
||||
bankID = arg - bankranges[placement.type][0];
|
||||
}
|
||||
|
||||
/* If we read a token we shouldn't have... */
|
||||
|
||||
Reference in New Issue
Block a user