ref: c878ff8775ddf9c31877e52fdc3ded3762df860c
parent: a4049a3f1b58bbc699b86808bb2fe6dcb692fefc
author: Rangi <[email protected]>
date: Fri Mar 5 00:53:27 EST 2021
Report slack totals at the end of the .map file (#781) Fixes #777
--- a/src/link/output.c
+++ b/src/link/output.c
@@ -19,6 +19,8 @@
#include "linkdefs.h"
+#include "platform.h" // MIN_NB_ELMS
+
#define BANK_SIZE 0x4000
FILE *outputFile;
@@ -39,6 +41,18 @@
} *banks;
} sections[SECTTYPE_INVALID];
+/* Defines the order in which types are output to the sym and map files */
+static enum SectionType typeMap[SECTTYPE_INVALID] = {
+ SECTTYPE_ROM0,
+ SECTTYPE_ROMX,
+ SECTTYPE_VRAM,
+ SECTTYPE_SRAM,
+ SECTTYPE_WRAM0,
+ SECTTYPE_WRAMX,
+ SECTTYPE_OAM,
+ SECTTYPE_HRAM
+};
+
void out_AddSection(struct Section const *section)
{
static uint32_t maxNbBanks[] = {
@@ -64,8 +78,7 @@
sections[section->type].banks =
realloc(sections[section->type].banks,
sizeof(*sections[0].banks) * minNbBanks);
- for (uint32_t i = sections[section->type].nbBanks;
- i < minNbBanks; i++) {
+ for (uint32_t i = sections[section->type].nbBanks; i < minNbBanks; i++) {
sections[section->type].banks[i].sections = NULL;
sections[section->type].banks[i].zeroLenSections = NULL;
}
@@ -323,12 +336,13 @@
/**
* Write a bank's contents to the map file
* @param bankSections The bank's sections
+ * @return The bank's slack space
*/
-static void writeMapBank(struct SortedSections const *sectList,
- enum SectionType type, uint32_t bank)
+static uint16_t writeMapBank(struct SortedSections const *sectList,
+ enum SectionType type, uint32_t bank)
{
if (!mapFile)
- return;
+ return 0;
struct SortedSection const *section = sectList->sections;
struct SortedSection const *zeroLenSection = sectList->zeroLenSections;
@@ -367,9 +381,37 @@
else
fprintf(mapFile, " SLACK: $%04" PRIx16 " byte%s\n\n", slack,
slack == 1 ? "" : "s");
+
+ return slack;
}
/**
+ * Write the total slack space by section type to the map file
+ * @param slackMap The total slack space by section type
+ */
+static void writeMapSlack(uint32_t slackMap[MIN_NB_ELMS(SECTTYPE_INVALID)])
+{
+ if (!mapFile)
+ return;
+
+ fputs("FREE:\n", mapFile);
+
+ for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
+ enum SectionType type = typeMap[i];
+
+ // Do not output slack space for VRAM or OAM
+ if (type == SECTTYPE_VRAM || type == SECTTYPE_OAM)
+ continue;
+
+ if (sections[type].nbBanks > 0) {
+ fprintf(mapFile, " %s: $%04" PRIx32 " byte%s in %" PRIu32 " bank%s\n",
+ typeNames[type], slackMap[type], slackMap[type] == 1 ? "" : "s",
+ sections[type].nbBanks, sections[type].nbBanks == 1 ? "" : "s");
+ }
+ }
+}
+
+/**
* Writes the sym and/or map files, if applicable.
*/
static void writeSymAndMap(void)
@@ -377,16 +419,7 @@
if (!symFileName && !mapFileName)
return;
- enum SectionType typeMap[SECTTYPE_INVALID] = {
- SECTTYPE_ROM0,
- SECTTYPE_ROMX,
- SECTTYPE_VRAM,
- SECTTYPE_SRAM,
- SECTTYPE_WRAM0,
- SECTTYPE_WRAMX,
- SECTTYPE_OAM,
- SECTTYPE_HRAM
- };
+ uint32_t slackMap[SECTTYPE_INVALID] = {0};
symFile = openFile(symFileName, "w");
mapFile = openFile(mapFileName, "w");
@@ -397,15 +430,15 @@
for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) {
enum SectionType type = typeMap[i];
- if (sections[type].nbBanks > 0) {
- for (uint32_t bank = 0; bank < sections[type].nbBanks;
- bank++) {
- writeSymBank(§ions[type].banks[bank]);
- writeMapBank(§ions[type].banks[bank],
- type, bank);
- }
+ for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) {
+ struct SortedSections const *sect = §ions[type].banks[bank];
+
+ writeSymBank(sect);
+ slackMap[type] += writeMapBank(sect, type, bank);
}
}
+
+ writeMapSlack(slackMap);
closeFile(symFile);
closeFile(mapFile);