gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 486dc36efb41765bc67b865a3a91c021b3c7c6a3 parent 28710d40d89dc5de1c11f0fc1e193bb07e79e528 Author: bbbbbr <bbbbbr@users.noreply.github.com> Date: Tue, 14 Jun 2022 15:47:24 -0700 Merge pull request #382 from bbbbbr/ihxcheck_warn_bank_overflow ihxcheck: Check and warn for bank overflows under specific conditions Diffstat:
| M | gbdk-support/ihxcheck/areas.c | 14 | +++++++++++--- |
| M | gbdk-support/ihxcheck/areas.h | 8 | ++++++++ |
| M | gbdk-support/ihxcheck/ihx_file.c | 54 | +++++++++++++++++++++++++++++++++++++++++++++++------- |
3 files changed, 66 insertions(+), 10 deletions(-)
diff --git a/gbdk-support/ihxcheck/areas.c b/gbdk-support/ihxcheck/areas.c @@ -13,6 +13,8 @@ #define AREA_GROW_SIZE 500 +extern bank_info banks[]; + area_item * arealist; uint32_t arealist_size; uint32_t arealist_count; @@ -39,9 +41,15 @@ static uint32_t addrs_check_overlap(uint32_t a_start, uint32_t a_end, uint32_t b } else { size_used = min(b_end, a_end) - max(b_start, a_start) + 1; // Calculate minimum overlap - printf("WARNING: Multiple write of %5d bytes at 0x%x -> 0x%x (%x -> %x, %x -> %x)\n", - size_used, max(b_start, a_start), min(b_end, a_end), - a_start, a_end, b_start, b_end); + uint32_t overlap_start = max(a_start, b_start); + uint32_t overlap_end = min(a_end, b_end); + + // Flag a multiple write warning in the bank where the overflow ENDS + // Used later to check for overflows + banks[BANK_NUM(overlap_end)].had_multiple_write_warning = true; + + printf("Warning: Multiple write of %5d bytes at 0x%x -> 0x%x writes:(0x%x -> 0x%x, 0x%x -> 0x%x)\n", + size_used, overlap_start, overlap_end, a_start, a_end, b_start, b_end); } return size_used; } diff --git a/gbdk-support/ihxcheck/areas.h b/gbdk-support/ihxcheck/areas.h @@ -11,6 +11,14 @@ typedef struct area_item { uint32_t length; } area_item; +typedef struct bank_info { + bool overflowed_into; + uint16_t overflow_from; + bool had_multiple_write_warning; +} bank_info; + +#define BANKS_MAX_COUNT 512 +#define BANK_NUM(addr) ((addr & 0xFFFFC000U) >> 14) void areas_init(void); void areas_cleanup(void); diff --git a/gbdk-support/ihxcheck/ihx_file.c b/gbdk-support/ihxcheck/ihx_file.c @@ -41,8 +41,11 @@ zero - versus - the first bank overflowed into the second that is empty. Currently the 100% bank will get merged into the next one and present as overflow */ +bank_info banks[BANKS_MAX_COUNT] = { + {.overflowed_into = false, + .overflow_from = 0, + .had_multiple_write_warning = false } }; -#define BANK_NUM(addr) ((addr & 0xFFFFC000U) >> 14) #define ADDR_UNSET 0xFFFFFFFEU #define MAX_STR_LEN 4096 @@ -75,7 +78,7 @@ void set_option_warnings_as_errors(bool new_val) { // Return false if any character isn't a valid hex digit -int check_hex(char * c) { +static int check_hex(char * c) { while (*c != '\0') { if ((*c >= '0') && (*c <= '9')) c++; @@ -91,8 +94,35 @@ int check_hex(char * c) { } +// Check for bank overflows under specific conditions +// (fragmented writes of the ihx format make overflows hard to detect reliably) +// +// Call this after processing of all areas has been completed +// +// In order to avoid falsely flagging overflows (including 32K only roms +// where bank 0 is normally allowed to overflow into bank 1) the following +// criteria must be met: +// +// * A multiple write to the same address must occur. The address +// where the overlap ends is used as the CURRENT BANK. +// +// * There must also be a write which spans multiple banks, the +// ending address of that must match CURRENT BANK. +// The starting addresses is the OVERFLOW-FROM BANK. +// +static void ihx_check_for_overflows(void) { + + for (int c = 0; c < BANKS_MAX_COUNT; c++) { + if (banks[c].overflowed_into && banks[c].had_multiple_write_warning) { + + printf("Warning: Possible overflow from Bank %d into Bank %d\n", banks[c].overflow_from, c); + } + } +} + + // Parse and validate an IHX record -int ihx_parse_and_validate_record(char * p_str, ihx_record * p_rec) { +static int ihx_parse_and_validate_record(char * p_str, ihx_record * p_rec) { int calc_length = 0; int c; @@ -181,10 +211,17 @@ int ihx_parse_and_validate_record(char * p_str, ihx_record * p_rec) { // For records that start in banks above the unbanked region (0x000 - 0x3FFF) // Warn (but don't error) if they cross the boundary between different banks - if ((p_rec->address >= 0x00004000U) && - ((p_rec->address & 0xFFFFC000U) != (p_rec->address_end & 0xFFFFC000U))) { - printf("Warning: Write from one bank spans into the next. %x -> %x (bank %d -> %d)\n", - p_rec->address, p_rec->address_end, BANK_NUM(p_rec->address), BANK_NUM(p_rec->address_end)); + if ((p_rec->address & 0xFFFFC000U) != (p_rec->address_end & 0xFFFFC000U)) { + + if (p_rec->address >= 0x00004000U) { + printf("Warning: Write from one bank spans into the next. 0x%x -> 0x%x (bank %d -> %d)\n", + p_rec->address, p_rec->address_end, BANK_NUM(p_rec->address), BANK_NUM(p_rec->address_end)); + } + // Log all writes that spans multiple banks, including bank 0 -> 1 + // Used later to help check for overflow + banks[BANK_NUM(p_rec->address_end)].overflowed_into = true; + banks[BANK_NUM(p_rec->address_end)].overflow_from = BANK_NUM(p_rec->address); + } return true; @@ -265,6 +302,9 @@ int ihx_file_process_areas(char * filename_in) { ret = EXIT_FAILURE; } + // Check and warn for possible overflows + ihx_check_for_overflows(); + areas_cleanup(); return ret; }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.