gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit 813c57f7c68802c4fa7a524566baa6fabed5aff3 parent ac2326e1b82afb2d2e1d967f2fddbe311730a02c Author: bbbbbr <bbbbbr@users.noreply.github.com> Date: Sat, 20 Aug 2022 22:37:37 -0700 Merge pull request #401 from bbbbbr/bankpack_reserve_bank_space Bankpack: Add -reserve=<banks>:<size> + option refactor Diffstat:
| M | gbdk-support/bankpack/Makefile | 2 | +- |
| M | gbdk-support/bankpack/bankpack.c | 71 | ++++++++++++++++++++++++++++++++++++----------------------------------- |
| M | gbdk-support/bankpack/common.h | 1 | + |
| M | gbdk-support/bankpack/obj_data.c | 247 | ++++++++----------------------------------------------------------------------- |
| M | gbdk-support/bankpack/obj_data.h | 24 | +----------------------- |
| A | gbdk-support/bankpack/options.c | 297 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | gbdk-support/bankpack/options.h | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
7 files changed, 407 insertions(+), 281 deletions(-)
diff --git a/gbdk-support/bankpack/Makefile b/gbdk-support/bankpack/Makefile @@ -17,7 +17,7 @@ endif CC = $(TOOLSPREFIX)gcc CFLAGS = -ggdb -O -Wno-incompatible-pointer-types -DGBDKLIBDIR=\"$(TARGETDIR)\" -OBJ = bankpack.o files.o obj_data.o list.o path_ops.o +OBJ = bankpack.o files.o obj_data.o list.o path_ops.o options.o BIN = bankpack all: $(BIN) diff --git a/gbdk-support/bankpack/bankpack.c b/gbdk-support/bankpack/bankpack.c @@ -12,13 +12,10 @@ #include "obj_data.h" #include "files.h" - -bool g_option_verbose = false; -bool g_option_cartsize = false; +#include "options.h" static void display_help(void); static int handle_args(int argc, char * argv[]); -static void option_set_verbose(bool is_enabled); static void init(void); void cleanup(void); @@ -30,25 +27,27 @@ static void display_help(void) { " Typically called by Lcc compiler driver before linker.\n" "\n" "Options\n" - "-h : Show this help\n" - "-lkin=<file> : Load object files specified in linker file <file>\n" - "-lkout=<file>: Write list of object files out to linker file <file>\n" - "-yt<mbctype> : Set MBC type per ROM byte 149 in Decimal or Hex (0xNN)\n" + "-h : Show this help\n" + "-lkin=<file> : Load object files specified in linker file <file>\n" + "-lkout=<file> : Write list of object files out to linker file <file>\n" + "-yt<mbctype> : Set MBC type per ROM byte 149 in Decimal or Hex (0xNN)\n" " ([see pandocs](https://gbdev.io/pandocs/The_Cartridge_Header.html#0147---cartridge-type))\n" - "-mbc=N : Similar to -yt, but sets MBC type directly to N instead\n" + "-mbc=N : Similar to -yt, but sets MBC type directly to N instead\n" " of by intepreting ROM byte 149\n" " mbc1 will exclude banks {0x20,0x40,0x60} max=127, \n" " mbc2 max=15, mbc3 max=127, mbc5 max=255 (not 511!) \n" - "-min=N : Min assigned ROM bank is N (default 1)\n" - "-max=N : Max assigned ROM bank is N, error if exceeded\n" - "-ext=<.ext> : Write files out with <.ext> instead of source extension\n" - "-path=<path> : Write files out to <path> (<path> *MUST* already exist)\n" - "-sym=<prefix>: Add symbols starting with <prefix> to match + update list.\n" + "-min=N : Min assigned ROM bank is N (default 1)\n" + "-max=N : Max assigned ROM bank is N, error if exceeded\n" + "-ext=<.ext> : Write files out with <.ext> instead of source extension\n" + "-path=<path> : Write files out to <path> (<path> *MUST* already exist)\n" + "-sym=<prefix> : Add symbols starting with <prefix> to match + update list.\n" " Default entry is \"___bank_\" (see below)\n" - "-cartsize : Print min required cart size as \"autocartsize:<NNN>\"\n" - "-plat=<plat> : Select platform specific behavior (default:gb) (gb,sms)\n" - "-random : Distribute banks randomly for testing (honors -min/-max)\n" - "-v : Verbose output, show assignments\n" + "-cartsize : Print min required cart size as \"autocartsize:<NNN>\"\n" + "-plat=<plat> : Select platform specific behavior (default:gb) (gb,sms)\n" + "-random : Distribute banks randomly for testing (honors -min/-max)\n" + "-reserve=<b:n>: Reserve N bytes (hex) in bank B (decimal)\n" + " Ex: -reserve=105:30F reserves 0x30F bytes in bank 105\n" + "-v : Verbose output, show assignments\n" "\n" "Example: \"bankpack -ext=.rel -path=some/newpath/ file1.o file2.o\"\n" "Unless -ext or -path specify otherwise, input files are overwritten.\n" @@ -81,12 +80,12 @@ static int handle_args(int argc, char * argv[]) { display_help(); return false; // Don't parse input when -h is used } else if (strstr(argv[i], "-min=") == argv[i]) { - if (!banks_set_min(atoi(argv[i] + 5))) { + if (!option_banks_set_min(atoi(argv[i] + 5))) { printf("BankPack: ERROR: Invalid min bank: %s\n", argv[i] + 5); return false; } } else if (strstr(argv[i], "-max=") == argv[i]) { - if (!banks_set_max(atoi(argv[i] + 5))) { + if (!option_banks_set_max(atoi(argv[i] + 5))) { printf("BankPack: ERROR: Invalid max bank: %s\n", argv[i] + 5); return false; } @@ -95,25 +94,32 @@ static int handle_args(int argc, char * argv[]) { } else if (strstr(argv[i], "-path=") == argv[i]) { files_set_out_path(argv[i] + 6); } else if (strstr(argv[i], "-mbc=") == argv[i]) { - banks_set_mbc(atoi(argv[i] + 5)); + option_set_mbc(atoi(argv[i] + 5)); } else if (strstr(argv[i], "-yt") == argv[i]) { - banks_set_mbc_by_rom_byte_149(strtol(argv[i] + 3, NULL, 0)); + option_mbc_by_rom_byte_149(strtol(argv[i] + 3, NULL, 0)); } else if (strstr(argv[i], "-v") == argv[i]) { option_set_verbose(true); } else if (strstr(argv[i], "-sym=") == argv[i]) { symbol_match_add(argv[i] + 5); } else if (strstr(argv[i], "-cartsize") == argv[i]) { - g_option_cartsize = true; + option_set_cartsize(true); } else if (strstr(argv[i], "-plat=") == argv[i]) { - banks_set_platform(argv[i] + 6); + option_set_platform(argv[i] + 6); } else if (strstr(argv[i], "-random") == argv[i]) { - banks_set_random(true); + option_set_random_assign(true); } else if (strstr(argv[i], "-lkin=") == argv[i]) { files_read_linkerfile(argv[i] + strlen("-lkin=")); } else if (strstr(argv[i], "-lkout=") == argv[i]) { files_set_linkerfile_outname(argv[i] + strlen("-lkout=")); - } else + } else if (strstr(argv[i], "-reserve=") == argv[i]) { + if (!option_bank_reserve_bytes(argv[i])) { + fprintf(stdout,"BankPack: ERROR! Malformed argument: %s\n\n", argv[i]); + display_help(); + return false; + } + } else { printf("BankPack: Warning: Ignoring unknown option %s\n", argv[i]); + } } else { // Add to list of object files to process files_add(argv[i]); @@ -124,11 +130,6 @@ static int handle_args(int argc, char * argv[]) { } -static void option_set_verbose(bool is_enabled) { - g_option_verbose = is_enabled; -} - - static int matches_extension(char * filename, char * extension) { return (strcmp(filename + (strlen(filename) - strlen(extension)), extension) == 0); } @@ -161,7 +162,7 @@ int main( int argc, char *argv[] ) { // Require MBC for Game Boy // SMS doesn't require an MBC setting - if ((banks_get_platform() == PLATFORM_GB) && (banks_get_mbc_type() == MBC_TYPE_NONE)) + if ((option_get_platform() == PLATFORM_GB) && (option_get_mbc_type() == MBC_TYPE_NONE)) printf("BankPack: ERROR: auto-banking does not work with unbanked ROMS (no MBC for Game Boy)\n"); else { // Extract areas, sort and assign them to banks @@ -169,10 +170,10 @@ int main( int argc, char *argv[] ) { files_extract(); files_rewrite(); - if (g_option_verbose) + if (option_get_verbose()) banks_show(); - if (g_option_cartsize) - fprintf(stdout,"autocartsize:%d\n",banks_calc_cart_size()); + if (option_get_cartsize()) + fprintf(stdout,"autocartsize:%d\n",option_banks_calc_cart_size()); cleanup(); ret = EXIT_SUCCESS; diff --git a/gbdk-support/bankpack/common.h b/gbdk-support/bankpack/common.h @@ -24,6 +24,7 @@ enum { #define BANK_ROM_TOTAL 256 // Banks 0-255 #define BANK_ROM_CALC_MAX 512 // Banks 0-512 (>256 not supported for auto-banking right now) #define BANK_SIZE_ROM 0x4000U +#define BANK_SIZE_ROM_MAX (BANK_SIZE_ROM) #define BANK_ITEM_COUNT_MAX 0xFFFF diff --git a/gbdk-support/bankpack/obj_data.c b/gbdk-support/bankpack/obj_data.c @@ -13,6 +13,7 @@ #include "common.h" #include "list.h" #include "files.h" +#include "options.h" #include "obj_data.h" @@ -26,7 +27,6 @@ static int area_item_compare(const void* a, const void* b); static void areas_sort(void); static bool symbol_banked_check_rewrite_ok(char *, uint32_t); -extern bool g_option_verbose; list_type banklist; @@ -38,207 +38,9 @@ uint16_t bank_limit_rom_min = BANK_NUM_ROM_MIN; uint16_t bank_limit_rom_max = BANK_NUM_ROM_MAX; -uint16_t bank_assign_rom_min = BANK_NUM_ROM_MAX; -uint16_t bank_assign_rom_max = 0; -uint16_t bank_all_rom_max = 0; - -int g_mbc_type = MBC_TYPE_DEFAULT; -int g_platform = PLATFORM_DEFAULT; -bool g_opt_random_assign = false; - - -int banks_get_platform(void) { - return g_platform; -} - -void banks_set_platform(char * platform_str) { - - if (strcmp(platform_str, PLATFORM_STR_GB) == 0) - g_platform = PLATFORM_GB; - else if (strcmp(platform_str, PLATFORM_STR_AP) == 0) - g_platform = PLATFORM_GB; // Analogue Pocket uses GB platform - else if (strcmp(platform_str, PLATFORM_STR_DUCK) == 0) - g_platform = PLATFORM_GB; // Megaduck uses GB platform - else if (strcmp(platform_str, PLATFORM_STR_SMS) == 0) - g_platform = PLATFORM_SMS; - else if (strcmp(platform_str, PLATFORM_STR_GG) == 0) - g_platform = PLATFORM_SMS; // GG uses SMS platform - else if (strcmp(platform_str, PLATFORM_STR_MSXDOS) == 0) - g_platform = PLATFORM_SMS; // MSXDOS uses SMS platform - else - printf("BankPack: Warning: Invalid platform option %s\n", platform_str); -} - - - -int banks_get_mbc_type(void) { - return g_mbc_type; -} - - -// Set MBC type by interpreting from byte 149 -// -// For lcc linker option: -Wl-ytN where N is one of the numbers below -// (from makebin.c in SDCC) -// -// ROM Byte 0147: Cartridge type: -// 0-ROM ONLY 12-ROM+MBC3+RAM -// 1-ROM+MBC1 13-ROM+MBC3+RAM+BATT -// 2-ROM+MBC1+RAM 19-ROM+MBC5 -// 3-ROM+MBC1+RAM+BATT 1A-ROM+MBC5+RAM -// 5-ROM+MBC2 1B-ROM+MBC5+RAM+BATT -// 6-ROM+MBC2+BATTERY 1C-ROM+MBC5+RUMBLE -// 8-ROM+RAM 1D-ROM+MBC5+RUMBLE+SRAM -// 9-ROM+RAM+BATTERY 1E-ROM+MBC5+RUMBLE+SRAM+BATT -// B-ROM+MMM01 1F-Pocket Camera -// C-ROM+MMM01+SRAM FD-Bandai TAMA5 -// D-ROM+MMM01+SRAM+BATT FE - Hudson HuC-3 -// F-ROM+MBC3+TIMER+BATT FF - Hudson HuC-1 -// 10-ROM+MBC3+TIMER+RAM+BATT -// 11-ROM+MBC3 -void banks_set_mbc_by_rom_byte_149(int mbc_type_rom_byte) { - - switch (mbc_type_rom_byte) { - // NO MBC - case 0x00U: // 0-ROM ONLY - case 0x08U: // 2-ROM+MBC1+RAM - case 0x09U: // 8-ROM+RAM - case 0x0BU: // B-ROM+MMM01 - case 0x0CU: // C-ROM+MMM01+SRAM - case 0x0DU: // D-ROM+MMM01+SRAM+BATT - banks_set_mbc(MBC_TYPE_NONE); - break; - - // MBC 1 - case 0x01U: // 1-ROM+MBC1 - case 0x02U: // 2-ROM+MBC1+RAM - case 0x03U: // 3-ROM+MBC1+RAM+BATT - banks_set_mbc(MBC_TYPE_MBC1); - break; - - // MBC 2 - case 0x05U: // 5-ROM+MBC2 - case 0x06U: // 6-ROM+MBC2+BATTERY - banks_set_mbc(MBC_TYPE_MBC2); - break; - - // MBC 3 - case 0x0FU: // F-ROM+MBC3+TIMER+BATT - case 0x10U: // 10-ROM+MBC3+TIMER+RAM+BATT - case 0x11U: // 11-ROM+MBC3 - case 0x12U: // 12-ROM+MBC3+RAM - case 0x13U: // 13-ROM+MBC3+RAM+BATT - case 0xFCU: // FC-GAME BOY CAMERA - banks_set_mbc(MBC_TYPE_MBC3); - break; - - // MBC 5 - case 0x19U: // 19-ROM+MBC5 - case 0x1AU: // 1A-ROM+MBC5+RAM - case 0x1BU: // 1B-ROM+MBC5+RAM+BATT - case 0x1CU: // 1C-ROM+MBC5+RUMBLE - case 0x1DU: // 1D-ROM+MBC5+RUMBLE+SRAM - case 0x1EU: // 1E-ROM+MBC5+RUMBLE+SRAM+BATT - banks_set_mbc(MBC_TYPE_MBC5); - break; - - default: - printf("BankPack: Warning: unrecognized MBC option -yt=%x\n", mbc_type_rom_byte); - break; - } -} - - -// Set MBC type directly -void banks_set_mbc(int mbc_type) { - - uint16_t mbc_bank_limit_rom_max; - - switch (mbc_type) { - case MBC_TYPE_NONE: - g_mbc_type = MBC_TYPE_NONE; - break; - case MBC_TYPE_MBC1: - g_mbc_type = mbc_type; - mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC1; - break; - case MBC_TYPE_MBC2: - g_mbc_type = mbc_type; - mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC2; - break; - case MBC_TYPE_MBC3: - g_mbc_type = mbc_type; - mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC3; - break; - case MBC_TYPE_MBC5: - g_mbc_type = mbc_type; - mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC5; - break; - default: - printf("BankPack: Warning: unrecognized MBC option -mbc%d!\n", mbc_type); - break; - } - if (mbc_bank_limit_rom_max < bank_limit_rom_max) - bank_limit_rom_max = mbc_bank_limit_rom_max; -} - - - -// From makebin -// Byte -// 0148 - ROM size -yt<N> -// 0 - 256Kbit = 32KByte = 2 banks -// 1 - 512Kbit = 64KByte = 4 banks -// 2 - 1Mbit = 128KByte = 8 banks -// 3 - 2Mbit = 256KByte = 16 banks -// 4 - 4Mbit = 512KByte = 32 banks -// 5 - 8Mbit = 1MByte = 64 banks -// 6 - 16Mbit = 2MByte = 128 banks -// 7 - 16Mbit = 2MByte = 256 banks -// 8 - 16Mbit = 2MByte = 512 banks -// -// Not supported by makebin: -// $52 - 9Mbit = 1.1MByte = 72 banks -// $53 - 10Mbit = 1.2MByte = 80 banks -// $54 - 12Mbit = 1.5MByte = 96 banks -uint32_t banks_calc_cart_size(void) { - - uint32_t req_banks = 1; - - if ((bank_all_rom_max + 1) > BANK_ROM_CALC_MAX) { - printf("BankPack: Warning! Can't calc cart size, too many banks: %d (max %d)\n", (bank_all_rom_max + 1), BANK_ROM_CALC_MAX); - return (0); - } - - // Calculate nearest upper power of 2 - while (req_banks < (bank_all_rom_max + 1)) - req_banks *= 2; - - return (req_banks); -} - - -bool banks_set_min(uint16_t bank_num) { - if (bank_num < BANK_NUM_ROM_MIN) - return false; - else bank_limit_rom_min = bank_num; - - return true; -} - -bool banks_set_max(uint16_t bank_num) { - if (bank_num > BANK_NUM_ROM_MAX) - return false; - else bank_limit_rom_max = bank_num; - - return true; -} - - -void banks_set_random(bool is_random) { - g_opt_random_assign = is_random; -} - +uint16_t bank_assigned_rom_min = BANK_NUM_ROM_MAX; +uint16_t bank_assigned_rom_max = 0; +uint16_t bank_assigned_rom_max_alltypes = 0; void obj_data_init(void) { @@ -250,9 +52,10 @@ void obj_data_init(void) { list_init(&symbollist, sizeof(symbol_item)); list_init(&symbol_matchlist, sizeof(symbol_match_item)); - // Pre-populate bank list with max number of of banks + // Pre-populate bank list with max number of banks // to allow handling fixed-bank (non-autobank) areas newbank.size = newbank.free = BANK_SIZE_ROM; + newbank.reserved = 0; newbank.type = BANK_TYPE_UNSET; newbank.item_count = 0; for (c=0; c < BANK_ROM_TOTAL; c++) @@ -343,11 +146,11 @@ int symbols_add(char * symbol_str, uint32_t file_id) { // Track Min/Max assigned banks used static void bank_update_assigned_minmax(uint16_t bank_num) { - if (bank_num > bank_assign_rom_max) - bank_assign_rom_max = bank_num; + if (bank_num > bank_assigned_rom_max) + bank_assigned_rom_max = bank_num; - if (bank_num < bank_assign_rom_min) - bank_assign_rom_min = bank_num; + if (bank_num < bank_assigned_rom_min) + bank_assigned_rom_min = bank_num; bank_update_all_max(bank_num); } @@ -356,8 +159,8 @@ static void bank_update_assigned_minmax(uint16_t bank_num) { // Tracks Max bank for *all* banks used, including fixed banks outside max limits static void bank_update_all_max(uint16_t bank_num) { - if (bank_num > bank_all_rom_max) - bank_all_rom_max = bank_num; + if (bank_num > bank_assigned_rom_max_alltypes) + bank_assigned_rom_max_alltypes = bank_num; } @@ -371,13 +174,13 @@ static void bank_add_area(bank_item * p_bank, uint16_t bank_num, area_item * p_a // Trying to add an auto-bank area to a full bank should be prevented by previous tests, but just in case if (p_area->bank_num_in == BANK_NUM_AUTO) { - printf("BankPack: ERROR! Auto-banked Area %s, bank %d, size %d won't fit in assigned bank %d (free %d)\n", - p_area->name, p_area->bank_num_in, p_area->size, bank_num, p_bank->free); + printf("BankPack: ERROR! Auto-banked Area %s, bank %d, size %d won't fit in assigned bank %d (%d bytes free, %d bytes reserved)\n", + p_area->name, p_area->bank_num_in, p_area->size, bank_num, p_bank->free, p_bank->reserved); exit(EXIT_FAILURE); } else { // Only warn for fixed bank areas. Don't exit and add the area anyway - printf("BankPack: Warning: Fixed-bank Area %s, bank %d, size %d won't fit in assigned bank %d (free %d)\n", - p_area->name, p_area->bank_num_in, p_area->size, bank_num, p_bank->free); + printf("BankPack: Warning: Fixed-bank Area %s, bank %d, size %d won't fit in assigned bank %d (%d bytes free, %d bytes reserved)\n", + p_area->name, p_area->bank_num_in, p_area->size, bank_num, p_bank->free, p_bank->reserved); } // Force bank space to zero, subtracting at this point would overflow @@ -422,7 +225,7 @@ static void bank_report_mixed_area_error(bank_item * p_bank, uint16_t bank_num, " Area %s, bank %d, file:%s\n", p_area->bank_num_in, p_area->name, bank_num, file_get_name_in_by_id(p_area->file_id)); - if (g_option_verbose) + if (option_get_verbose()) banks_show(); } @@ -432,7 +235,7 @@ static bool bank_check_mixed_area_types_ok(bank_item * p_bank, uint16_t bank_num // Don't allow mixing of _CODE_ and _LIT_ for sms/gg ports // If one type has already been assigned to the bank, lock others out - if ((g_platform == PLATFORM_SMS) && + if ((option_get_platform() == PLATFORM_SMS) && (p_bank->type != BANK_TYPE_UNSET) && (p_area->type != p_bank->type)) return false; @@ -446,7 +249,7 @@ static bool bank_check_mixed_area_types_ok(bank_item * p_bank, uint16_t bank_num static bool bank_check_ok_for_area(uint16_t bank_num, area_item * p_area, bank_item * banks) { // Check for MBC bank restrictions - if ((g_mbc_type != MBC_TYPE_MBC1) || (bank_check_mbc1_ok(bank_num))) { + if ((option_get_mbc_type() != MBC_TYPE_MBC1) || (bank_check_mbc1_ok(bank_num))) { // Check for allowed area mixing if needed if (bank_check_mixed_area_types_ok(&banks[bank_num], bank_num, p_area)) { // Make sure there is enough space for the area @@ -530,7 +333,7 @@ static void banks_assign_area(area_item * p_area) { if ((bank_num >= bank_limit_rom_min) && (bank_num <= bank_limit_rom_max)) { - if ((g_mbc_type == MBC_TYPE_MBC1) && (!bank_check_mbc1_ok(bank_num))) + if ((option_get_mbc_type() == MBC_TYPE_MBC1) && (!bank_check_mbc1_ok(bank_num))) printf("BankPack: Warning: Area in fixed bank assigned to MBC1 excluded bank: %d, file: %s\n", bank_num, file_get_name_in_by_id(p_area->file_id)); if (!bank_check_mixed_area_types_ok(&banks[bank_num], bank_num, p_area)) { @@ -547,7 +350,7 @@ static void banks_assign_area(area_item * p_area) { } else if (p_area->bank_num_in == BANK_NUM_AUTO) { - if (g_opt_random_assign) + if (option_get_random_assign()) result = banks_assign_area_random(p_area, banks); else result = banks_assign_area_linear(p_area, banks); @@ -556,7 +359,7 @@ static void banks_assign_area(area_item * p_area) { return; } - if (g_option_verbose) + if (option_get_verbose()) banks_show(); printf("BankPack: ERROR! Failed to assign bank for Area %s, bank %d, size %d. Out of banks!\n", p_area->name, p_area->bank_num_in, p_area->size); @@ -644,15 +447,15 @@ void banks_show(void) { uint32_t a; printf("\n=== Banks assigned: %d -> %d (allowed range %d -> %d). Max including fixed: %d) ===\n", - bank_assign_rom_min, bank_assign_rom_max, + bank_assigned_rom_min, bank_assigned_rom_max, bank_limit_rom_min, bank_limit_rom_max, - bank_all_rom_max); + bank_assigned_rom_max_alltypes); bank_item * banks = (bank_item *)banklist.p_array; area_item * areas = (area_item *)arealist.p_array; for (c = 0; c < banklist.count; c++) { if (banks[c].free != BANK_SIZE_ROM) { - printf("Bank %d: size=%5d, free=%5d\n", c, banks[c].size, banks[c].free); + printf("Bank %d: size=%5d, free=%5d, reserved=%5d\n", c, banks[c].size, banks[c].free, banks[c].reserved); for (a = 0; a < arealist.count; a++) { if (areas[a].bank_num_out == c) { printf(" +- Area: name=%8s, size=%5d, bank_in=%3d, bank_out=%3d, file=%s -> %s\n", diff --git a/gbdk-support/bankpack/obj_data.h b/gbdk-support/bankpack/obj_data.h @@ -12,17 +12,6 @@ #define SYMBOL_LINE_RECORDS 2 // Name, DefVal #define SYMBOL_REWRITE_RECORDS 2 // Name, DefVal -#define PLATFORM_GB 0 -#define PLATFORM_SMS 1 -#define PLATFORM_DEFAULT PLATFORM_GB - -#define PLATFORM_STR_GB "gb" -#define PLATFORM_STR_AP "ap" // Uses PLATFORM_GB -#define PLATFORM_STR_DUCK "duck" // Uses PLATFORM_GB -#define PLATFORM_STR_SMS "sms" -#define PLATFORM_STR_GG "gg" // Uses PLATFORM_SMS -#define PLATFORM_STR_MSXDOS "msxdos" // Uses PLATFORM_SMS - #define BANK_TYPE_UNSET 0 #define BANK_TYPE_DEFAULT 1 #define BANK_TYPE_LIT_EXCLUSIVE 2 @@ -31,6 +20,7 @@ typedef struct bank_item { uint32_t size; uint32_t free; + uint32_t reserved; uint32_t type; uint16_t item_count; } bank_item; @@ -57,18 +47,6 @@ typedef struct symbol_match_item { char name[OBJ_NAME_MAX_STR_LEN]; } symbol_match_item; -void banks_set_platform(char * platform_str); -int banks_get_platform(void); -int banks_get_mbc_type(void); -void banks_set_mbc(int); -void banks_set_mbc_by_rom_byte_149(int); - -uint32_t banks_calc_cart_size(void); - -bool banks_set_min(uint16_t bank_num); -bool banks_set_max(uint16_t bank_num); - -void banks_set_random(bool is_random); void obj_data_init(void); void obj_data_cleanup(void); diff --git a/gbdk-support/bankpack/options.c b/gbdk-support/bankpack/options.c @@ -0,0 +1,297 @@ +// This is free and unencumbered software released into the public domain. +// For more information, please refer to <https://unlicense.org> +// bbbbbr 2022 + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdbool.h> +#include <stdint.h> + +#include "common.h" +#include "list.h" +#include "files.h" +#include "obj_data.h" +#include "options.h" + +extern list_type banklist; +extern uint16_t bank_limit_rom_min; +extern uint16_t bank_limit_rom_max; +extern uint16_t bank_assigned_rom_max_alltypes; + +bool option_verbose = false; +bool option_cartsize = false; +bool option_random_assign = false; +int option_mbc_type = MBC_TYPE_DEFAULT; +int option_platform = PLATFORM_DEFAULT; + + +void option_set_verbose(bool is_enabled) { + option_verbose = is_enabled; +} +bool option_get_verbose(void) { + return option_verbose; +} + + +void option_set_cartsize(bool is_enabled) { + option_cartsize = is_enabled; +} +bool option_get_cartsize(void) { + return option_cartsize; +} + + +void option_set_random_assign(bool is_enabled) { + option_random_assign = is_enabled; +} +bool option_get_random_assign(void) { + return option_random_assign; +} + + + +// Format: -reserve=DECIMAL_BANKNUM:HEX_SIZE +// Reserve space in banks manually from command line arguments +// Should be called *after* obj_data_init() has initialized banks +int option_bank_reserve_bytes(char * arg_str) { + + bank_item * banks = (bank_item *)banklist.p_array; + + char cols; + char * p_str; + char * p_words[ARG_BANK_RESERVE_SIZE_MAX_SPLIT_WORDS]; + char arg_str_copy[ARG_BANK_RESERVE_SIZE_MAX_LEN]; // copy arg since strtok modifies strings it operates on + snprintf(arg_str_copy, sizeof(arg_str_copy), "%s", arg_str); + + // Split string into words using "-:=" as delimiters + cols = 0; + p_str = strtok(arg_str_copy,"-:="); + while (p_str != NULL) + { + p_words[cols++] = p_str; + p_str = strtok(NULL, "-:="); + if (cols >= ARG_BANK_RESERVE_SIZE_MAX_SPLIT_WORDS) break; + } + + if (cols == ARG_BANK_RESERVE_SIZE_REC_COUNT_MATCH) { + + uint32_t reserve_bank = strtol(p_words[1], NULL, 10); // [1] Decimal Bank Number + uint32_t reserve_size = strtol(p_words[2], NULL, 16); // [2] Hex Reserve Size + + if ((reserve_bank < BANK_NUM_ROM_MIN) || (reserve_bank > BANK_NUM_ROM_MAX)) { + printf("BankPack: ERROR! Bank number %d for %s is invalid (min: %d, max: %d)\n", reserve_bank, arg_str, BANK_NUM_ROM_MIN, BANK_NUM_ROM_MAX); + exit(EXIT_FAILURE); + } + + if (reserve_size > BANK_SIZE_ROM_MAX) { + printf("BankPack: ERROR! Size value %x for %s is too large (max:%x)\n", reserve_size, arg_str, BANK_SIZE_ROM_MAX); + exit(EXIT_FAILURE); + } + + if (reserve_size > banks[reserve_bank].free) { + printf("BankPack: ERROR! Size of %x bytes for %s is larger than free space (%x bytes) in bank %d\n", reserve_size, arg_str, banks[reserve_bank].free, reserve_bank); + exit(EXIT_FAILURE); + } + + // printf("Bankpack: Reserving %x bytes for bank %d (%s)\n", reserve_size, reserve_bank, arg_str); + + // Params were valid, deduct the space from the bank + banks[reserve_bank].free -= reserve_size; + banks[reserve_bank].reserved += reserve_size; + return true; + } else + return false; // Signal failure + +} + + +int option_get_platform(void) { + return option_platform; +} + + +void option_set_platform(char * platform_str) { + + if (strcmp(platform_str, PLATFORM_STR_GB) == 0) + option_platform = PLATFORM_GB; + else if (strcmp(platform_str, PLATFORM_STR_AP) == 0) + option_platform = PLATFORM_GB; // Analogue Pocket uses GB platform + else if (strcmp(platform_str, PLATFORM_STR_DUCK) == 0) + option_platform = PLATFORM_GB; // Megaduck uses GB platform + else if (strcmp(platform_str, PLATFORM_STR_SMS) == 0) + option_platform = PLATFORM_SMS; + else if (strcmp(platform_str, PLATFORM_STR_GG) == 0) + option_platform = PLATFORM_SMS; // GG uses SMS platform + else if (strcmp(platform_str, PLATFORM_STR_MSXDOS) == 0) + option_platform = PLATFORM_SMS; // MSXDOS uses SMS platform + else + printf("BankPack: Warning: Invalid platform option %s\n", platform_str); +} + + + +int option_get_mbc_type(void) { + return option_mbc_type; +} + + +// Set MBC type by interpreting from byte 149 +// +// For lcc linker option: -Wl-ytN where N is one of the numbers below +// (from makebin.c in SDCC) +// +// ROM Byte 0147: Cartridge type: +// 0-ROM ONLY 12-ROM+MBC3+RAM +// 1-ROM+MBC1 13-ROM+MBC3+RAM+BATT +// 2-ROM+MBC1+RAM 19-ROM+MBC5 +// 3-ROM+MBC1+RAM+BATT 1A-ROM+MBC5+RAM +// 5-ROM+MBC2 1B-ROM+MBC5+RAM+BATT +// 6-ROM+MBC2+BATTERY 1C-ROM+MBC5+RUMBLE +// 8-ROM+RAM 1D-ROM+MBC5+RUMBLE+SRAM +// 9-ROM+RAM+BATTERY 1E-ROM+MBC5+RUMBLE+SRAM+BATT +// B-ROM+MMM01 1F-Pocket Camera +// C-ROM+MMM01+SRAM FD-Bandai TAMA5 +// D-ROM+MMM01+SRAM+BATT FE - Hudson HuC-3 +// F-ROM+MBC3+TIMER+BATT FF - Hudson HuC-1 +// 10-ROM+MBC3+TIMER+RAM+BATT +// 11-ROM+MBC3 +void option_mbc_by_rom_byte_149(int mbc_type_rom_byte) { + + switch (mbc_type_rom_byte) { + // NO MBC + case 0x00U: // 0-ROM ONLY + case 0x08U: // 2-ROM+MBC1+RAM + case 0x09U: // 8-ROM+RAM + case 0x0BU: // B-ROM+MMM01 + case 0x0CU: // C-ROM+MMM01+SRAM + case 0x0DU: // D-ROM+MMM01+SRAM+BATT + option_set_mbc(MBC_TYPE_NONE); + break; + + // MBC 1 + case 0x01U: // 1-ROM+MBC1 + case 0x02U: // 2-ROM+MBC1+RAM + case 0x03U: // 3-ROM+MBC1+RAM+BATT + option_set_mbc(MBC_TYPE_MBC1); + break; + + // MBC 2 + case 0x05U: // 5-ROM+MBC2 + case 0x06U: // 6-ROM+MBC2+BATTERY + option_set_mbc(MBC_TYPE_MBC2); + break; + + // MBC 3 + case 0x0FU: // F-ROM+MBC3+TIMER+BATT + case 0x10U: // 10-ROM+MBC3+TIMER+RAM+BATT + case 0x11U: // 11-ROM+MBC3 + case 0x12U: // 12-ROM+MBC3+RAM + case 0x13U: // 13-ROM+MBC3+RAM+BATT + case 0xFCU: // FC-GAME BOY CAMERA + option_set_mbc(MBC_TYPE_MBC3); + break; + + // MBC 5 + case 0x19U: // 19-ROM+MBC5 + case 0x1AU: // 1A-ROM+MBC5+RAM + case 0x1BU: // 1B-ROM+MBC5+RAM+BATT + case 0x1CU: // 1C-ROM+MBC5+RUMBLE + case 0x1DU: // 1D-ROM+MBC5+RUMBLE+SRAM + case 0x1EU: // 1E-ROM+MBC5+RUMBLE+SRAM+BATT + option_set_mbc(MBC_TYPE_MBC5); + break; + + default: + printf("BankPack: Warning: unrecognized MBC option -yt=%x\n", mbc_type_rom_byte); + break; + } +} + + +// Set MBC type directly +void option_set_mbc(int mbc_type) { + + uint16_t mbc_bank_limit_rom_max; + + switch (mbc_type) { + case MBC_TYPE_NONE: + option_mbc_type = MBC_TYPE_NONE; + break; + case MBC_TYPE_MBC1: + option_mbc_type = mbc_type; + mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC1; + break; + case MBC_TYPE_MBC2: + option_mbc_type = mbc_type; + mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC2; + break; + case MBC_TYPE_MBC3: + option_mbc_type = mbc_type; + mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC3; + break; + case MBC_TYPE_MBC5: + option_mbc_type = mbc_type; + mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC5; + break; + default: + printf("BankPack: Warning: unrecognized MBC option -mbc%d!\n", mbc_type); + break; + } + if (mbc_bank_limit_rom_max < bank_limit_rom_max) + bank_limit_rom_max = mbc_bank_limit_rom_max; +} + + + +// From makebin +// Byte +// 0148 - ROM size -yt<N> +// 0 - 256Kbit = 32KByte = 2 banks +// 1 - 512Kbit = 64KByte = 4 banks +// 2 - 1Mbit = 128KByte = 8 banks +// 3 - 2Mbit = 256KByte = 16 banks +// 4 - 4Mbit = 512KByte = 32 banks +// 5 - 8Mbit = 1MByte = 64 banks +// 6 - 16Mbit = 2MByte = 128 banks +// 7 - 16Mbit = 2MByte = 256 banks +// 8 - 16Mbit = 2MByte = 512 banks +// +// Not supported by makebin: +// $52 - 9Mbit = 1.1MByte = 72 banks +// $53 - 10Mbit = 1.2MByte = 80 banks +// $54 - 12Mbit = 1.5MByte = 96 banks +uint32_t option_banks_calc_cart_size(void) { + + uint32_t req_banks = 1; + + if ((bank_assigned_rom_max_alltypes + 1) > BANK_ROM_CALC_MAX) { + printf("BankPack: Warning! Can't calc cart size, too many banks: %d (max %d)\n", (bank_assigned_rom_max_alltypes + 1), BANK_ROM_CALC_MAX); + return (0); + } + + // Calculate nearest upper power of 2 + while (req_banks < (bank_assigned_rom_max_alltypes + 1)) + req_banks *= 2; + + return (req_banks); +} + + +bool option_banks_set_min(uint16_t bank_num) { + if (bank_num < BANK_NUM_ROM_MIN) + return false; + else bank_limit_rom_min = bank_num; + + return true; +} + +bool option_banks_set_max(uint16_t bank_num) { + if (bank_num > BANK_NUM_ROM_MAX) + return false; + else bank_limit_rom_max = bank_num; + + return true; +} + diff --git a/gbdk-support/bankpack/options.h b/gbdk-support/bankpack/options.h @@ -0,0 +1,46 @@ +// This is free and unencumbered software released into the public domain. +// For more information, please refer to <https://unlicense.org> +// bbbbbr 2022 + + +#define ARG_BANK_RESERVE_SIZE_MAX_LEN 256u // -reserve=255:4000 +#define ARG_BANK_RESERVE_SIZE_REC_COUNT_MATCH 3u +#define ARG_BANK_RESERVE_SIZE_MAX_SPLIT_WORDS (ARG_BANK_RESERVE_SIZE_REC_COUNT_MATCH + 1u) + +#define PLATFORM_GB 0 +#define PLATFORM_SMS 1 +#define PLATFORM_DEFAULT PLATFORM_GB + +#define PLATFORM_STR_GB "gb" +#define PLATFORM_STR_AP "ap" // Uses PLATFORM_GB +#define PLATFORM_STR_DUCK "duck" // Uses PLATFORM_GB +#define PLATFORM_STR_SMS "sms" +#define PLATFORM_STR_GG "gg" // Uses PLATFORM_SMS +#define PLATFORM_STR_MSXDOS "msxdos" // Uses PLATFORM_SMS + + +void option_set_verbose(bool is_enabled); +bool option_get_verbose(void); + +void option_set_cartsize(bool is_enabled); +bool option_get_cartsize(void); + +void option_set_random_assign(bool is_enabled); +bool option_get_random_assign(void); + +int option_bank_reserve_bytes(char * arg_str); + +void option_set_platform(char * platform_str); +int option_get_platform(void); + +int option_get_mbc_type(void); +void option_set_mbc(int); +void option_mbc_by_rom_byte_149(int); + +uint32_t option_banks_calc_cart_size(void); + +bool option_banks_set_min(uint16_t bank_num); +bool option_banks_set_max(uint16_t bank_num); + +void option_banks_set_random(bool is_random); +
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.