Skip to content

Commit 9ec8186

Browse files
committed
Switch linkdefs from scattered arrays to an array of structs
The info is better organized this way
1 parent ab9945c commit 9ec8186

File tree

8 files changed

+149
-143
lines changed

8 files changed

+149
-143
lines changed

include/linkdefs.h

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,14 @@ enum SectionType {
7979
SECTTYPE_INVALID
8080
};
8181

82-
enum SectionModifier {
83-
SECTION_NORMAL,
84-
SECTION_UNION,
85-
SECTION_FRAGMENT
86-
};
87-
88-
extern char const * const sectionModNames[];
82+
// Nont-`const` members may be patched in RGBLINK depending on CLI flags
83+
extern struct SectionTypeInfo {
84+
char const *const name;
85+
uint16_t const startAddr;
86+
uint16_t size;
87+
uint32_t const firstBank;
88+
uint32_t lastBank;
89+
} sectionTypeInfo[SECTTYPE_INVALID];
8990

9091
/**
9192
* Tells whether a section has data in its object file definition,
@@ -99,49 +100,13 @@ static inline bool sect_HasData(enum SectionType type)
99100
return type == SECTTYPE_ROM0 || type == SECTTYPE_ROMX;
100101
}
101102

102-
enum ExportLevel {
103-
SYMTYPE_LOCAL,
104-
SYMTYPE_IMPORT,
105-
SYMTYPE_EXPORT
106-
};
107-
108-
enum PatchType {
109-
PATCHTYPE_BYTE,
110-
PATCHTYPE_WORD,
111-
PATCHTYPE_LONG,
112-
PATCHTYPE_JR,
113-
114-
PATCHTYPE_INVALID
115-
};
116-
117-
#define BANK_MIN_ROM0 0
118-
#define BANK_MAX_ROM0 0
119-
#define BANK_MIN_ROMX 1
120-
#define BANK_MAX_ROMX 511
121-
#define BANK_MIN_VRAM 0
122-
#define BANK_MAX_VRAM 1
123-
#define BANK_MIN_SRAM 0
124-
#define BANK_MAX_SRAM 15
125-
#define BANK_MIN_WRAM0 0
126-
#define BANK_MAX_WRAM0 0
127-
#define BANK_MIN_WRAMX 1
128-
#define BANK_MAX_WRAMX 7
129-
#define BANK_MIN_OAM 0
130-
#define BANK_MAX_OAM 0
131-
#define BANK_MIN_HRAM 0
132-
#define BANK_MAX_HRAM 0
133-
134-
extern uint16_t startaddr[];
135-
extern uint16_t maxsize[];
136-
extern uint32_t bankranges[][2];
137-
138103
/**
139104
* Computes a memory region's end address (last byte), eg. 0x7FFF
140105
* @return The address of the last byte in that memory region
141106
*/
142107
static inline uint16_t endaddr(enum SectionType type)
143108
{
144-
return startaddr[type] + maxsize[type] - 1;
109+
return sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size - 1;
145110
}
146111

147112
/**
@@ -150,9 +115,30 @@ static inline uint16_t endaddr(enum SectionType type)
150115
*/
151116
static inline uint32_t nbbanks(enum SectionType type)
152117
{
153-
return bankranges[type][1] - bankranges[type][0] + 1;
118+
return sectionTypeInfo[type].lastBank - sectionTypeInfo[type].firstBank + 1;
154119
}
155120

156-
extern char const * const typeNames[SECTTYPE_INVALID];
121+
enum SectionModifier {
122+
SECTION_NORMAL,
123+
SECTION_UNION,
124+
SECTION_FRAGMENT
125+
};
126+
127+
extern char const * const sectionModNames[];
128+
129+
enum ExportLevel {
130+
SYMTYPE_LOCAL,
131+
SYMTYPE_IMPORT,
132+
SYMTYPE_EXPORT
133+
};
134+
135+
enum PatchType {
136+
PATCHTYPE_BYTE,
137+
PATCHTYPE_WORD,
138+
PATCHTYPE_LONG,
139+
PATCHTYPE_JR,
140+
141+
PATCHTYPE_INVALID
142+
};
157143

158144
#endif /* RGBDS_LINKDEFS_H */

src/asm/section.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "asm/warning.h"
1717

1818
#include "error.h"
19+
#include "linkdefs.h"
1920
#include "platform.h" // strdup
2021

2122
uint8_t fillByte;
@@ -73,7 +74,7 @@ attr_(warn_unused_result) static bool checkcodesection(void)
7374

