gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 3d1f76591d59851cbe8d332602147aa8658735d1 parent b24c0215271cb3ed128f64cb1b9f9219ba09129d Author: bbbbbr <bbbbbr@users.noreply.github.com> Date: Thu, 30 May 2024 14:06:25 -0700 Merge pull request #682 from bbbbbr/bankpack_add_xl4_support bankpack: support both xl3 and xl4 obj file formats Diffstat:
| M | gbdk-support/bankpack/common.h | 9 | +++++++++ |
| M | gbdk-support/bankpack/files.c | 39 | +++++++++++++++++++++++++++++++++++++-- |
| M | gbdk-support/bankpack/files.h | 1 | + |
| M | gbdk-support/bankpack/obj_data.c | 38 | +++++++++++++++++++++++++++----------- |
| M | gbdk-support/bankpack/obj_data.h | 4 | ++-- |
5 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/gbdk-support/bankpack/common.h b/gbdk-support/bankpack/common.h @@ -25,6 +25,15 @@ enum { NES_MAPPER_TYPE_DEFAULT = NES_MAPPER_TYPE_MAPPER30 }; +enum { + OBJ_FILE_XL3_24BIT_ADDR = 0, + OBJ_FILE_XL4_32BIT_ADDR = 1, + OBJ_FILE_UNKNOWN +}; +#define OBJ_FILE_XL3_ID "XL3" +#define OBJ_FILE_XL4_ID "XL4" + + #define MAX_FILE_STR 2048 #define BANK_NUM_UNASSIGNED 0xFFFFU diff --git a/gbdk-support/bankpack/files.c b/gbdk-support/bankpack/files.c @@ -24,6 +24,8 @@ char g_out_ext[MAX_FILE_STR]; char g_out_path[MAX_FILE_STR]; char g_out_linkerfile_name[MAX_FILE_STR] = {'\0'}; +static unsigned int get_obj_file_format(char * str_filename); + void files_set_out_ext(char * ext_str) { if (snprintf(g_out_ext, sizeof(g_out_ext), "%s", ext_str) > sizeof(g_out_ext)) printf("Bankpack: Warning: truncated output extension to:%s\n",g_out_ext); @@ -195,6 +197,36 @@ static char * file_read_to_buffer(char * filename) { } +// Scan the file looking for lines that start with XL3 or XL4 +// which indicate object file version type +static unsigned int get_obj_file_format(char * str_filename) { + + char strline_in[OBJ_NAME_MAX_STR_LEN] = ""; + FILE * obj_file = fopen(str_filename, "r"); + if (obj_file) { + + // Read one line at a time into \0 terminated string + while ( fgets(strline_in, sizeof(strline_in), obj_file) != NULL) { + + // Check if a version version indicator was found + if (strncmp(strline_in, OBJ_FILE_XL3_ID, strlen(OBJ_FILE_XL3_ID)) == 0) { + return (OBJ_FILE_XL3_24BIT_ADDR); + } + else if (strncmp(strline_in, OBJ_FILE_XL4_ID, strlen(OBJ_FILE_XL4_ID)) == 0) { + return (OBJ_FILE_XL4_32BIT_ADDR); + } + } + fclose(obj_file); + } else { + printf("BankPack: ERROR: failed to open file %s\n", str_filename); + exit(EXIT_FAILURE); + } + + printf("BankPack: ERROR: unable to determine Object File version for file: \"%s\"\n", str_filename); + exit(EXIT_FAILURE); +} + + // Extract areas from files, then collected assign them to banks void files_extract(void) { uint32_t c; @@ -205,16 +237,19 @@ void files_extract(void) { // Process stored file names for (c = 0; c < filelist.count; c++) { + files[c].obj_file_format = get_obj_file_format(files[c].name_in); + // Open each object file and try to process all the lines obj_file = fopen(files[c].name_in, "r"); if (obj_file) { + // Read one line at a time into \0 terminated string while ( fgets(strline_in, sizeof(strline_in), obj_file) != NULL) { if (strline_in[0] == 'A') areas_add(strline_in, c); else if (strline_in[0] == 'S') - symbols_add(strline_in, c); + symbols_add(strline_in, c, files[c].obj_file_format); } fclose(obj_file); @@ -264,7 +299,7 @@ void files_rewrite(void) { if (files[c].rewrite_needed) { if (!area_modify_and_write_to_file(strline_in, out_file, files[c].bank_num)) { - if (!symbol_modify_and_write_to_file(strline_in, out_file, files[c].bank_num, c)) { + if (!symbol_modify_and_write_to_file(strline_in, out_file, files[c].bank_num, c, files[c].obj_file_format)) { // Default is to write line with no changes fprintf(out_file, "%s\n", strline_in); } diff --git a/gbdk-support/bankpack/files.h b/gbdk-support/bankpack/files.h @@ -12,6 +12,7 @@ typedef struct file_item { uint16_t bank_num; bool rewrite_needed; char name_out[MAX_FILE_STR]; + unsigned int obj_file_format; } file_item; diff --git a/gbdk-support/bankpack/obj_data.c b/gbdk-support/bankpack/obj_data.c @@ -119,13 +119,16 @@ int areas_add(char * area_str, uint32_t file_id) { } -// Add an area into the pool of areas to assign (if it's banked CODE) -int symbols_add(char * symbol_str, uint32_t file_id) { +// Check and add a symbol record (if it's banked CODE) +int symbols_add(char * symbol_str, uint32_t file_id, unsigned int obj_file_format) { symbol_item newsymbol; - if (SYMBOL_LINE_RECORDS == sscanf(symbol_str,"S %" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def00%4x", - newsymbol.name, &newsymbol.bank_num_in)) { + const char * s_def_matches[] = {[OBJ_FILE_XL3_24BIT_ADDR] = "S %" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def00%4x", + [OBJ_FILE_XL4_32BIT_ADDR] = "S %" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def0000%4x"}; + if (obj_file_format >= OBJ_FILE_UNKNOWN) return false; + + if (SYMBOL_LINE_RECORDS == sscanf(symbol_str, s_def_matches[obj_file_format], newsymbol.name, &newsymbol.bank_num_in)) { // Symbols that start with b_ store the bank num for the matching symbol without 'b' newsymbol.is_banked_def = (newsymbol.name[0] == 'b'); @@ -425,7 +428,7 @@ void obj_data_process(list_type * p_filelist) { if (symbols[c].is_banked_def) { for (s = 0; s < symbollist.count; s++) { if (symbols[c].file_id == symbols[s].file_id) { - // offset +1 bast the "b" char at start of banekd symbol entry name + // offset +1 past the "b" char at start of banked symbol entry name if (strcmp(symbols[c].name + 1, symbols[s].name) == 0) { symbols[c].found_matching_symbol = true; break; @@ -524,7 +527,7 @@ bool symbol_banked_check_rewrite_ok(char * symbol_name, uint32_t file_id) { // Accepts an input string line // and writes it out with an updated bank to a file // * Adds trailing \n if missing -bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_t bank_num, uint32_t file_id) { +bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_t bank_num, uint32_t file_id, unsigned int obj_file_format) { uint32_t c; uint32_t bank_in = 0; @@ -532,13 +535,26 @@ bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_ char symbol_name[OBJ_NAME_MAX_STR_LEN]; symbol_match_item * sym_match = (symbol_match_item *)symbol_matchlist.p_array; + const char * s_def_b_matches[] = {[OBJ_FILE_XL3_24BIT_ADDR] = "S b_%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%06x", + [OBJ_FILE_XL4_32BIT_ADDR] = "S b_%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%08x"}; + const char * s_def_b_rewrite[] = {[OBJ_FILE_XL3_24BIT_ADDR] = "S b_%s Def0000%02x", + [OBJ_FILE_XL4_32BIT_ADDR] = "S b_%s Def0000%04x"}; + + const char * s_def_matches[] = {[OBJ_FILE_XL3_24BIT_ADDR] = "S %s%%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%%06x", + [OBJ_FILE_XL4_32BIT_ADDR] = "S %s%%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%%08x"}; + const char * s_def_rewrite[] = {[OBJ_FILE_XL3_24BIT_ADDR] = "S %s%s Def0000%02x", + [OBJ_FILE_XL4_32BIT_ADDR] = "S %s%s Def0000%04x"}; + + if (obj_file_format >= OBJ_FILE_UNKNOWN) return false; + // Only rewrite banked symbol entries if (strline_in[0] == 'S') { - // For lines: S b_<symbol name>... Def0000FF - if (SYMBOL_REWRITE_RECORDS == sscanf(strline_in,"S b_%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%06x", symbol_name, &bank_in)) { + // For lines: S b_<symbol name>... Def0000FF (XL3 version) + // For lines: S b_<symbol name>... Def000000FF (XL4 version) + if (SYMBOL_REWRITE_RECORDS == sscanf(strline_in, s_def_b_matches[obj_file_format], symbol_name, &bank_in)) { if (bank_in == BANK_NUM_AUTO) { if (symbol_banked_check_rewrite_ok(symbol_name, file_id)) { - fprintf(out_file, "S b_%s Def0000%02x", symbol_name, bank_num); + fprintf(out_file, s_def_b_rewrite[obj_file_format], symbol_name, bank_num); if (strline_in[(strlen(strline_in)-1)] != '\n') fprintf(out_file, "\n"); return true; @@ -548,12 +564,12 @@ bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_ else { for (c = 0; c < symbol_matchlist.count; c++) { // Prepare a sscanf match test string for the current symbol name - if (snprintf(strmatch, sizeof(strmatch), "S %s%%" TOSTR(OBJ_NAME_MAX_STR_LEN) "s Def%%06x", sym_match[c].name) > sizeof(strmatch)) + if (snprintf(strmatch, sizeof(strmatch), s_def_matches[obj_file_format], sym_match[c].name) > sizeof(strmatch)) printf("BankPack: Warning: truncated symbol match string to:%s\n",strmatch); if (SYMBOL_REWRITE_RECORDS == sscanf(strline_in, strmatch, symbol_name, &bank_in)) { if (bank_in == BANK_NUM_AUTO) { - fprintf(out_file, "S %s%s Def0000%02x", sym_match[c].name, symbol_name, bank_num); + fprintf(out_file, s_def_rewrite[obj_file_format], sym_match[c].name, symbol_name, bank_num); if (strline_in[(strlen(strline_in)-1)] != '\n') fprintf(out_file, "\n"); return true; diff --git a/gbdk-support/bankpack/obj_data.h b/gbdk-support/bankpack/obj_data.h @@ -52,13 +52,13 @@ void obj_data_init(void); void obj_data_cleanup(void); int areas_add(char * area_str, uint32_t file_id); -int symbols_add(char * area_str, uint32_t file_id); +int symbols_add(char * area_str, uint32_t file_id, unsigned int obj_file_format); void symbol_match_add(char *); void obj_data_process(list_type *); bool area_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_t bank_num); -bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_t bank_num, uint32_t file_id); +bool symbol_modify_and_write_to_file(char * strline_in, FILE * out_file, uint16_t bank_num, uint32_t file_id, unsigned int obj_file_format); void banks_show(void);
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.