git.y1.nz

gbdk-2020

GameBoy Development Kit
download: https://git.y1.nz/archives/gbdk.tar.gz
README | Files | Log | Refs | LICENSE

gbdk-support/bankpack/options.c

      1 // This is free and unencumbered software released into the public domain.
      2 // For more information, please refer to <https://unlicense.org>
      3 // bbbbbr 2022
      4 
      5 #include <stdio.h>
      6 #include <string.h>
      7 #include <stdlib.h>
      8 #include <unistd.h>
      9 #include <stdbool.h>
     10 #include <stdint.h>
     11 
     12 #include "common.h"
     13 #include "list.h"
     14 #include "files.h"
     15 #include "obj_data.h"
     16 #include "options.h"
     17 
     18 extern list_type banklist;
     19 extern uint16_t bank_limit_rom_min;
     20 extern uint16_t bank_limit_rom_max;
     21 extern uint16_t bank_assigned_rom_max_alltypes;
     22 
     23 bool option_verbose       = false;
     24 bool option_cartsize      = false;
     25 bool option_random_assign = false;
     26 int  option_mbc_type = MBC_TYPE_DEFAULT;
     27 int  option_platform = PLATFORM_DEFAULT;
     28 
     29 
     30 void option_set_verbose(bool is_enabled) {
     31     option_verbose = is_enabled;
     32 }
     33 bool option_get_verbose(void) {
     34     return option_verbose;
     35 }
     36 
     37 
     38 void option_set_cartsize(bool is_enabled) {
     39     option_cartsize = is_enabled;
     40 }
     41 bool option_get_cartsize(void) {
     42     return option_cartsize;
     43 }
     44 
     45 
     46 void option_set_random_assign(bool is_enabled) {
     47     option_random_assign = is_enabled;
     48 }
     49 bool option_get_random_assign(void) {
     50     return option_random_assign;
     51 }
     52 
     53 
     54 
     55 // Format: -reserve=DECIMAL_BANKNUM:HEX_SIZE
     56 // Reserve space in banks manually from command line arguments
     57 // Should be called *after* obj_data_init() has initialized banks
     58 int option_bank_reserve_bytes(char * arg_str) {
     59 
     60     bank_item * banks = (bank_item *)banklist.p_array;
     61 
     62     char cols;
     63     char * p_str;
     64     char * p_words[ARG_BANK_RESERVE_SIZE_MAX_SPLIT_WORDS];
     65     char arg_str_copy[ARG_BANK_RESERVE_SIZE_MAX_LEN]; // copy arg since strtok modifies strings it operates on
     66     snprintf(arg_str_copy, sizeof(arg_str_copy), "%s", arg_str);
     67 
     68     // Split string into words using "-:=" as delimiters
     69     cols = 0;
     70     p_str = strtok(arg_str_copy,"-:=");
     71     while (p_str != NULL)
     72     {
     73         p_words[cols++] = p_str;
     74         p_str = strtok(NULL, "-:=");
     75         if (cols >= ARG_BANK_RESERVE_SIZE_MAX_SPLIT_WORDS) break;
     76     }
     77 
     78     if (cols == ARG_BANK_RESERVE_SIZE_REC_COUNT_MATCH) {
     79 
     80         uint32_t reserve_bank = strtol(p_words[1], NULL, 10); // [1] Decimal Bank Number
     81         uint32_t reserve_size = strtol(p_words[2], NULL, 16); // [2] Hex Reserve Size
     82 
     83         if ((reserve_bank < BANK_NUM_ROM_MIN) || (reserve_bank > BANK_NUM_ROM_MAX)) {
     84             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);
     85             exit(EXIT_FAILURE);
     86         }
     87 
     88         if (reserve_size > BANK_SIZE_ROM_MAX) {
     89             printf("BankPack: ERROR! Size value %x for %s is too large (max:%x)\n", reserve_size, arg_str, BANK_SIZE_ROM_MAX);
     90             exit(EXIT_FAILURE);
     91         }
     92 
     93         if (reserve_size > banks[reserve_bank].free) {
     94             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);
     95             exit(EXIT_FAILURE);
     96         }
     97 
     98         // printf("Bankpack: Reserving %x bytes for bank %d (%s)\n", reserve_size, reserve_bank, arg_str);
     99 
    100         // Params were valid, deduct the space from the bank
    101         banks[reserve_bank].free -= reserve_size;
    102         banks[reserve_bank].reserved += reserve_size;
    103         return true;
    104     } else
    105         return false; // Signal failure
    106 
    107 }
    108 
    109 
    110 // Format: -banktype=DECIMAL_BANKNUM:BANK_TYPE_STRING
    111 // Force a given bank to a specific type (mainly for SMS/GG with CODE and LIT types)
    112 // Should be called *after* obj_data_init() has initialized banks
    113 int option_bank_set_type(char * arg_str) {
    114 
    115     bank_item * banks = (bank_item *)banklist.p_array;
    116 
    117     char cols;
    118     char * p_str;
    119     char * p_words[ARG_BANK_SET_TYPE_MAX_SPLIT_WORDS];
    120     char arg_str_copy[ARG_BANK_SET_TYPE_MAX_LEN]; // copy arg since strtok modifies strings it operates on
    121     snprintf(arg_str_copy, sizeof(arg_str_copy), "%s", arg_str);
    122 
    123     // Split string into words using "-:=" as delimiters
    124     cols = 0;
    125     p_str = strtok(arg_str_copy,"-:=");
    126     while (p_str != NULL)
    127     {
    128         p_words[cols++] = p_str;
    129         p_str = strtok(NULL, "-:=");
    130         if (cols >= ARG_BANK_SET_TYPE_MAX_SPLIT_WORDS) break;
    131     }
    132 
    133     if (cols == ARG_BANK_SET_TYPE_REC_COUNT_MATCH) {
    134 
    135         uint32_t bank_num = strtol(p_words[1], NULL, 10); // [1] Decimal Bank Number
    136         uint32_t bank_type = BANK_TYPE_UNSET;
    137 
    138         if (strncmp(p_words[2], "CODE", strlen("CODE") + 1) == 0) {
    139             bank_type = BANK_TYPE_CODE;
    140         } else if (strncmp(p_words[2], "LIT", strlen("LIT") + 1) == 0) {
    141             bank_type = BANK_TYPE_LIT_EXCLUSIVE;
    142         } else {
    143             printf("BankPack: ERROR! Bank type %s for %s is invalid\n", p_words[2], arg_str);
    144             exit(EXIT_FAILURE);
    145         }
    146 
    147         if ((bank_num < BANK_NUM_ROM_MIN) || (bank_num > BANK_NUM_ROM_MAX)) {
    148             printf("BankPack: ERROR! Bank number %d for %s is invalid (min: %d, max: %d)\n", bank_num, arg_str, BANK_NUM_ROM_MIN, BANK_NUM_ROM_MAX);
    149             exit(EXIT_FAILURE);
    150         }
    151 
    152         // Params were valid, set the bank type
    153         banks[bank_num].type = bank_type;
    154         return true;
    155     } else
    156         return false; // Signal failure
    157 }
    158 
    159 
    160 int option_get_platform(void) {
    161     return option_platform;
    162 }
    163 
    164 
    165 void option_set_platform(char * platform_str) {
    166 
    167     if (strcmp(platform_str, PLATFORM_STR_GB) == 0)
    168         option_platform = PLATFORM_GB;
    169     else if (strcmp(platform_str, PLATFORM_STR_AP) == 0)
    170         option_platform = PLATFORM_GB;  // Analogue Pocket uses GB platform
    171     else if (strcmp(platform_str, PLATFORM_STR_DUCK) == 0)
    172         option_platform = PLATFORM_GB;  // Megaduck uses GB platform
    173     else if (strcmp(platform_str, PLATFORM_STR_NES) == 0)
    174         option_platform = PLATFORM_GB;  // NES uses GB platform
    175     else if (strcmp(platform_str, PLATFORM_STR_SMS) == 0)
    176         option_platform = PLATFORM_SMS;
    177     else if (strcmp(platform_str, PLATFORM_STR_GG) == 0)
    178         option_platform = PLATFORM_SMS; // GG uses SMS platform
    179     else if (strcmp(platform_str, PLATFORM_STR_MSXDOS) == 0)
    180         option_platform = PLATFORM_SMS; // MSXDOS uses SMS platform
    181     else
    182         printf("BankPack: Warning: Invalid platform option %s\n", platform_str);
    183 }
    184 
    185 
    186 
    187 int option_get_mbc_type(void) {
    188     return option_mbc_type;
    189 }
    190 
    191 
    192 // Set MBC type by interpreting from byte 149
    193 //
    194 //  For lcc linker option: -Wl-ytN where N is one of the numbers below
    195 //
    196 // | Hex Code | MBC Type      | SRAM | Battery | RTC | Extra Feature   | Max ROM Size (1)|Max SRAM Size   |
    197 // | -------- | ------------- | ---- | ------- | --- | --------------- | --------------- |--------------- |
    198 // | 0x00     | ROM ONLY      |      |         |     |                 | 32 K            |0               |
    199 // | 0x01     | MBC-1 (2)     |      |         |     |                 | 2 MB            |0               |
    200 // | 0x02     | MBC-1 (2)     | SRAM |         |     |                 | 2 MB            |32 K (5)        |
    201 // | 0x03     | MBC-1 (2)     | SRAM | BATTERY |     |                 | 2 MB            |32 K (5)        |
    202 // | 0x05     | MBC-2         |      |         |     |                 | 256 K           |512 x 4 bits (6)|
    203 // | 0x06     | MBC-2         |      | BATTERY |     |                 | 256 K           |512 x 4 bits (6)|
    204 // | 0x08     | ROM (3)       | SRAM |         |     |                 | 32 K            |8 K             |
    205 // | 0x09     | ROM (3)       | SRAM | BATTERY |     |                 | 32 K            |8 K             |
    206 // | 0x0B     | MMM01         |      |         |     |                 | 8 MB / N        |                |
    207 // | 0x0C     | MMM01         | SRAM |         |     |                 | 8 MB / N        |128K / N        |
    208 // | 0x0D     | MMM01         | SRAM | BATTERY |     |                 | 8 MB / N        |128K / N        |
    209 // | 0x0F     | MBC-3         |      | BATTERY | RTC |                 | 2 MB            |                |
    210 // | 0x10     | MBC-3 (4)     | SRAM | BATTERY | RTC |                 | 2 MB            |32 K            |
    211 // | 0x11     | MBC-3         |      |         |     |                 | 2 MB            |                |
    212 // | 0x12     | MBC-3 (4)     | SRAM |         |     |                 | 2 MB            |32 K            |
    213 // | 0x13     | MBC-3 (4)     | SRAM | BATTERY |     |                 | 2 MB            |32 K            |
    214 // | 0x19     | MBC-5         |      |         |     |                 | 8 MB            |                |
    215 // | 0x1A     | MBC-5         | SRAM |         |     |                 | 8 MB            |128 K           |
    216 // | 0x1B     | MBC-5         | SRAM | BATTERY |     |                 | 8 MB            |128 K           |
    217 // | 0x1C     | MBC-5         |      |         |     | RUMBLE          | 8 MB            |                |
    218 // | 0x1D     | MBC-5         | SRAM |         |     | RUMBLE          | 8 MB            |128 K           |
    219 // | 0x1E     | MBC-5         | SRAM | BATTERY |     | RUMBLE          | 8 MB            |128 K           |
    220 // | 0x20     | MBC-6         |      |         |     |                 | ~2MB            |                |
    221 // | 0x22     | MBC-7         |EEPROM|         |     | ACCELEROMETER   | 2MB             |256 byte EEPROM |
    222 // | 0xFC     | POCKET CAMERA |      |         |     |                 | 1MB             |128KB RAM       |
    223 // | 0xFD     | BANDAI TAMA5  |      |         |     |                 | To Do           |To Do           |
    224 // | 0xFE     | HuC3          |      |         | RTC |                 | To Do           |To Do           |
    225 // | 0xFF     | HuC1          | SRAM | BATTERY |     | IR              | To Do           |To Do           |
    226 void option_mbc_by_rom_byte_149(int mbc_type_rom_byte) {
    227 
    228     switch (mbc_type_rom_byte) {
    229         // NO MBC
    230         case 0x00u: //  0-ROM ONLY
    231         case 0x08u: //  2-ROM+MBC1+RAM
    232         case 0x09u: //  8-ROM+RAM
    233         case 0x0Bu: //  B-ROM+MMM01
    234         case 0x0Cu: //  C-ROM+MMM01+SRAM
    235         case 0x0Du: //  D-ROM+MMM01+SRAM+BATT
    236             option_set_mbc(MBC_TYPE_NONE);
    237             break;
    238 
    239         // MBC 1
    240         case 0x01u: //  1-ROM+MBC1
    241         case 0x02u: //  2-ROM+MBC1+RAM
    242         case 0x03u: //  3-ROM+MBC1+RAM+BATT
    243             option_set_mbc(MBC_TYPE_MBC1);
    244             break;
    245 
    246         // MBC 2
    247         case 0x05u: //  5-ROM+MBC2
    248         case 0x06u: //  6-ROM+MBC2+BATTERY
    249             option_set_mbc(MBC_TYPE_MBC2);
    250             break;
    251 
    252         // MBC 3
    253         case 0x0Fu: //  F-ROM+MBC3+TIMER+BATT
    254         case 0x10u: //  10-ROM+MBC3+TIMER+RAM+BATT
    255         case 0x11u: //  11-ROM+MBC3
    256         case 0x12u: //  12-ROM+MBC3+RAM
    257         case 0x13u: //  13-ROM+MBC3+RAM+BATT
    258         case 0xFCu: //  FC-GAME BOY CAMERA
    259             option_set_mbc(MBC_TYPE_MBC3);
    260             break;
    261 
    262         // MBC 5
    263         case 0x19u: //  19-ROM+MBC5
    264         case 0x1Au: //  1A-ROM+MBC5+RAM
    265         case 0x1Bu: //  1B-ROM+MBC5+RAM+BATT
    266         case 0x1Cu: //  1C-ROM+MBC5+RUMBLE
    267         case 0x1Du: //  1D-ROM+MBC5+RUMBLE+SRAM
    268         case 0x1Eu: //  1E-ROM+MBC5+RUMBLE+SRAM+BATT
    269             option_set_mbc(MBC_TYPE_MBC5);
    270             break;
    271 
    272         // MBC 7
    273         case 0x22u: //  22-MBC-7 +ACCELEROMETER +EEPROM : 2MB ROM, 256 byte EEPROM
    274             option_set_mbc(MBC_TYPE_MBC7);
    275             break;
    276 
    277         default:
    278             printf("BankPack: Warning: unrecognized MBC option -yt=%x\n", mbc_type_rom_byte);
    279             break;
    280     }
    281 }
    282 
    283 
    284 // Set MBC type directly
    285 void option_set_mbc(int mbc_type) {
    286 
    287     uint16_t mbc_bank_limit_rom_max;
    288 
    289     switch (mbc_type) {
    290         case MBC_TYPE_NONE:
    291             option_mbc_type = MBC_TYPE_NONE;
    292             break;
    293         case MBC_TYPE_MBC1:
    294             option_mbc_type = mbc_type;
    295             mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC1;
    296             break;
    297         case MBC_TYPE_MBC2:
    298             option_mbc_type = mbc_type;
    299             mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC2;
    300             break;
    301         case MBC_TYPE_MBC3:
    302             option_mbc_type = mbc_type;
    303             mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC3;
    304             break;
    305         case MBC_TYPE_MBC5:
    306             option_mbc_type = mbc_type;
    307             mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC5;
    308             break;
    309         case MBC_TYPE_MBC7:
    310             option_mbc_type = mbc_type;
    311             mbc_bank_limit_rom_max = BANK_NUM_ROM_MAX_MBC7;
    312             break;
    313         default:
    314             printf("BankPack: Warning: unrecognized MBC option -mbc%d!\n", mbc_type);
    315             break;
    316     }
    317     if (mbc_bank_limit_rom_max < bank_limit_rom_max)
    318         bank_limit_rom_max = mbc_bank_limit_rom_max;
    319 }
    320 
    321 // Set NES mapper type directly
    322 void option_set_nes_mapper(int mapper_type) {
    323 
    324     uint16_t mapper_bank_limit_rom_max;
    325 
    326     switch (mapper_type) {
    327     case NES_MAPPER_TYPE_NONE:
    328         option_mbc_type = NES_MAPPER_TYPE_NONE;
    329         break;
    330     case NES_MAPPER_TYPE_UXROM:
    331         option_mbc_type = mapper_type;
    332         mapper_bank_limit_rom_max = BANK_NUM_ROM_MAX_UXROM;
    333         break;
    334     case NES_MAPPER_TYPE_MAPPER30:
    335         option_mbc_type = mapper_type;
    336         mapper_bank_limit_rom_max = BANK_NUM_ROM_MAX_MAPPER30;
    337         break;
    338     default:
    339         printf("BankPack: Warning: unrecognized NES mapper option -mapper%d!\n", mapper_type);
    340         break;
    341     }
    342     if (mapper_bank_limit_rom_max < bank_limit_rom_max)
    343         bank_limit_rom_max = mapper_bank_limit_rom_max;
    344 }
    345 
    346 // From makebin
    347 //  Byte
    348 //  0148 - ROM size             -yt<N>
    349 //  0    - 256Kbit = 32KByte  =   2 banks
    350 //  1    - 512Kbit = 64KByte  =   4 banks
    351 //  2    - 1Mbit   = 128KByte =   8 banks
    352 //  3    - 2Mbit   = 256KByte =  16 banks
    353 //  4    - 4Mbit   = 512KByte =  32 banks
    354 //  5    - 8Mbit   = 1MByte   =  64 banks
    355 //  6    - 16Mbit  = 2MByte   = 128 banks
    356 //  7    - 16Mbit  = 2MByte   = 256 banks
    357 //  8    - 16Mbit  = 2MByte   = 512 banks
    358 //
    359 //  Not supported by makebin:
    360 //  $52 - 9Mbit = 1.1MByte = 72 banks
    361 //  $53 - 10Mbit = 1.2MByte = 80 banks
    362 //  $54 - 12Mbit = 1.5MByte = 96 banks
    363 uint32_t option_banks_calc_cart_size(void) {
    364 
    365     uint32_t req_banks = 1;
    366 
    367     if ((bank_assigned_rom_max_alltypes + 1) > BANK_ROM_CALC_MAX) {
    368         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);
    369         return (0);
    370     }
    371 
    372     // Calculate nearest upper power of 2
    373     while (req_banks < (bank_assigned_rom_max_alltypes + 1))
    374         req_banks *= 2;
    375 
    376     return (req_banks);
    377 }
    378 
    379 
    380 bool option_banks_set_min(uint16_t bank_num) {
    381     if (bank_num < BANK_NUM_ROM_MIN)
    382         return false;
    383     else bank_limit_rom_min = bank_num;
    384 
    385     return true;
    386 }
    387 
    388 bool option_banks_set_max(uint16_t bank_num) {
    389     if (bank_num > BANK_NUM_ROM_MAX)
    390         return false;
    391     else bank_limit_rom_max = bank_num;
    392 
    393     return true;
    394 }
    395 

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.