7475
attr_(warn_unused_result) static bool checkSectionSize(struct Section const *sect, uint32_t size)
7576
{
76-
uint32_t maxSize = maxsize[sect->type];
77+
uint32_t maxSize = sectionTypeInfo[sect->type].size;
7778

7879
// If the new size is reasonable, keep going
7980
if (size <= maxSize)
@@ -232,7 +233,7 @@ static void mergeSections(struct Section *sect, enum SectionType type, uint32_t
232233
unsigned int nbSectErrors = 0;
233234

234235
if (type != sect->type)
235-
fail("Section already exists but with type %s\n", typeNames[sect->type]);
236+
fail("Section already exists but with type %s\n", sectionTypeInfo[sect->type].name);
236237

237238
if (sect->modifier != mod) {
238239
fail("Section already declared as %s section\n", sectionModNames[sect->modifier]);
@@ -299,7 +300,7 @@ static struct Section *createSection(char const *name, enum SectionType type,
299300

300301
/* It is only needed to allocate memory for ROM sections. */
301302
if (sect_HasData(type)) {
302-
sect->data = malloc(maxsize[type]);
303+
sect->data = malloc(sectionTypeInfo[type].size);
303304
if (sect->data == NULL)
304305
fatalerror("Not enough memory for section: %s\n", strerror(errno));
305306
} else {
@@ -325,14 +326,13 @@ static struct Section *getSection(char const *name, enum SectionType type, uint3
325326
if (type != SECTTYPE_ROMX && type != SECTTYPE_VRAM
326327
&& type != SECTTYPE_SRAM && type != SECTTYPE_WRAMX)
327328
error("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections\n");
328-
else if (bank < bankranges[type][0]
329-
|| bank > bankranges[type][1])
329+
else if (bank < sectionTypeInfo[type].firstBank || bank > sectionTypeInfo[type].lastBank)
330330
error("%s bank value $%04" PRIx32 " out of range ($%04" PRIx32 " to $%04"
331-
PRIx32 ")\n", typeNames[type], bank,
332-
bankranges[type][0], bankranges[type][1]);
331+
PRIx32 ")\n", sectionTypeInfo[type].name, bank,
332+
sectionTypeInfo[type].firstBank, sectionTypeInfo[type].lastBank);
333333
} else if (nbbanks(type) == 1) {
334334
// If the section type only has a single bank, implicitly force it
335-
bank = bankranges[type][0];
335+
bank = sectionTypeInfo[type].firstBank;
336336
}
337337

338338
if (alignOffset >= 1 << alignment) {
@@ -342,10 +342,10 @@ static struct Section *getSection(char const *name, enum SectionType type, uint3
342342
}
343343

344344
if (org != (uint32_t)-1) {
345-
if (org < startaddr[type] || org > endaddr(type))
345+
if (org < sectionTypeInfo[type].startAddr || org > endaddr(type))
346346
error("Section \"%s\"'s fixed address %#" PRIx32
347347
" is outside of range [%#" PRIx16 "; %#" PRIx16 "]\n",
348-
name, org, startaddr[type], endaddr(type));
348+
name, org, sectionTypeInfo[type].startAddr, endaddr(type));
349349
}
350350

351351
if (alignment != 0) {
@@ -361,9 +361,9 @@ static struct Section *getSection(char const *name, enum SectionType type, uint3
361361
error("Section \"%s\"'s fixed address doesn't match its alignment\n",
362362
name);
363363
alignment = 0; /* Ignore it if it's satisfied */
364-
} else if (startaddr[type] & mask) {
364+
} else if (sectionTypeInfo[type].startAddr & mask) {
365365
error("Section \"%s\"'s alignment cannot be attained in %s\n",
366-
name, typeNames[type]);
366+
name, sectionTypeInfo[type].name);
367367
alignment = 0; /* Ignore it if it's unattainable */
368368
org = 0;
369369
} else if (alignment == 16) {

src/link/assign.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "error.h"
2323
#include "helpers.h"
24+
#include "linkdefs.h"
2425

2526
struct MemoryLocation {
2627
uint16_t address;
@@ -54,8 +55,8 @@ static void initFreeSpace(void)
5455
if (!memory[type][bank].next)
5556
err("Failed to init free space for region %d bank %" PRIu32,
5657
type, bank);
57-
memory[type][bank].next->address = startaddr[type];
58-
memory[type][bank].next->size = maxsize[type];
58+
memory[type][bank].next->address = sectionTypeInfo[type].startAddr;
59+
memory[type][bank].next->size = sectionTypeInfo[type].size;
5960
memory[type][bank].next->next = NULL;
6061
memory[type][bank].next->prev = &memory[type][bank];
6162
}
@@ -140,13 +141,13 @@ static struct FreeSpace *getPlacement(struct Section const *section,
140141
if (curScrambleSRAM > scrambleSRAM)
141142
curScrambleSRAM = 0;
142143
} else {
143-
location->bank = bankranges[section->type][0];
144+
location->bank = sectionTypeInfo[section->type].firstBank;
144145
}
145146
struct FreeSpace *space;
146147

147148
for (;;) {
148149
/* Switch to the beginning of the next bank */
149-
#define BANK_INDEX (location->bank - bankranges[section->type][0])
150+
#define BANK_INDEX (location->bank - sectionTypeInfo[section->type].firstBank)
150151
space = memory[section->type][BANK_INDEX].next;
151152
if (space)
152153
location->address = space->address;
@@ -201,7 +202,7 @@ static struct FreeSpace *getPlacement(struct Section const *section,
201202

202203
/* Try again in the next bank */
203204
location->bank++;
204-
if (location->bank > bankranges[section->type][1])
205+
if (location->bank > sectionTypeInfo[section->type].lastBank)
205206
return NULL;
206207
#undef BANK_INDEX
207208
}
@@ -225,10 +226,10 @@ static void placeSection(struct Section *section)
225226
*/
226227
location.address = section->isAddressFixed
227228
? section->org
228-
: startaddr[section->type];
229+
: sectionTypeInfo[section->type].startAddr;
229230
location.bank = section->isBankFixed
230231
? section->bank
231-
: bankranges[section->type][0];
232+
: sectionTypeInfo[section->type].firstBank;
232233
assignSection(section, &location);
233234
return;
234235
}
@@ -314,16 +315,16 @@ static void placeSection(struct Section *section)
314315
/* If a section failed to go to several places, nothing we can report */
315316
if (!section->isBankFixed || !section->isAddressFixed)
316317
errx("Unable to place \"%s\" (%s section) %s",
317-
section->name, typeNames[section->type], where);
318+
section->name, sectionTypeInfo[section->type].name, where);
318319
/* If the section just can't fit the bank, report that */
319320
else if (section->org + section->size > endaddr(section->type) + 1)
320321
errx("Unable to place \"%s\" (%s section) %s: section runs past end of region ($%04x > $%04x)",
321-
section->name, typeNames[section->type], where,
322+
section->name, sectionTypeInfo[section->type].name, where,
322323
section->org + section->size, endaddr(section->type) + 1);
323324
/* Otherwise there is overlap with another section */
324325
else
325326
errx("Unable to place \"%s\" (%s section) %s: section overlaps with \"%s\"",
326-
section->name, typeNames[section->type], where,
327+
section->name, sectionTypeInfo[section->type].name, where,
327328
out_OverlappingSection(section)->name);
328329
}
329330

src/link/main.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,13 +440,13 @@ int main(int argc, char *argv[])
440440

441441
/* Patch the size array depending on command-line options */
442442
if (!is32kMode)
443-
maxsize[SECTTYPE_ROM0] = 0x4000;
443+
sectionTypeInfo[SECTTYPE_ROM0].size = 0x4000;
444444
if (!isWRA0Mode)
445-
maxsize[SECTTYPE_WRAM0] = 0x1000;
445+
sectionTypeInfo[SECTTYPE_WRAM0].size = 0x1000;
446446

447447
/* Patch the bank ranges array depending on command-line options */
448448
if (isDmgMode)
449-
bankranges[SECTTYPE_VRAM][1] = BANK_MIN_VRAM;
449+
sectionTypeInfo[SECTTYPE_VRAM].lastBank = 0;
450450

451451
/* Read all object files first, */
452452
for (obj_Setup(argc - curArgIndex); curArgIndex < argc; curArgIndex++)

src/link/output.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void out_AddSection(struct Section const *section)
7272
[SECTTYPE_HRAM] = 1
7373
};
7474

75-
uint32_t targetBank = section->bank - bankranges[section->type][0];
75+
uint32_t targetBank = section->bank - sectionTypeInfo[section->type].firstBank;
7676
uint32_t minNbBanks = targetBank + 1;
7777

7878
if (minNbBanks > maxNbBanks[section->type])
@@ -113,7 +113,7 @@ struct Section const *out_OverlappingSection(struct Section const *section)
113113
{
114114
struct SortedSections *banks = sections[section->type].banks;
115115
struct SortedSection *ptr =
116-
banks[section->bank - bankranges[section->type][0]].sections;
116+
banks[section->bank - sectionTypeInfo[section->type].firstBank].sections;
117117

118118
while (ptr) {
119119
if (ptr->section->org < section->org + section->size
@@ -166,7 +166,7 @@ static uint32_t checkOverlaySize(void)
166166
static void coverOverlayBanks(uint32_t nbOverlayBanks)
167167
{
168168
/* 2 if is32kMode, 1 otherwise */
169-
uint32_t nbRom0Banks = maxsize[SECTTYPE_ROM0] / BANK_SIZE;
169+
uint32_t nbRom0Banks = sectionTypeInfo[SECTTYPE_ROM0].size / BANK_SIZE;
170170
/* Discount ROM0 banks to avoid outputting too much */
171171
uint32_t nbUncoveredBanks = nbOverlayBanks - nbRom0Banks > sections[SECTTYPE_ROMX].nbBanks
172172
? nbOverlayBanks - nbRom0Banks
@@ -247,11 +247,11 @@ static void writeROM(void)
247247
if (outputFile) {
248248
writeBank(sections[SECTTYPE_ROM0].banks ? sections[SECTTYPE_ROM0].banks[0].sections
249249
: NULL,
250-
startaddr[SECTTYPE_ROM0], maxsize[SECTTYPE_ROM0]);
250+
sectionTypeInfo[SECTTYPE_ROM0].startAddr, sectionTypeInfo[SECTTYPE_ROM0].size);
251251

252252
for (uint32_t i = 0 ; i < sections[SECTTYPE_ROMX].nbBanks; i++)
253253
writeBank(sections[SECTTYPE_ROMX].banks[i].sections,
254-
startaddr[SECTTYPE_ROMX], maxsize[SECTTYPE_ROMX]);
254+
sectionTypeInfo[SECTTYPE_ROMX].startAddr, sectionTypeInfo[SECTTYPE_ROMX].size);
255255
}
256256

257257
closeFile(outputFile);
@@ -345,7 +345,7 @@ static void writeSymBank(struct SortedSections const *bankSections,
345345

346346
qsort(symList, nbSymbols, sizeof(*symList), compareSymbols);
347347

348-
uint32_t symBank = bank + bankranges[type][0];
348+
uint32_t symBank = bank + sectionTypeInfo[type].firstBank;
349349

350350
for (uint32_t i = 0; i < nbSymbols; i++) {
351351
struct SortedSymbol *sym = &symList[i];
@@ -371,8 +371,8 @@ static uint16_t writeMapBank(struct SortedSections const *sectList,
371371
struct SortedSection const *section = sectList->sections;
372372
struct SortedSection const *zeroLenSection = sectList->zeroLenSections;
373373

374-
fprintf(mapFile, "%s bank #%" PRIu32 ":\n", typeNames[type],
375-
bank + bankranges[type][0]);
374+
fprintf(mapFile, "%s bank #%" PRIu32 ":\n", sectionTypeInfo[type].name,
375+
bank + sectionTypeInfo[type].firstBank);
376376

377377
uint16_t used = 0;
378378

@@ -413,7 +413,7 @@ static uint16_t writeMapBank(struct SortedSections const *sectList,
413413
if (used == 0) {
414414
fputs(" EMPTY\n\n", mapFile);
415415
} else {
416-
uint16_t slack = maxsize[type] - used;
416+
uint16_t slack = sectionTypeInfo[type].size - used;
417417

418418
fprintf(mapFile, " SLACK: $%04" PRIx16 " byte%s\n\n", slack,
419419
slack == 1 ? "" : "s");
@@ -442,7 +442,7 @@ static void writeMapUsed(uint32_t usedMap[MIN_NB_ELMS(SECTTYPE_INVALID)])
442442

443443
if (sections[type].nbBanks > 0) {
444444
fprintf(mapFile, " %s: $%04" PRIx32 " byte%s in %" PRIu32 " bank%s\n",
445-
typeNames[type], usedMap[type], usedMap[type] == 1 ? "" : "s",
445+
sectionTypeInfo[type].name, usedMap[type], usedMap[type] == 1 ? "" : "s",
446446
sections[type].nbBanks, sections[type].nbBanks == 1 ? "" : "s");
447447
}
448448
}

0 commit comments

Comments
 (0)