git.y1.nz

gbdk-2020

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

docs/pages/06_toolchain.md

      1 @page docs_toolchain GBDK Toolchain
      2 
      3 
      4 @anchor toolchain_overview
      5 # Overview
      6 GBDK 2020 uses the SDCC compiler along with some custom tools to build Game Boy ROMs.
      7 - All tools are located under `bin/`
      8 - The typical order of tools called is as follows (when using lcc these steps are usually performed automatically).
      9   1. Compile and assemble source files (.c, .s, .asm) with @ref sdcc and @ref sdasgb
     10   2. Optional: perform auto banking with @ref bankpack on the object files
     11   3. Link the object files into .ihx file with @ref sdldgb
     12   4. Validate the .ihx file with @ref ihxcheck
     13   5. Convert the .ihx file to a ROM file (.gb, .gbc) with @ref makebin
     14 
     15 To see individual arguments and options for a tool, run that tool from the command line with either no arguments or with `-h`.
     16 
     17 
     18 # Data Types
     19 For data types and special C keywords, see @ref file_asm_sm83_types_h "asm/sm83/types.h" and @ref file_asm_types_h "asm/types.h".
     20 
     21 Also see the SDCC manual (scroll down a little on the linked page): http://sdcc.sourceforge.net/doc/sdccman.pdf#section.1.1
     22 
     23 ## Using variables in High RAM on the Game Boy
     24 The High RAM (`_HRAM`) address space is at `0xFF80 - 0xFFFE`. It is eight bit addressable using the `ldh` opcodes which allow for more efficient read and write access.
     25 
     26 There are two main ways variables can be placed into High RAM
     27 - Using the `SFR` keyword
     28   - For example: `SFR my_hram_variable;`
     29   - Variables will be allocated in the `_HRAM` area
     30   - They will be treated as 8-bit unsigned
     31   - The compiler will automatically tag the variable as `volatile`
     32   - The codegen will try to optimize them with `ldh` access
     33 - Using the `dataseg` pragma
     34   - For example: `#pragma dataseg HRAM` followed by `unsigned char my_dataseg_var;`
     35   - The codegen **will not** try to optimize them with `ldh` access
     36 
     37 
     38 @anchor toolchain_changing_important_addresses 
     39 # Changing Important Addresses
     40 It is possible to change some of the important addresses used by the toolchain at link time using the -Wl-g XXX=YYY and =Wl-b XXX=YYY flags (where XXX is the name of the data, and YYY is the new address). 
     41 
     42 @ref lcc will include the following linker defaults for @ref sdldgb if they are not defined by the user.
     43 
     44   - `_shadow_OAM`
     45     - Location of sprite ram (requires 0xA0 bytes).
     46     - Default `-Wl-g _shadow_OAM=0xC000`
     47 
     48   - `.STACK`
     49     - Initial stack address
     50     - Default `-Wl-g .STACK=0xE000`
     51 
     52   - `.refresh_OAM`
     53     - Address to which the routine for refreshing OAM will be copied (must be in HIRAM). Default
     54     - Default `-Wl-g .refresh_OAM=0xFF80`
     55 
     56   - `_DATA`
     57     - Start of RAM section (starts after Shadow OAM)
     58     - Default `-Wl-b _DATA=0xc0A0`
     59 
     60   - `_CODE`
     61     - Start of ROM section
     62     - Default `-Wl-b _CODE=0x0200`
     63 
     64 
     65 @anchor toolchain_compiling_programs
     66 # Compiling programs
     67 
     68 The @ref lcc program is the front end compiler driver for the actual compiler, assembler and linker. It works out what you want to do based on command line options and the extensions of the files you give it, computes the order in which the various programs must be called and then executes them in order. Some examples are:
     69 
     70   - Compile the C source 'source.c', assemble and link it producing the Gameboy image 'image.gb'
     71 
     72         lcc -o image.gb source.c
     73 
     74   - Assemble the file 'source.s' and link it producing the Gameboy image 'image.gb'
     75 
     76         lcc -o image.gb source.s
     77 
     78   - Compile the C program 'source1.c' and assemble it producing the object file 'object1.o' for later linking.
     79 
     80         lcc -c -o object1.o source1.c
     81 
     82   - Assemble the file 'source2.s' producing the object file 'object2.o' for later linking
     83 
     84         lcc -c -o object2.o source2.s
     85 
     86   - Link the two object files 'object1.o' and 'object2.o' and produce the Gameboy image 'image.gb'
     87 
     88         lcc -o image.gb object1.o object2.o
     89 
     90   - Do all sorts of clever stuff by compiling then assembling source1.c, assembling source2.s and then linking them together to produce image.gb. 
     91 
     92         lcc -o image.gb source1.c source2.s
     93 
     94 Arguments to the assembler, linker, etc can be passed via lcc using -Wp..., -Wf..., -Wa... and -Wl... to pass options to the pre-processor, compiler, assembler and linker respectively. Some common options are:
     95 
     96   - To generate an assembler listing file.
     97 
     98         -Wa-l
     99 
    100   - To generate a linker map file.
    101 
    102         -Wl-m
    103 
    104   - To bind var to address 'addr' at link time.
    105 
    106         -Wl-gvar=addr
    107 
    108 For example, to compile the example in the memory section and to generate a listing and map file you would use the following. Note the leading underscore that C adds to symbol names.
    109 
    110     lcc -Wa-l -Wl-m -Wl-g_snd_stat=0xff26 -o image.gb hardware.c
    111 
    112 
    113 @subsection Makefiles
    114 ## Using Makefiles
    115 
    116 Please see the sample projects included with GBDK-2020 for a couple different examples of how to use Makefiles.
    117 
    118 You may also want to read a tutorial on Makefiles. For example:  
    119 https://makefiletutorial.com/  
    120 https://www.tutorialspoint.com/makefile/index.htm
    121 
    122 @anchor linkerfiles_and_autobanking
    123 ## Linker Files and ROM Auto Banking
    124 
    125 When @ref bankpack is called through @ref lcc it will now always use linkerfile output (`-lkout=`) for passing files to the linker (all input object files and linkerfiles will get get consolidated to a single linkerfile).
    126 
    127 Bankpack:
    128 - `lkin=<filename>` : Adds a input linkerfile (can specify multiple ones)
    129 - `-lkout=<filename>` : Enables linkerfile output and sets name (only one can be specified). ALL loaded object files, both from the command line and any loaded from linkerfiles will have their names written to this single output.
    130 
    131 LCC + Bankpack:
    132 - `lcc` passes all input linkerfiles (from `-Wl-f<name>`) to bankpack (`-lkin=`)
    133 - Linkerfile output is always used when lcc calls `bankpack` (`-lkout=`)
    134 - A temporary file name is used for bankpack linkerfile output.
    135 - `lcc` clears out the linker object file and linkerfile lists, then uses the single linkerfile generated by `bankpack`
    136 
    137 Also see the `linkerfile` example project.
    138 
    139 
    140 @anchor build_tools
    141 # Build Tools
    142 
    143 @anchor lcc
    144 ## lcc
    145 lcc is the compiler driver (front end) for the GBDK/sdcc toolchain.
    146 
    147 For detailed settings see @ref lcc-settings
    148 
    149 It can be used to invoke all the tools needed for building a rom.
    150 If preferred, the individual tools can be called directly.
    151 - the `-v` flag can be used to show the exact steps lcc executes for a build
    152 - lcc can compile, link and generate a binary in a single pass: `lcc -o somerom.gb somesource.c`
    153 - @anchor lcc_debug
    154   lcc now has a `-debug` flag that will turn on the following recommended flags for debugging
    155     - `--debug` for sdcc (lcc equiv: `-Wf-debug`)
    156     - `-y` enables .cdb output for @ref sdldgb (lcc equiv: `-Wl-y`)
    157     - `-j` enables .noi output for @ref sdldgb (lcc equiv: `-Wl-j`)
    158 
    159 
    160 @anchor sdcc
    161 ## sdcc
    162 SDCC C Source compiler.
    163 
    164 For detailed settings see @ref sdcc-settings
    165 
    166 - Arguments can be passed to it through @ref lcc using `-Wf-<argument>` and `-Wp-<argument>` (pre-processor)
    167 
    168 @anchor sdasgb
    169 ## sdasgb
    170 SDCC Assembler for the Game Boy.
    171 
    172 For detailed settings see @ref sdasgb-settings
    173 
    174 - Arguments can be passed to it through @ref lcc using `-Wa-<argument>`
    175 
    176 
    177 @anchor bankpack
    178 ## bankpack
    179 Automatic Bank packer.
    180 
    181 For detailed settings see @ref bankpack-settings
    182 
    183 When enabled, automatically assigns banks for object files where bank has been set to `255`, see @ref rom_autobanking.
    184 Unless an alternative output is specified the given object files are updated with the new bank numbers.
    185 - Can be enabled by using the `-autobank` argument with @ref lcc.
    186 - Must be called after compiling/assembling and before linking.
    187 - Arguments can be passed to it through @ref lcc using `-Wb-<argument>`
    188 
    189 
    190 @anchor sdldgb
    191 ## sdldgb
    192 The SDCC linker for the gameboy.
    193 
    194 For detailed settings see @ref sdldgb-settings
    195 
    196 Links object files (.o) into a .ihx file which can be processed by @ref makebin
    197 - Arguments can be passed to it through @ref lcc using `-Wl-<argument>`
    198 
    199 
    200 @anchor ihxcheck
    201 ## ihxcheck
    202 IHX file validator.
    203 
    204 For detailed settings see @ref ihxcheck-settings
    205 
    206 Checks .ihx files produced by @ref sdldgb for correctness.
    207 - It will warn if there are multiple writes to the same ROM address. This may indicate mistakes in the code or ROM bank overflows
    208 - Arguments can be passed to it through @ref lcc using `-Wi-<argument>`
    209 
    210 
    211 @anchor makebin
    212 ## makebin
    213 IHX to ROM converter.
    214 
    215 - For detailed settings see @ref makebin-settings
    216 - For makebin `-yt` MBC values see @ref setting_mbc_and_rom_ram_banks
    217 
    218 Converts .ihx files produced by @ref sdldgb into ROM files (.gb, .gbc). Also used for setting some ROM header data.
    219 - Arguments can be passed to it through @ref lcc using `-Wm-<argument>`
    220 
    221 
    222 @anchor gbdk_utilities
    223 # GBDK Utilities
    224 
    225 
    226 @anchor utility_gbcompress
    227 ## GBCompress
    228 Compression utility.
    229 
    230 For detailed settings see @ref gbcompress-settings
    231 
    232 Compresses (and decompresses) binary file data with the gbcompress algorithm (also used in GBTD/GBMB). Decompression support is available in GBDK:
    233 - gb_decompress(), gb_decompress_bkg_data(),  gb_decompress_win_data(), gb_decompress_sprite_data()
    234 - The `cross-platform/gbdecompress` example demonstrates how to use this compression
    235 
    236 
    237 The utility can also compress (and decompress) using block style RLE encoding with the `--alg=rle` flag. Decompression support is available in GBDK:
    238 - rle_init(), rle_decompress()
    239 - The `cross-platform/rle_map` example demonstrates how to use this compression
    240 
    241 
    242 @anchor utility_png2asset
    243 ## png2asset
    244 Tool for converting PNGs into GBDK format MetaSprites and Tile Maps.
    245 
    246 - Convert single or multiple frames of graphics into metasprite structured data for use with the ...metasprite...() functions.
    247 - When `-map` is used, converts images into Tile Maps and matching Tile Sets
    248 - Supports Game Boy / Color, SGB borders, SMS/GG, NES
    249 
    250 For detailed settings see @ref png2asset-settings  
    251 For working with sprite properties (including cgb palettes), see @ref metasprite_and_sprite_properties  
    252 For API support see @ref move_metasprite() and related functions in @ref metasprites.h  
    253 
    254 ### Working with png2asset
    255   - The origin (pivot) for the metasprite is not required to be in the upper left-hand corner as with regular hardware sprites. See `-px` and `-py`.
    256 
    257   - The conversion process supports using both SPRITES_8x8 (`-spr8x8`) and SPRITES_8x16 mode (`-spr8x16`). If 8x16 mode is used then the height of the metasprite must be a multiple of 16.
    258 
    259 #### Terminology
    260 The following abbreviations are used in this section:
    261 * Original Game Boy and Game Boy Pocket style hardware: `DMG`
    262 * Game Boy Color: `CGB`
    263 
    264 #### Conversion Process
    265 png2asset accepts any png as input, although that does not mean any image will be valid. The program will follow the next steps:
    266   - The image will be subdivided into tiles of 8x8 or 8x16.
    267   - For each tile a palette will be generated.
    268   - If there are more than 4 colors in the palette it will throw an error.
    269   - The palette will be sorted from darkest to lightest. If there is a transparent color that will be the first one (this will create a palette that will also work with `DMG` devices).
    270   - If there are more than 8 palettes the program will throw an error.
    271 
    272 With all this, the program will generate a new indexed image (with palette), where each 4 colors define a palette and all colors within a tile can only have colors from one of these palettes
    273 
    274 It is also posible to pass a indexed 8-bit png with the palette properly sorted out, using `-keep_palette_order`
    275   - Palettes will be extracted from the image palette in groups of 4 colors.
    276   - Each tile can only have colors from one of these palettes per tile.
    277   - The maximum number of colors is 32.
    278 
    279 For indexed color images, sometimes RGB paint programs mix up indexed colors in tiles if the same color exists in multiple palettes.
    280   - `-repair_indexed_pal` can be used to fix this problem, though tiles must still follow the rule of using only one palette per tile.
    281   
    282 Using this image a tileset will be created
    283   - Duplicated tiles will be removed.
    284   - Tiles will be matched without mirror, using vertical mirror, horizontal mirror or both (use `-noflip` to turn off matching mirrored tiles).
    285   - The palette won't be taken into account for matching, only the pixel color order, meaning there will be a match between tiles using different palettes but looking identical on grayscale.
    286 
    287 
    288 #### Maps
    289 Passing `-map` the png can be converted to a map that can be used in both the background and the window. In this case, png2asset will generate:
    290   - The palettes
    291   - The tileset
    292   - The map
    293   - The color info
    294     - By default, an array of palette index for each tile. This is not the way the hardware works but it takes less space and will create maps compatibles with both `DMG` and `CGB` devices.
    295     - Passing `-use_map_attributes` will create an array of map attributes. It will also add mirroring info for each tile and because of that maps created with this won't be compatible with `DMG`.
    296       - Use `-noflip` to make background maps which are compatible with `DMG` devices.
    297 
    298 #### Meta sprites
    299 By default the png will be converted to metasprites. The image will be subdivided into meta sprites of `-sw` x `-sh`. In this case png2asset will generate:
    300   - The metasprites, containing an array of:
    301     - tile index
    302     - y offset
    303     - x offset
    304     - flags, containing the mirror info, the palettes for both DMG and GBC and the sprite priority
    305   - The metasprites array
    306 
    307 
    308 #### Super Game Boy Borders (SGB)
    309 Screen border assets for the Super Game Boy can be generated using png2asset.
    310 
    311 The following flags should be used to perform the conversion:
    312   - `<input_border_file.png> -map -bpp 4 -max_palettes 4 -pack_mode sgb -use_map_attributes -c <output_border_data.c>`
    313   - Where `<input_border_file.png>` is the image of the SGB border (256x224) and `<output_border_data.c>` is the name of the source file to write the assets out to.
    314 
    315 
    316 See the `sgb_border` example project for more details.
    317 
    318 
    319 @anchor utility_makecom
    320 ## makecom
    321 Converts a binary .rom file to .msxdos com format, including splitting the banks up into separate files.
    322 
    323 - For detailed settings see @ref makecom-settings
    324 
    325 @anchor utility_makenes
    326 ## makenes
    327 Converts a binary .rom file to a .nes file, prepending a 16-byte header.
    328 
    329 - For an explanation of the interpretation of header bits see https://www.nesdev.org/wiki/INES
    330 
    331 @anchor utility_png2hicolorgb
    332 ## png2hicolorgb
    333 An updated version of Glen Cook's Windows GUI "hicolour.exe" 1.2 conversion tool for the Game Boy Color. The starting code base was the 1.2 release.
    334 
    335 - For detailed settings see @ref png2hicolorgb-settings
    336 
    337 "Hi Color" on the Game Boy Color is a technique for displaying backgrounds with thousands of colors instead being limtied to 32 colors for the entire screen background. It achieves this by changing ~16 colors of the background palette per scanline. The main tradeoffs are that it uses much of the Game Boy's available cpu processing per frame and requires more ROM space. The tile patterns, map, attributes and per-scanline palettes are pre-calculated using the PC based conversion tool.
    338 
    339 For the current GBDK example ISR implementation there is a limit of 6 sprites per line before the hi-color timing breaks down and there start to be background artifacts.
    340 
    341 Example: `png2hicolorgb myimage.png --csource -o=my_output_filename`
    342 Example with higher quality (slower conversion): `png2hicolorgb myimage.png --csource -o=my_output_filename --type=3 -L=2 -R=2`
    343 
    344 ```
    345 Historical credits and info:
    346    Original Concept : Icarus Productions
    347    Original Code : Jeff Frohwein
    348    Full Screen Modification : Anon
    349    Adaptive Code : Glen Cook
    350    Windows Interface : Glen Cook
    351    Additional Windows Programming : Rob Jones
    352    Original Quantiser Code : Benny
    353    Quantiser Conversion : Glen Cook
    354 ```
    355 
    356 ### Additional Details
    357 For technical details about the conversion process and rendering, see:
    358 https://github.com/bbbbbr/png2hicolorgb
    359 
    360 
    361 @anchor utility_romusage
    362 ## romusage
    363 A utility for estimating usage of Game Boy and SMS/GG ROMs from .noi and .map files, binary ROMs and more.
    364 
    365 - For detailed settings see @ref romusage-settings
    366 
    367 Example: `romusage myprogram.noi -g`
    368 

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