From 143e76b7e345c776b39cc9419b0521f396537269 Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Sun, 5 Nov 2023 09:43:58 -0500 Subject: [PATCH] Output the map file summary at the top of the file (#1203) --- src/gfx/main.cpp | 10 ++-- src/link/output.c | 142 +++++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 70 deletions(-) diff --git a/src/gfx/main.cpp b/src/gfx/main.cpp index ddf2a00f..0b37407f 100644 --- a/src/gfx/main.cpp +++ b/src/gfx/main.cpp @@ -679,7 +679,7 @@ int main(int argc, char *argv[]) { fprintf(stderr, "rgbgfx %s\n", get_package_version_string()); if (options.verbosity >= Options::VERB_VVVVVV) { - fputc('\n', stderr); + putc('\n', stderr); static std::array gfx{ 0x1FE, 0x3FF, 0x399, 0x399, 0x3FF, 0x3FF, 0x381, 0x3C3, 0x1FE, 0x078, 0x1FE, 0x3FF, 0x3FF, 0x3FF, 0x37B, 0x37B, 0x0FC, 0x0CC, 0x1CE, 0x1CE, 0x1CE, @@ -692,17 +692,17 @@ int main(int argc, char *argv[]) { uint16_t row = gfx[i]; for (uint8_t _ = 0; _ < 10; ++_) { unsigned char c = row & 1 ? '0' : ' '; - fputc(c, stderr); + putc(c, stderr); // Double the pixel horizontally, otherwise the aspect ratio looks wrong - fputc(c, stderr); + putc(c, stderr); row >>= 1; } if (i < textbox.size()) { fputs(textbox[i], stderr); } - fputc('\n', stderr); + putc('\n', stderr); } - fputc('\n', stderr); + putc('\n', stderr); } fputs("Options:\n", stderr); diff --git a/src/link/output.c b/src/link/output.c index 71f33bf9..7c3bee24 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -200,8 +200,7 @@ static void writeBank(struct SortedSection *bankSections, uint16_t baseOffset, assert(section->offset == 0); // Output padding up to the next SECTION while (offset + baseOffset < section->org) { - putc(overlayFile ? getc(overlayFile) : padValue, - outputFile); + putc(overlayFile ? getc(overlayFile) : padValue, outputFile); offset++; } @@ -220,9 +219,7 @@ static void writeBank(struct SortedSection *bankSections, uint16_t baseOffset, if (!disablePadding) { while (offset < size) { - putc(overlayFile ? getc(overlayFile) - : padValue, - outputFile); + putc(overlayFile ? getc(overlayFile) : padValue, outputFile); offset++; } } @@ -292,7 +289,7 @@ static void printSymName(char const *name) if (isLegalForSymName(c)) { // Output legal ASCII characters as-is - fputc(c, symFile); + putc(c, symFile); ++ptr; } else { // Output illegal characters using Unicode escapes @@ -357,9 +354,6 @@ static int compareSymbols(void const *a, void const *b) static void writeSymBank(struct SortedSections const *bankSections, enum SectionType type, uint32_t bank) { - if (!symFile) - return; - #define forEachSortedSection(sect, ...) do { \ for (struct SortedSection const *ssp = bankSections->zeroLenSections; ssp; ssp = ssp->next) { \ for (struct Section const *sect = ssp->section; sect; sect = sect->nextu) \ @@ -410,7 +404,7 @@ static void writeSymBank(struct SortedSections const *bankSections, fprintf(symFile, "%02" PRIx32 ":%04" PRIx16 " ", symBank, sym->addr); printSymName(sym->sym->name); - fputc('\n', symFile); + putc('\n', symFile); } free(symList); @@ -429,22 +423,16 @@ static void writeEmptySpace(uint16_t begin, uint16_t end) /* * Write a bank's contents to the map file - * @param bankSections The bank's sections - * @return The bank's used space */ -static uint16_t writeMapBank(struct SortedSections const *sectList, - enum SectionType type, uint32_t bank) +static void writeMapBank(struct SortedSections const *sectList, enum SectionType type, + uint32_t bank) { - if (!mapFile) - return 0; - - struct SortedSection const *section = sectList->sections; - struct SortedSection const *zeroLenSection = sectList->zeroLenSections; - - fprintf(mapFile, "%s bank #%" PRIu32 ":\n", sectionTypeInfo[type].name, + fprintf(mapFile, "\n%s bank #%" PRIu32 ":\n", sectionTypeInfo[type].name, bank + sectionTypeInfo[type].firstBank); uint16_t used = 0; + struct SortedSection const *section = sectList->sections; + struct SortedSection const *zeroLenSection = sectList->zeroLenSections; uint16_t prevEndAddr = sectionTypeInfo[type].startAddr; while (section || zeroLenSection) { @@ -496,83 +484,109 @@ static uint16_t writeMapBank(struct SortedSections const *sectList, *pickedSection = (*pickedSection)->next; } - uint16_t bankEndAddr = sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size; - if (used == 0) { - fputs("\tEMPTY\n\n", mapFile); + fputs("\tEMPTY\n", mapFile); } else { + uint16_t bankEndAddr = sectionTypeInfo[type].startAddr + sectionTypeInfo[type].size; + writeEmptySpace(prevEndAddr, bankEndAddr); uint16_t slack = sectionTypeInfo[type].size - used; - fprintf(mapFile, "\tTOTAL EMPTY: $%04" PRIx16 " byte%s\n\n", slack, + fprintf(mapFile, "\tTOTAL EMPTY: $%04" PRIx16 " byte%s\n", slack, slack == 1 ? "" : "s"); } - - return used; } /* * Write the total used and free space by section type to the map file - * @param usedMap The total used space by section type */ -static void writeMapSummary(uint32_t usedMap[MIN_NB_ELMS(SECTTYPE_INVALID)]) +static void writeMapSummary(void) { - if (!mapFile) - return; - fputs("SUMMARY:\n", mapFile); for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) { enum SectionType type = typeMap[i]; + uint32_t nbBanks = sections[type].nbBanks; // Do not output used space for VRAM or OAM if (type == SECTTYPE_VRAM || type == SECTTYPE_OAM) continue; // Do not output unused section types - if (sections[type].nbBanks == 0) + if (nbBanks == 0) continue; + uint32_t usedTotal = 0; + + for (uint32_t bank = 0; bank < nbBanks; bank++) { + uint16_t used = 0; + struct SortedSections const *sectList = §ions[type].banks[bank]; + struct SortedSection const *section = sectList->sections; + struct SortedSection const *zeroLenSection = sectList->zeroLenSections; + + while (section || zeroLenSection) { + struct SortedSection const **pickedSection = + nextSection(§ion, &zeroLenSection); + + used += (*pickedSection)->section->size; + *pickedSection = (*pickedSection)->next; + } + + usedTotal += used; + } + fprintf(mapFile, "\t%s: %" PRId32 " byte%s used / %" PRId32 " free", - sectionTypeInfo[type].name, usedMap[type], usedMap[type] == 1 ? "" : "s", - sections[type].nbBanks * sectionTypeInfo[type].size - usedMap[type]); - if (sectionTypeInfo[type].firstBank != sectionTypeInfo[type].lastBank || - sections[type].nbBanks > 1) - fprintf(mapFile, " in %d bank%s", sections[type].nbBanks, - sections[type].nbBanks == 1 ? "" : "s"); - fputc('\n', mapFile); + sectionTypeInfo[type].name, usedTotal, usedTotal == 1 ? "" : "s", + nbBanks * sectionTypeInfo[type].size - usedTotal); + if (sectionTypeInfo[type].firstBank != sectionTypeInfo[type].lastBank + || nbBanks > 1) + fprintf(mapFile, " in %d bank%s", nbBanks, nbBanks == 1 ? "" : "s"); + putc('\n', mapFile); } } -// Writes the sym and/or map files, if applicable. -static void writeSymAndMap(void) +// Writes the sym file, if applicable. +static void writeSym(void) { - if (!symFileName && !mapFileName) + if (!symFileName) return; - uint32_t usedMap[SECTTYPE_INVALID] = {0}; - symFile = openFile(symFileName, "w"); - mapFile = openFile(mapFileName, "w"); + if (!symFile) + err("Failed to open sym file \"%s\"", symFileName); - if (symFileName) - fputs("; File generated by rgblink\n", symFile); + fputs("; File generated by rgblink\n", symFile); for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) { enum SectionType type = typeMap[i]; - for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) { - struct SortedSections const *sect = §ions[type].banks[bank]; - - writeSymBank(sect, type, bank); - usedMap[type] += writeMapBank(sect, type, bank); - } + for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) + writeSymBank(§ions[type].banks[bank], type, bank); } - writeMapSummary(usedMap); - closeFile(symFile); +} + +// Writes the map file, if applicable. +static void writeMap(void) +{ + if (!mapFileName) + return; + + mapFile = openFile(mapFileName, "w"); + if (!mapFile) + err("Failed to open map file \"%s\"", mapFileName); + + writeMapSummary(); + + for (uint8_t i = 0; i < SECTTYPE_INVALID; i++) { + enum SectionType type = typeMap[i]; + + for (uint32_t bank = 0; bank < sections[type].nbBanks; bank++) + writeMapBank(§ions[type].banks[bank], type, bank); + } + closeFile(mapFile); } @@ -589,23 +603,21 @@ static void cleanupSections(struct SortedSection *section) static void cleanup(void) { for (enum SectionType type = 0; type < SECTTYPE_INVALID; type++) { - if (sections[type].nbBanks > 0) { - for (uint32_t i = 0; i < sections[type].nbBanks; i++) { - struct SortedSections *bank = - §ions[type].banks[i]; + for (uint32_t i = 0; i < sections[type].nbBanks; i++) { + struct SortedSections *bank = §ions[type].banks[i]; - cleanupSections(bank->sections); - cleanupSections(bank->zeroLenSections); - } - free(sections[type].banks); + cleanupSections(bank->sections); + cleanupSections(bank->zeroLenSections); } + free(sections[type].banks); } } void out_WriteFiles(void) { writeROM(); - writeSymAndMap(); + writeSym(); + writeMap(); cleanup(); }