mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Write some doc comments
This commit is contained in:
@@ -14,8 +14,15 @@
|
|||||||
|
|
||||||
#include "link/section.h"
|
#include "link/section.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a section for output.
|
||||||
|
* @param section The section to add
|
||||||
|
*/
|
||||||
void out_AddSection(struct Section const *section);
|
void out_AddSection(struct Section const *section);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes all output (bin, sym, map) files.
|
||||||
|
*/
|
||||||
void out_WriteFiles(void);
|
void out_WriteFiles(void);
|
||||||
|
|
||||||
#endif /* RGBDS_LINK_OUTPUT_H */
|
#endif /* RGBDS_LINK_OUTPUT_H */
|
||||||
|
|||||||
@@ -104,6 +104,15 @@ static inline void assignSection(struct Section *section,
|
|||||||
out_AddSection(section);
|
out_AddSection(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a given location is suitable for placing a given section
|
||||||
|
* This checks not only that the location has enough room for the section, but
|
||||||
|
* also that the constraints (alignment...) are respected.
|
||||||
|
* @param section The section to be placed
|
||||||
|
* @param freeSpace The candidate free space to place the section into
|
||||||
|
* @param location The location to attempt placing the section at
|
||||||
|
* @return True if the location is suitable, false otherwise.
|
||||||
|
*/
|
||||||
static bool isLocationSuitable(struct Section const *section,
|
static bool isLocationSuitable(struct Section const *section,
|
||||||
struct FreeSpace const *freeSpace,
|
struct FreeSpace const *freeSpace,
|
||||||
struct MemoryLocation const *location)
|
struct MemoryLocation const *location)
|
||||||
@@ -118,6 +127,13 @@ static bool isLocationSuitable(struct Section const *section,
|
|||||||
<= freeSpace->address + freeSpace->size;
|
<= freeSpace->address + freeSpace->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a suitable location to place a section at.
|
||||||
|
* @param section The section to be placed
|
||||||
|
* @param location A pointer to a location struct that will be filled
|
||||||
|
* @return A pointer to the free space encompassing the location, or NULL if
|
||||||
|
* none was found
|
||||||
|
*/
|
||||||
static struct FreeSpace *getPlacement(struct Section const *section,
|
static struct FreeSpace *getPlacement(struct Section const *section,
|
||||||
struct MemoryLocation *location)
|
struct MemoryLocation *location)
|
||||||
{
|
{
|
||||||
@@ -177,9 +193,16 @@ static struct FreeSpace *getPlacement(struct Section const *section,
|
|||||||
location->bank++;
|
location->bank++;
|
||||||
if (location->bank > bankranges[section->type][1])
|
if (location->bank > bankranges[section->type][1])
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#undef BANK_INDEX
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places a section in a suitable location, or error out if it fails to.
|
||||||
|
* @warning Due to the implemented algorithm, this should be called with
|
||||||
|
* sections of decreasing size.
|
||||||
|
* @param section The section to place
|
||||||
|
*/
|
||||||
static void placeSection(struct Section *section)
|
static void placeSection(struct Section *section)
|
||||||
{
|
{
|
||||||
struct MemoryLocation location;
|
struct MemoryLocation location;
|
||||||
@@ -293,6 +316,12 @@ struct UnassignedSection {
|
|||||||
static struct UnassignedSection *unassignedSections[1 << 3] = {0};
|
static struct UnassignedSection *unassignedSections[1 << 3] = {0};
|
||||||
static struct UnassignedSection *sections;
|
static struct UnassignedSection *sections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Categorize a section depending on how constrained it is
|
||||||
|
* This is so the most-constrained sections are placed first
|
||||||
|
* @param section The section to categorize
|
||||||
|
* @param arg Callback arg, unused
|
||||||
|
*/
|
||||||
static void categorizeSection(struct Section *section, void *arg)
|
static void categorizeSection(struct Section *section, void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|||||||
@@ -145,6 +145,12 @@ static char *readstr(FILE *file)
|
|||||||
|
|
||||||
/***** Functions to parse object files *****/
|
/***** Functions to parse object files *****/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a RGB6 symbol from a file.
|
||||||
|
* @param file The file to read from
|
||||||
|
* @param symbol The struct to fill
|
||||||
|
* @param fileName The filename to report in errors
|
||||||
|
*/
|
||||||
static void readSymbol(FILE *file, struct Symbol *symbol, char const *fileName)
|
static void readSymbol(FILE *file, struct Symbol *symbol, char const *fileName)
|
||||||
{
|
{
|
||||||
tryReadstr(symbol->name, file, "%s: Cannot read symbol name: %s",
|
tryReadstr(symbol->name, file, "%s: Cannot read symbol name: %s",
|
||||||
@@ -171,6 +177,13 @@ static void readSymbol(FILE *file, struct Symbol *symbol, char const *fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a RGB6 patch from a file.
|
||||||
|
* @param file The file to read from
|
||||||
|
* @param patch The struct to fill
|
||||||
|
* @param fileName The filename to report in errors
|
||||||
|
* @param i The number of the patch to report in errors
|
||||||
|
*/
|
||||||
static void readPatch(FILE *file, struct Patch *patch,
|
static void readPatch(FILE *file, struct Patch *patch,
|
||||||
char const *fileName, char const *sectName, uint32_t i)
|
char const *fileName, char const *sectName, uint32_t i)
|
||||||
{
|
{
|
||||||
@@ -201,6 +214,12 @@ static void readPatch(FILE *file, struct Patch *patch,
|
|||||||
patch->rpnExpression = rpnExpression;
|
patch->rpnExpression = rpnExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a RGB6 section from a file.
|
||||||
|
* @param file The file to read from
|
||||||
|
* @param section The struct to fill
|
||||||
|
* @param fileName The filename to report in errors
|
||||||
|
*/
|
||||||
static void readSection(FILE *file, struct Section *section,
|
static void readSection(FILE *file, struct Section *section,
|
||||||
char const *fileName)
|
char const *fileName)
|
||||||
{
|
{
|
||||||
@@ -266,6 +285,11 @@ static void readSection(FILE *file, struct Section *section,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Links a symbol to a section, keeping the section's symbol list sorted.
|
||||||
|
* @param symbol The symbol to link
|
||||||
|
* @param section The section to link
|
||||||
|
*/
|
||||||
static void linkSymToSect(struct Symbol const *symbol, struct Section *section)
|
static void linkSymToSect(struct Symbol const *symbol, struct Section *section)
|
||||||
{
|
{
|
||||||
uint32_t a = 0, b = section->nbSymbols;
|
uint32_t a = 0, b = section->nbSymbols;
|
||||||
@@ -290,6 +314,11 @@ static void linkSymToSect(struct Symbol const *symbol, struct Section *section)
|
|||||||
section->nbSymbols++;
|
section->nbSymbols++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a RGB6 object file.
|
||||||
|
* @param file The file to read from
|
||||||
|
* @param fileName The filename to report in errors
|
||||||
|
*/
|
||||||
static void readRGB6File(FILE *file, char const *fileName)
|
static void readRGB6File(FILE *file, char const *fileName)
|
||||||
{
|
{
|
||||||
uint32_t nbSymbols;
|
uint32_t nbSymbols;
|
||||||
@@ -378,6 +407,10 @@ static void readRGB6File(FILE *file, char const *fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads an object file of any supported format
|
||||||
|
* @param fileName The filename to report for errors
|
||||||
|
*/
|
||||||
void obj_ReadFile(char const *fileName)
|
void obj_ReadFile(char const *fileName)
|
||||||
{
|
{
|
||||||
FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin;
|
FILE *file = strcmp("-", fileName) ? fopen(fileName, "rb") : stdin;
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ void out_AddSection(struct Section const *section)
|
|||||||
*ptr = newSection;
|
*ptr = newSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs sanity checks on the overlay file.
|
||||||
|
*/
|
||||||
static void checkOverlay(void)
|
static void checkOverlay(void)
|
||||||
{
|
{
|
||||||
if (!overlayFile)
|
if (!overlayFile)
|
||||||
@@ -88,6 +91,9 @@ static void checkOverlay(void)
|
|||||||
if (overlaySize % 0x4000)
|
if (overlaySize % 0x4000)
|
||||||
errx(1, "Overlay file must have a size multiple of 0x4000");
|
errx(1, "Overlay file must have a size multiple of 0x4000");
|
||||||
|
|
||||||
|
/* Reset back to beginning */
|
||||||
|
fseek(overlayFile, 0, SEEK_SET);
|
||||||
|
|
||||||
uint32_t nbOverlayBanks = overlaySize / 0x4000 - 1;
|
uint32_t nbOverlayBanks = overlaySize / 0x4000 - 1;
|
||||||
|
|
||||||
if (nbOverlayBanks < 1)
|
if (nbOverlayBanks < 1)
|
||||||
@@ -104,6 +110,12 @@ static void checkOverlay(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a ROM bank's sections to the output file.
|
||||||
|
* @param bankSections The bank's sections, ordered by increasing address
|
||||||
|
* @param baseOffset The address of the bank's first byte in GB address space
|
||||||
|
* @param size The size of the bank
|
||||||
|
*/
|
||||||
static void writeBank(struct SortedSection *bankSections, uint16_t baseOffset,
|
static void writeBank(struct SortedSection *bankSections, uint16_t baseOffset,
|
||||||
uint16_t size)
|
uint16_t size)
|
||||||
{
|
{
|
||||||
@@ -141,6 +153,9 @@ static void writeBank(struct SortedSection *bankSections, uint16_t baseOffset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a ROM file to the output.
|
||||||
|
*/
|
||||||
static void writeROM(void)
|
static void writeROM(void)
|
||||||
{
|
{
|
||||||
checkOverlay();
|
checkOverlay();
|
||||||
@@ -164,6 +179,12 @@ static void writeROM(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lowest section by address out of the two
|
||||||
|
* @param s1 One choice
|
||||||
|
* @param s2 The other
|
||||||
|
* @return The lowest section of the two, or the non-NULL one if applicable
|
||||||
|
*/
|
||||||
static struct SortedSection const **nextSection(struct SortedSection const **s1,
|
static struct SortedSection const **nextSection(struct SortedSection const **s1,
|
||||||
struct SortedSection const **s2)
|
struct SortedSection const **s2)
|
||||||
{
|
{
|
||||||
@@ -175,6 +196,10 @@ static struct SortedSection const **nextSection(struct SortedSection const **s1,
|
|||||||
return (*s1)->section->org < (*s2)->section->org ? s1 : s2;
|
return (*s1)->section->org < (*s2)->section->org ? s1 : s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a bank's contents to the sym file
|
||||||
|
* @param bankSections The bank's sections
|
||||||
|
*/
|
||||||
static void writeSymBank(struct SortedSections const *bankSections)
|
static void writeSymBank(struct SortedSections const *bankSections)
|
||||||
{
|
{
|
||||||
if (!symFile)
|
if (!symFile)
|
||||||
@@ -236,6 +261,10 @@ static void writeSymBank(struct SortedSections const *bankSections)
|
|||||||
#undef sect
|
#undef sect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a bank's contents to the map file
|
||||||
|
* @param bankSections The bank's sections
|
||||||
|
*/
|
||||||
static void writeMapBank(struct SortedSections const *sectList,
|
static void writeMapBank(struct SortedSections const *sectList,
|
||||||
enum SectionType type, uint32_t bank)
|
enum SectionType type, uint32_t bank)
|
||||||
{
|
{
|
||||||
@@ -276,6 +305,9 @@ static void writeMapBank(struct SortedSections const *sectList,
|
|||||||
slack == 1 ? "" : "s");
|
slack == 1 ? "" : "s");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the sym and/or map files, if applicable.
|
||||||
|
*/
|
||||||
static void writeSymAndMap(void)
|
static void writeSymAndMap(void)
|
||||||
{
|
{
|
||||||
if (!symFile && !mapFile)
|
if (!symFile && !mapFile)
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ static uint8_t getRPNByte(uint8_t const **expression, int32_t *size,
|
|||||||
return *(*expression)++;
|
return *(*expression)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a patch's value from its RPN string.
|
||||||
|
* @param patch The patch to compute the value of
|
||||||
|
* @param section The section the patch is contained in
|
||||||
|
* @return The patch's value
|
||||||
|
*/
|
||||||
static int32_t computeRPNExpr(struct Patch const *patch,
|
static int32_t computeRPNExpr(struct Patch const *patch,
|
||||||
struct Section const *section)
|
struct Section const *section)
|
||||||
{
|
{
|
||||||
@@ -272,6 +278,11 @@ static int32_t computeRPNExpr(struct Patch const *patch,
|
|||||||
return popRPN();
|
return popRPN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies all of a section's patches
|
||||||
|
* @param section The section to patch
|
||||||
|
* @param arg Ignored callback arg
|
||||||
|
*/
|
||||||
static void applyPatches(struct Section *section, void *arg)
|
static void applyPatches(struct Section *section, void *arg)
|
||||||
{
|
{
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ static inline bool isNewline(int c)
|
|||||||
return c == '\r' || c == '\n';
|
return c == '\r' || c == '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try parsing a number, in base 16 if it begins with a dollar,
|
||||||
|
* in base 10 otherwise
|
||||||
|
* @param str The number to parse
|
||||||
|
* @param number A pointer where the number will be written to
|
||||||
|
* @return True if parsing was successful, false otherwise
|
||||||
|
*/
|
||||||
static bool tryParseNumber(char const *str, uint32_t *number)
|
static bool tryParseNumber(char const *str, uint32_t *number)
|
||||||
{
|
{
|
||||||
static char const digits[] = {
|
static char const digits[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user