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/bankpack.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 2020
      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 #include <time.h>
     12 
     13 #include "obj_data.h"
     14 #include "files.h"
     15 #include "options.h"
     16 
     17 static void display_help(void);
     18 static int handle_args(int argc, char * argv[]);
     19 static void init(void);
     20 void cleanup(void);
     21 
     22 
     23 static void display_help(void) {
     24     fprintf(stdout,
     25        "bankalloc [options] objfile1 objfile2 etc\n"
     26        "Use: Read .o files and auto-assign areas with bank=255.\n"
     27        "     Typically called by Lcc compiler driver before linker.\n"
     28        "\n"
     29        "Options\n"
     30        "-h             : Show this help\n"
     31        "-lkin=<file>   : Load object files specified in linker file <file>\n"
     32        "-lkout=<file>  : Write list of object files out to linker file <file>\n"
     33        "-yt<mbctype>   : Set MBC type per ROM byte 149 in Decimal or Hex (0xNN)\n"
     34        "                ([see pandocs](https://gbdev.io/pandocs/The_Cartridge_Header.html#0147---cartridge-type))\n"
     35        "-mbc=N         : Similar to -yt, but sets MBC type directly to N instead\n"
     36        "                of by intepreting ROM byte 149\n"
     37        "                mbc1 will exclude banks {0x20,0x40,0x60} max=127, \n"
     38        "                mbc2 max=15, mbc3 max=127, mbc5 max=255 (not 511!) \n"
     39        "-min=N         : Min assigned ROM bank is N (default 1)\n"
     40        "-max=N         : Max assigned ROM bank is N, error if exceeded\n"
     41        "-ext=<.ext>    : Write files out with <.ext> instead of source extension\n"
     42        "-path=<path>   : Write files out to <path> (<path> *MUST* already exist)\n"
     43        "-sym=<prefix>  : Add symbols starting with <prefix> to match + update list\n"
     44        "                 Default entry is \"___bank_\" (see below)\n"
     45        "-cartsize      : Print min required cart size as \"autocartsize:<NNN>\"\n"
     46        "-plat=<plat>   : Select platform specific behavior (default:gb) (gb,sms)\n"
     47        "-random        : Distribute banks randomly for testing (honors -min/-max)\n"
     48        "-reserve=<b:n> : Reserve N bytes (hex) in bank B (decimal)\n"
     49        "                 Ex: -reserve=105:30F reserves 0x30F bytes in bank 105\n"
     50        "-banktype=<b:t>: Set bank B (decimal) to use type T (CODE or LIT). For sms/gg\n"
     51        "                 Ex: -banktype=2:LIT sets bank 2 to type LIT\n"
     52        "-v             : Verbose output, show assignments\n"
     53        "\n"
     54        "Example: \"bankpack -ext=.rel -path=some/newpath/ file1.o file2.o\"\n"
     55        "Unless -ext or -path specify otherwise, input files are overwritten.\n"
     56        "\n"
     57        "Default MBC type is not set. It *must* be specified by -mbc= or -yt!\n"
     58        "\n"
     59        "The following will have FF and 255 replaced with the assigned bank:\n"
     60        "A _CODE_255 size <size> flags <flags> addr <address>\n"
     61        "S b_<function name> Def0000FF\n"
     62        "S ___bank_<const name> Def0000FF\n"
     63        "    (Above can be made by: const void __at(255) __bank_<const name>;\n"
     64        );
     65 }
     66 
     67 
     68 static int handle_args(int argc, char * argv[]) {
     69 
     70     int i;
     71 
     72     if( argc < 2 ) {
     73         display_help();
     74         return false;
     75     }
     76 
     77     // Start at first optional argument, argc is zero based
     78     for (i = 1; i <= (argc -1); i++ ) {
     79 
     80         if (argv[i][0] == '-') {
     81             if (strstr(argv[i], "-h") == argv[i]) {
     82                 display_help();
     83                 return false;  // Don't parse input when -h is used
     84             } else if (strstr(argv[i], "-min=") == argv[i]) {
     85                 if (!option_banks_set_min(atoi(argv[i] + 5))) {
     86                     printf("BankPack: ERROR: Invalid min bank: %s\n", argv[i] + 5);
     87                     return false;
     88                 }
     89             } else if (strstr(argv[i], "-max=") == argv[i]) {
     90                 if (!option_banks_set_max(atoi(argv[i] + 5))) {
     91                     printf("BankPack: ERROR: Invalid max bank: %s\n", argv[i] + 5);
     92                     return false;
     93                 }
     94             } else if (strstr(argv[i], "-ext=") == argv[i]) {
     95                 files_set_out_ext(argv[i] + 5);
     96             } else if (strstr(argv[i], "-path=") == argv[i]) {
     97                 files_set_out_path(argv[i] + 6);
     98             } else if (strstr(argv[i], "-mbc=") == argv[i]) {
     99                 option_set_mbc(atoi(argv[i] + 5));
    100             } else if (strstr(argv[i], "-mapper=") == argv[i]) {
    101                 option_set_nes_mapper(atoi(argv[i] + 8));
    102             } else if (strstr(argv[i], "-yt") == argv[i]) {
    103                 option_mbc_by_rom_byte_149(strtol(argv[i] + 3, NULL, 0));
    104             } else if (strstr(argv[i], "-v") == argv[i]) {
    105                 option_set_verbose(true);
    106             } else if (strstr(argv[i], "-sym=") == argv[i]) {
    107                 symbol_match_add(argv[i] + 5);
    108             } else if (strstr(argv[i], "-cartsize") == argv[i]) {
    109                 option_set_cartsize(true);
    110             } else if (strstr(argv[i], "-plat=") == argv[i]) {
    111                 option_set_platform(argv[i] + 6);
    112             } else if (strstr(argv[i], "-random") == argv[i]) {
    113                 option_set_random_assign(true);
    114             } else if (strstr(argv[i], "-lkin=") == argv[i]) {
    115                 files_read_linkerfile(argv[i] + strlen("-lkin="));
    116             } else if (strstr(argv[i], "-lkout=") == argv[i]) {
    117                 files_set_linkerfile_outname(argv[i] + strlen("-lkout="));
    118             } else if (strstr(argv[i], "-reserve=") == argv[i]) {
    119                 if (!option_bank_reserve_bytes(argv[i])) {
    120                     fprintf(stdout,"BankPack: ERROR! Malformed argument: %s\n\n", argv[i]);
    121                     display_help();
    122                     return false;
    123                 }
    124             } else if (strstr(argv[i], "-banktype=") == argv[i]) {
    125                 if (!option_bank_set_type(argv[i])) {
    126                     fprintf(stdout,"BankPack: ERROR! Malformed argument: %s\n\n", argv[i]);
    127                     display_help();
    128                     return false;
    129                 }
    130             } else {
    131                 printf("BankPack: Warning: Ignoring unknown option %s\n", argv[i]);
    132             }
    133         } else {
    134             // Add to list of object files to process
    135             files_add(argv[i]);
    136         }
    137     }
    138 
    139     return true;
    140 }
    141 
    142 
    143 static int matches_extension(char * filename, char * extension) {
    144     return (strcmp(filename + (strlen(filename) - strlen(extension)), extension) == 0);
    145 }
    146 
    147 
    148 static void init(void) {
    149     srand( time(0) );
    150     files_init();
    151     obj_data_init();
    152 }
    153 
    154 
    155 void cleanup(void) {
    156     files_cleanup();
    157     obj_data_cleanup();
    158 }
    159 
    160 
    161 int main( int argc, char *argv[] )  {
    162 
    163     // Exit with failure by default
    164     int ret = EXIT_FAILURE;
    165 
    166     // Register cleanup with exit handler
    167     atexit(cleanup);
    168 
    169     init();
    170 
    171     if (handle_args(argc, argv)) {
    172 
    173         // Require MBC for Game Boy
    174         // SMS doesn't require an MBC setting
    175         if ((option_get_platform() == PLATFORM_GB) && (option_get_mbc_type() == MBC_TYPE_NONE))
    176             printf("BankPack: ERROR: auto-banking does not work with nonbanked ROMS (no MBC for Game Boy)\n");
    177         else {
    178             // Extract areas, sort and assign them to banks
    179             // then rewrite object files as needed
    180             files_extract();
    181             files_rewrite();
    182 
    183             if (option_get_verbose())
    184                 banks_show();
    185             if (option_get_cartsize())
    186                 fprintf(stdout,"autocartsize:%d\n",option_banks_calc_cart_size());
    187 
    188             cleanup();
    189             ret = EXIT_SUCCESS;
    190         }
    191     }
    192 
    193     return ret; // Exit with failure by default
    194 }

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