git.y1.nz

gbdk-2020

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

commit 07d6d723c28e5941790d792ba658822b73b28fb3
parent 05ba3b4dc5c035b436da4d83759bc7cdfa7573f9
Author: Toxa <56631470+untoxa@users.noreply.github.com>
Date:   Sat, 23 Jan 2021 11:37:14 +0300

Merge pull request #122 from bbbbbr/develop_docs_markdown_merge

 Docs: Add general docs in markdown format, a couple minor header file doc updates
Diffstat:
Mdocs/config/gbdk-2020-doxyfile4++--
Mdocs/config/github-markdown-theme/doxygen_extra.css8++++++++
Mdocs/index.md10+++-------
Adocs/pages/banking_mbcs.md212+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/docs_index.md48++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/links_and_tools.md94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/migrating_new_versions.md56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/page docs_coding_guidelines.md147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/release_notes.md329+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/sample_programs.md112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/toolchain.md179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adocs/pages/using_gbdk.md161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgbdk-lib/include/gb/drawing.h16+++++++++++++++-
Mgbdk-lib/include/gb/hardware.h114++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mgbdk-lib/include/gbdk-lib.h23-----------------------
Mgbdk-lib/include/stdio.h3+++
16 files changed, 1427 insertions(+), 89 deletions(-)

diff --git a/docs/config/gbdk-2020-doxyfile b/docs/config/gbdk-2020-doxyfile @@ -32,7 +32,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "GBDK 2020 API Docs" +PROJECT_NAME = "GBDK 2020 Docs" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -834,7 +834,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = $(GBDKLIBDIR)/include +INPUT = $(GBDKLIBDIR)/include $(GBDKDOCSDIR)/pages # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/docs/config/github-markdown-theme/doxygen_extra.css b/docs/config/github-markdown-theme/doxygen_extra.css @@ -462,3 +462,11 @@ img { font-size:15px !important; content:"\2715"; } + +/* Add styling for the <code> tag so it stands out better */ +code { + background-color: #def4fd; + border-radius: 4px; + padding-left: 3px; + padding-right: 3px; +} diff --git a/docs/index.md b/docs/index.md @@ -1,11 +1,6 @@ # GBDK 2020 Documentation -Some intro information here. - -Links to other general sections could be here. - -[API documentation](api/) - -There could be some links to other resources. +[General docs](api/) +[API](api/globals_func.html) + diff --git a/docs/pages/banking_mbcs.md b/docs/pages/banking_mbcs.md @@ -0,0 +1,212 @@ +@page docs_rombanking_mbcs ROM/RAM Banking and MBCs + + + +# ROM/RAM Banking and MBCs (Memory Bank Controllers) +The standard Game Boy cartridge with no MBC has a fixed 32K bytes of ROM. In order to make cartridges with larger ROM sizes (to store more code and graphics) MBCs can be used. They allow switching between multiple ROM banks that use the same memory region. Only one of the banks can be selected as active at a given time, while all the other banks are inactive (and so, inaccessible). + + +## Unbanked cartridges +Cartridges with no MBC controller are unbanked, they have 32K bytes of fixed ROM space and no switchable banks. For these cartridges the ROM space between `0000h and 7FFFh` can be treated as a single large bank of 32K bytes, or as two contiguous banks of 16K bytes in Bank 0 at `0000h - 3FFFh` and Bank 1 at `4000h to 7FFFh`. + + +## MBC Banked cartridges (Memory Bank Controllers) +@anchor MBC +@anchor MBCS +Cartridges with MBCs allow the the Game Boy to work with ROMS up to 8MB in size and with RAM up to 128kB. Each bank is 16K Bytes. + - Bank 0 of the ROM is located in the region at `0000h - 3FFFh`. It is _usually_ fixed (unbanked) and cannot be switched out for another bank. + - The higher region at `4000h to 7FFFh` is used for switching between different ROM banks. + +See the @ref Pandocs for more details about the individual MBCs and their capabilities. + + +# Working with Banks +To assign code and constant data (such as graphics) to a ROM bank and use it: + - Place the code for your ROM bank in one or several source files. + - Specify the ROM bank to use, either in the source file or at compile/link time. + - Specify the number of banks and MBC type during link time. + - When the program is running and wants to use data or call a function that is in a given bank, manually or automatically set the desired bank to active. + + +## Setting the ROM bank for a Source file +The ROM and RAM bank for a source file can be set in a couple different ways. Multiple different banks cannot be assigned inside the same source file (unless the `__addressmod` method is used), but multiple source files can share the same bank. + +If no ROM and RAM bank are speciied for a file then the default _CODE, _BSS and _DATA segments are used. + +Ways to set the ROM bank for a Source file + - `#pragma bank <N>` at the start of a source file. Example (ROM bank 2): `#pragma bank 2` + - The lcc switch for ROM bank `-Wf-bo<N>`. Example (ROM bank 2): `-Wf-bo2` + - Using @ref rom_autobanking + +Note: You can use the `UNBANKED` keyword to define a function as unbanked if it resides in a source file which has been assigned a bank. + + +## Setting the RAM bank for a Source file + - Using the lcc switch for RAM bank `-Wf-ba<N>`. Example (RAM bank 3): `-Wf-bo3` + + +@anchor setting_mbc_and_rom_ram_banks +## Setting the MBC and number of ROM & RAM banks available + +At the link stage this is done with @ref lcc using pass-through switches for @ref makebin. + - `-Wl-yo<N>` where `<N>` is the number of ROM banks. 2, 4, 8, 16, 32, 64, 128, 256, 512 + - `-Wl-ya<N>` where `<N>` is the number of RAM banks. 2, 4, 8, 16, 32 + - `-Wl-yt<N>` where `<N>` is the type of MBC cartridge (see below). + +The following MBC settings are available when using the makebin MBC switch. +``` +# From Makebin source: +# +#-Wl-yt<NN> where <NN> is one of the numbers below +# +# 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 +``` + + +## Banked Functions +@anchor banked_calls +Banked functions can be called as follows. + - When defined with the `BANKED` keyword. Example: `void my_function() BANKED { do stuff }` in a source file which has had it's bank set (see above). + - Using @ref far_pointers + - When defined with an area set up using the `__addressmod` keyword (See the `banks_new` example project and the SDCC manual for details) + - Using @ref SWITCH_ROM_MBC1() (and related functions for other MBCs) to manually switch in the required bank and then call the function. + + +Unbanked functions (either in fixed Bank 0, or in an Unbanked ROM with no MBC) + - May call functions in any bank: __YES__ + - May use data in any bank: __YES__ + +@todo Fill in this info for Banked Functions +Banked functions (located in a switchable ROM bank) + - May call functions in any bank: ? + - May use data in any bank: __NO__ (may only use data from currently active banks) + +Limitations: + - SDCC banked calls and far_pointers in GBDK only save one byte for the ROM bank. So, for example, they are limtied to __bank 15__ max for MBC1 and __bank 255__ max for MBC5. This is due to the bank switching for those MBCs requiring a second, additional write to select the upper bits for more banks (banks 16+ in MBC1 and banks 256+ in MBC5). + + +## Const Data (Variables in ROM) +@todo Const Data (Variables in ROM) + + +## Variables in RAM +@todo Variables in RAM + + +## Far Pointers +@anchor far_pointers +Far pointers include a segment (bank) selector so they are able to point to addresses (functions or data) outside of the current bank (unlike normal pointers which are not bank-aware). A set of macros is provided by GBDK 2020 for working with far pointers. + +__Warning:__ Do not call the far pointer function macros from inside interrupt routines (ISRs). The far pointer function macros use a global variable that would not get restored properly if a function called that way was interrupted by another one called the same way. However, they may be called recursively. + +See @ref FAR_CALL, @ref TO_FAR_PTR and the `banks_farptr` example project. + + +## Bank switching +You can manually switch banks using the @ref SWITCH_ROM_MBC1(), @ref SWITCH_RAM_MBC1(), and other related macros. See `banks.c` project for an example. + +Note: You can only do a switch_rom_bank call from unbanked `_CODE` since otherwise you would switch out the code that was executing. Global routines that will be called without an expectation of bank switching should fit within the limited 16k of unbanked `_CODE`. + + +## Bank switching inside an Interrupt Service Routine (ISR) +If a banked function call is made inside an ISR, then the @ref _current_bank variable should be saved and then restored. + +For example, __instead__ of this code: +``` +void vbl_music_isr(void) +{ + // some_banked_function() causes the bank to change + some_banked_function(); +} +``` +It should be: +``` +void vbl_music_isr(void) +{ + // Save the current bank + UBYTE _saved_bank = _current_bank; + + // some_banked_function() causes the bank to change + some_banked_function(); + + // Now restore the current bank + SWITCH_ROM_MBC5(_saved_bank); +} +``` + + +## Currently active bank: _current_bank +The global variable @ref _current_bank is updated automatically when calling @ref SWITCH_ROM_MBC1() and @ref SWITCH_ROM_MBC5, or when a `BANKED` function is called. + + +# Auto-Banking +@anchor rom_autobanking +A ROM bank auto-assignment feature was added in GBDK 2020 4.0.2. + +Instead of having to manually specify which bank a source file will reside it, the banks can be assigned automatically to make the best use of space. The bank assignment operates on object files, after compiling/assembling and before linking. + +To turn on auto-banking, use the `-autobank` argument with lcc + +For a source example see the `banks_autobank` project. + +In the source files you want auto-banked, do the following: + - Set the bank for the source file to `255`: `#pragma bank 255` + - Create a constant with no value to store the bank number for the source file: `const void __at(255) __bank_<name-for-a-given-source-file>;`. + This constant can then be used for obtaining that files bank number with `(UINT8)&__bank_<name-for-a-given-source-file`. + +Example: level_1_map.c + + #pragma bank 255 + const void __at(255) __bank_level_1_map; + + const UINT8 my_level_1_map[] = {... some map data here ...}; + +Accessing that data: main.c + + SWITCH_ROM_MBC1( (UINT8)&__bank_level_1_map ); + // Do something with my_level_1_map[] + +Features and Notes: + - Fixed banked source files can be used in the same project as auto-banked source files. The bankpack tool will attempt to pack the auto-banked source files as efficiently as possible around the fixed-bank ones. + - Sometimes a `clean rebuild` of a project may be needed to reorganize and sort the banks. This is because an auto-banked source file will remain in the same bank until it is re-compiled (due to changes or due to a `clean build`). An example of when this might happen is a fixed-bank source file growing too large to share a bank with an auto-banked source file that was previously assigned to it. + - See @ref bankpack for more options and settings + +Limitations: + - At this time, the constant entries that get rewritten with the assigned bank (const void __at(255) __bank_<name-you-want-to-use-for-that-source-file>;) __cannot__ be used from the source file they are declared in. In that case SDCC converts the bank number before @ref bankpack has a chance to rewrite it. It may be referenced from any other source file, but not it's own. + + +# Errors related to banking (overflow, multiple writes to same location) +A _bank overflow_ during compile/link time (in @ref makebin) is when more code and data are allocated to a ROM bank than it has capacity for. The address for any overflowed data will be incorrect and the data is potentially unreachable since it now resides at the start of a different bank instead of the end of the expected bank. + +The current toolchain can only detect and warn (using @ref ihxcheck) when one bank overflows into another bank that has data at its start. It cannot warn if a bank overflows into an empty one. For more complete detection , you can use the third-party @ref romusage tool. + + +# Bank space usage +In order to see how much space is used or remains available in a bank, you can use the third-party @ref romusage tool. + + +## Other important notes + - The @ref SWITCH_ROM_MBC5 macro is not interrupt-safe. If using less than 256 banks you may always use SWITCH_ROM_MBC1 - that is faster. Even if you use mbc5 hardware chip in the cart. + + +# Banking example projects +There are several projects in the GBDK 2020 examples folder which demonstrate different ways to use banking. + - `Banks`: A basic banking example + - `Banks_new`: Examples of using new bank assignment and calling conventions available in GBDK 2020 and it's updated SDCC version. + - `Banks_farptr`: Using far pointers which have the bank number built into the pointer. + - `Banks_autobank`: Shows how to use the bank auto-assignment feature of in GBDK 2020 4.0.2 or later, instead of having to manually specify which bank a source file will reside it. + diff --git a/docs/pages/docs_index.md b/docs/pages/docs_index.md @@ -0,0 +1,48 @@ +@mainpage General Documentation + +- @subpage docs_links_and_tools +- @subpage docs_using_gbdk +- @subpage docs_coding_guidelines +- @subpage docs_rombanking_mbcs +- @subpage docs_toolchain +- @subpage docs_sample_programs +- @subpage docs_migrating_versions +- @subpage docs_releases + + +# About the Documentation +This documentation is partially based on material written by the original GBDK authors in 1999 and updated for GBDK-2020. The API docs are automatically generated from the C header files using Doxygen. + +GBDK-2020 is an updated version of the original GBDK with a modernized SDCC toolchain and many API improvements and fixes. It can be found at: https://github.com/Zal0/gbdk-2020/. + +The original GBDK sources, documentation and website are at: http://gbdk.sourceforge.net/ + + +# About GBDK +The GameBoy Developer's Kit (GBDK, GBDK-2020) is used to develop games and programs for the Nintendo Game Boy system in C and assembly. GBDK includes a set of libraries for the most common requirements and generates image files for use with a real GameBoy or with emulators. + +GBDK features: + - C and ASM toolchain based on SDCC with some support utilities + - A set of libraries with source code + - Example programs in ASM and in C + - Support for multiple ROM bank images + +GBDK is freeware. Most of the tooling code is under the GPL. The runtime libraries should be under the LGPL. Please consider mentioning GBDK in the credits of projects made with it. + +- - - - - - + +# Historical Info and Links + +The following is from the original GBDK documenation. + +Thanks to quang for many of the comments to the gb functions. Some +of the comments are ripped directly from the Linux Programmers +manual, and some directly from the pan/k00Pa document. + +<a href="http://quangdx.com/">quangDX.com</a> + +<a href="http://gbdk.sourceforge.net/">The (original) gbdk homepage</a> + +<a href="http://www.devrs.com/gb/">Jeff Frohwein's GB development page.</a> +A extensive source of Game Boy related information, including GeeBee's GB faq and the pan/k00Pa document. + diff --git a/docs/pages/links_and_tools.md b/docs/pages/links_and_tools.md @@ -0,0 +1,94 @@ +@page docs_links_and_tools Links and Third-Party Tools + + +This is a brief list of useful tools and information. It is not meant to be complete or exhaustive, for a larger list see @ref awesome_gb + +@anchor links_sdcc_docs +# SDCC Compiler Suite User Manual + - GBDK-2020 uses the SDCC compiler and related tools. The SDCC manual goes into much more detail about available features and how to use them. + http://sdcc.sourceforge.net/doc/sdccman.pdf + http://sdcc.sourceforge.net + + +@anchor links_gameboy_docs +# Game Boy Documentation + - @anchor Pandocs + __Pandocs__ + Extensive and up-to-date technical documentation about the Game Boy and related hardware. + https://gbdev.io/pandocs/ + + - @anchor awesome_gb + __Awesome Game Boy List__ + A list of Game Boy/Color development resources, tools, docs, related projects and homebrew. + https://gbdev.io/list.html + + +@anchor links_graphic +# Graphics Tools + - @anchor gbmb + @anchor gbtd + __Game Boy Tile Designer and Map Builder (GBTD / GBMB)__ + Sprite / Tile editor and Map Builder that can export to C that works with GBDK. + https://github.com/untoxa/GBTD_GBMB (updated version with improvements and fixes) + http://www.devrs.com/gb/hmgd/intro.html (original tools) + https://github.com/bbbbbr/gimp-tilemap-gb (GIMP plugin to read/write GBR/GBM files) + + - @anchor Tilemap_Studio + __Tilemap Studio__ + A tilemap editor for Game Boy, GBC, GBA, or SNES projects. + https://github.com/Rangi42/tilemap-studio/ + + +@anchor tools_music +# Music drivers and tools + - @anchor gbt-player + __GBT Player__ + A .mod converter and music driver that works with GBDK and RGBDS. + https://github.com/AntonioND/gbt-player + Docs from GBStudio that should mostly apply: https://www.gbstudio.dev/docs/music/ + + + - @anchor hUGEdriver + __hUGEdriver__ + A tracker and music driver that works with GBDK and RGBDS. + It is smaller, more efficient and more versatile than gbt_player. + https://github.com/untoxa/hUGEBuild + https://github.com/SuperDisk/hUGEDriver + https://github.com/SuperDisk/hUGETracker + + +@anchor tools_emulators +# Emulators + - @anchor bgb + __BGB__ + Accurate emulator, has useful debugging tools. + http://bgb.bircd.org/ + + - @anchor emulicious + __Emulicious__ + An accurate emulator with extensive tools including source level debugging. + https://emulicious.net/ + + +@anchor tools_debug +# Debugging tools + - @anchor Emulicious_debug + __Emulicious debug adapter__ + Provides source-level debugging in VS Code that works with GBDK2020. + https://marketplace.visualstudio.com/items?itemName=emulicious.emulicious-debugger + + - @anchor romusage + __romusage__ + Calculate used and free space in banks (ROM/RAM) and warn about errors such as bank overflows. + https://github.com/bbbbbr/romusage + + - @anchor noi2sym + __noi2sym.py__ + Convert .noi files into a symbol format compatible with BGB. Allows BGB to recognize variables and functions based on address. + https://github.com/untoxa/hUGEBuild/blob/master/tools/noi2sym.py + + - @anchor src2sym + __src2sym.pl__ + Add line-by-line C source code to the main symbol file in a BGB compatible format. This allows for C source-like debugging in BGB in a limited way. + https://gbdev.gg8.se/forums/viewtopic.php?id=710 + diff --git a/docs/pages/migrating_new_versions.md b/docs/pages/migrating_new_versions.md @@ -0,0 +1,56 @@ +@page docs_migrating_versions Migrating to new GBDK Versions + +This section contains information that may be useful to know or important when upgrading to a newer GBDK release. + +# GBDK 2020 versions + +## Porting to GBDK 2020 4.0.2 + - The default font has been reduced from 256 to 96 characters. Code using special characters may need to be updated. + +## Porting to GBDK 2020 4.0.1 + - __Important!__ : The `WRAM` memory region is no longer automatically initialized to zeros during startup. + - Any variables which are declared without being initialized may have __indeterminate values instead of 0__ on startup. This might reveal previously hidden bugs in your code. + - Check your code for variables that are not initialized before use. + - In BGB you can turn on triggering exceptions (options panel) reading from unitialized RAM. This allows for some additional runtime detection of uninitialized vars. + - In .ihx files, multiple writes to the same ROM address are now warned about using @ref ihxcheck. + - `set_*_tiles()` now wrap maps around horizontal and vertical boundaries correctly. Code relying on it not wrapping correctly may be affected. + + +## Porting to GBDK 2020 4.0 + - GBDK now requires SDCC 4.0.3 or higher + - The old linker `link-gbz80` has been REMOVED, the linker @ref sdldgb from SDCC is used. + - Due to the linker change, there are no longer warnings about multiple writes to the same ROM address. + - GBDK now generates .ihx files, those are converted to a ROM using @ref makebin (lcc can do this automatically in some use cases) + - Setting ROM bytes directly with `-Wl-yp0x<address>=0x<value>` is no longer supported. Instead use @ref makebin flags. For example, use `-Wm-yC` instead of `-Wl-yp0x143=0xC0`. + - OAM symbol has been renamed to _shadow_OAM, that allows accessing shadow OAM directly from C code + + +## Porting to GBDK 2020 3.2 + - No significant changes required + +## Porting to GBDK 2020 3.1.1 + - No significant changes required + +## Porting to GBDK 2020 3.1 + - No significant changes required + +## Porting to GBDK 2020 3.0.1 + - LCC was upgraded to use SDCC v4.0. Makefile changes may be required + - The symbol format changed. To get usable symbols turn on `.noi` output (LCC argument: `-Wl-j`)can be enabled and you can use @ref noi2sym + - ?? Suggested: With LCC argument: `-Wa-l` (sdasgb:`-a All user symbols made global`) + - In SDCC 3.6.0, the default for char changed from signed to unsigned. + - If you want the old behavior use `--fsigned-char`. + - lcc includes `--fsigned-char` by default + - Explicit declaration of unsigned vars is encouraged (for example, '15U' instead of '15') + - `.init` address has been removed + +-------------------------------------------------- + +# Historical GBDK versions + +## GBDK 1.1 to GBDK 2.0 + - Change your int variables to long if they have to be bigger than 255. If they should only contain values between 0 and 255, use an unsigned int. + - If your application uses the delay function, you'll have to adapt your delay values. + - Several functions have new names. In particular some of them have been changed to macros (e.g. show_bkg() is now SHOW_BKG). + - You will probably have to change the name of the header files that you include. + diff --git a/docs/pages/page docs_coding_guidelines.md b/docs/pages/page docs_coding_guidelines.md @@ -0,0 +1,147 @@ +@page docs_coding_guidelines Coding Guidelines + +# Learning C / C fundamentals +Writing games and other programs with GBDK will be much easier with a basic understanding of the C language. In particular, understanding how to use C on "Embedded Platforms" (small computing systems, such as the Game Boy) can help you write better code (smaller, faster, less error prone) and avoid common pitfals. + +## General C tutorials + - https://www.learn-c.org/ + - https://www.tutorialspoint.com/cprogramming/index.htm + +## Embedded C introductions + + - http://dsp-book.narod.ru/CPES.pdf + - https://www.phaedsys.com/principals/bytecraft/bytecraftdata/bcfirststeps.pdf + +## Game Boy games in C + + - https://gbdev.io/list.html#c + +# Understanding the hardware +In addition to understanding the C language it's important to learn how the Game Boy hardware works. What it is capable of doing, what it isn't able to do, and what resources are available to work with. A good way to do this is by reading the @ref Pandocs and checking out the @ref awesome_gb list. + + +# Writing optimal C code for the Game Boy and SDCC +The following guidelines can result in better code for the Game Boy, even though some of the guidance may be contrary to typical advice for general purpose computers that have more resources and speed. + +## Variables + + - Use 8-bit values as much as possible. They will be much more efficient and compact than 16 and 32 bit types. + + - Prefer unsigned variables to signed ones: The code generated will be generally more efficient, espacially when comparing two values. + + - Use explicit types so you always know the size of your variables. `INT8, UINT8, INT16, UINT16, INT32, UINT32` or `BYTE, UBYTE, WORD, UWORD, LWORD, ULWORD`. + Types are defined in @ref asm/types.h and @ref asm/gbz80/types.h + + - Global and local static variables are generally more efficient than local non-static variables (which go on the stack and are slower and can result in slower code). + + - `const` keyword: Use const for arrays, structs and variables with read-only (constant) data. It will reduce ROM, RAM and CPU usage significantly. Non-`const` values are loaded from ROM into RAM inefficiently, and there is no benefit in loading them into the limited available RAM if they aren't going to be changed. + + - For calculated values that don't change, pre-compute results once and store the result. Using lookup-tables and the like can improve speed and reduce code size. Macros can sometimes help. It may be beneficial to do the calculations with an outside tool and then include the result as C code in a const array. + + - Use an advancing pointer (`someStruct->var = x; someStruct++`) to loop through arrays of structs instead of using indexing each time in the loop `someStruct[i].var = x`. + + - When modifying variables that are also changed in an Interrupt Service Routine (ISR), wrap them the relevant code block in a `__critical { }` block. See http://sdcc.sourceforge.net/doc/sdccman.pdf#section.3.9 + + - When using constants and literals the `U`, `L` and `UL` postfixes can be used. + - `U` specifies that the constant is unsigned + - `L` specifies that the constant is long. + + - NOTE: In SDCC 3.6.0, the default for char changed from signed to unsigned. The manual says to use `--fsigned-char` for the old behavior, this option flag is included by default when compiling through @ref lcc. + + +## Code structure + + - When procesing for a given frame is done and it is time to wait before starting the next frame, @ref wait_vbl_done() can be used. It uses HALT to put the CPU into a low power state until processing resumes. The CPU will wake up and resume processing at the end of the current frame when the Vertical Blanking interrupt is triggered. + + - Minimize use of multiplication, modulo and division. These operations have no corresponding CPU instructions (software functions), and hence are time costly. Division by powers of 2 are better, they have specific SDCC optimizations. + - Alternatives to modulo: + - When using power of 2 you can use bit masks. Example: `(n % 8)` can be achieved with `(n & 0x7)` + - If you need decimal numbers to count or display a score, you can use the GBDK BCD ([binary coded decimal](https://en.wikipedia.org/wiki/Binary-coded_decimal)) number functions. See: @ref bcd.h and the `BCD` example project included with GBDK. + + - Avoid long lists of function parameters. Passing many parameters can add overhead, especially if the function is called often. When applicable globals and local static vars can be used instead. + + - Use inline functions if the function is short. (with the `inline` keyword, such as `inline UINT8 myFunction() { ... }`) + + - Do not use recursive functions + + - Prefer `==` and `!=` comparison operators to `<`, `<=`, `>`, and `>=`. The code will be shorter and quicker. + + It is even faster to check if a variable is 0 than if it is equal to some other value, so looping from _N down to zero_ is faster than looping _from zero up to N_. + + For instance: + + for(i = 0; i < 10; i++) + + is less efficient than: + + for(i = 0; i != 10; i++) + + and if possible, even better: + + for(i = 10; i != 0; i--) + + +## GBDK API/Library + + - stdio.h: If you have other ways of printing text, avoid including @ref stdio.h and using functions such as @ref printf(). Including it will use a large number of the background tiles for font characters. If stdio.h is not included then that space will be available for use with other tiles instead. + + - drawing.h: The Game Boy graphics hardware is not well suited to frame-buffer style graphics such as the kind provided in @ref drawing.h. Due to that, most drawing functions (rectangles, circles, etc) will be slow . When possible it's much faster and more efficient to work with the tiles and tile maps that the Game Boy hardware is built around. + + - @ref waitpad() and @ref waitpadup check for input in a loop that doesn't HALT at all, so the CPU will be maxed out until it returns. One alternative is to write a function with a loop that checks input with @ref joypad() and then waits a frame using @ref wait_vbl_done() (which idles the CPU while waiting) before checking input again. + + +## Toolchain + + - See SDCC optimizations: http://sdcc.sourceforge.net/doc/sdccman.pdf#section.8.1 + + - Use profiling. Look at the ASM generated by the compiler, write several versions of a function, compare them and choose the faster one. + + - Use the SDCC `--max-allocs-per-node` flag with large values, such as `50000`. `--opt-code-speed` has a much smaller effect. + - GBDK-2020 (after v4.0.1) compiles the library with `--max-allocs-per-node 50000`, but it must be turned on for your own code. + (example: `lcc ... -Wf--max-allocs-per-mode 50000` or `sdcc ... --max-allocs-per-mode 50000`). + + - The other code/speed flags are `--opt-code-speed` or `--opt-code-size `. + + - Use current SDCC builds from http://sdcc.sourceforge.net/snap.php + The minimum required version of SDCC will depend on the GBDK-2020 release. See @ref docs_releases + + - Learn some ASM and inspect the compiler output to understand what the compiler is doing and how your code gets translated. This can help with writing better C code and with debugging. + + +# When C isn't fast enough +@todo Update and verify this section for the modernized SDCC and toolchain + +For many applications C is fast enough but in intensive functions are sometimes better written in assembler. This section deals with interfacing your core C program with fast assembly sub routines. + + +## Calling convention +sdcc in common with almost all C compilers prepends a '_' to any function names. For example the function printf(...) begins at the label _printf::. Note that all functions are declared global. + +The parameters to a function are pushed in right to left order with no aligning - so a byte takes up a byte on the stack instead of the more natural word. So for example the function int store_byte( UWORD addr, UBYTE byte) would push 'byte' onto the stack first then addr using a total of three bytes. As the return address is also pushed, the stack would contain: + + At SP+0 - the return address + + At SP+2 - addr + + At SP+4 - byte + +Note that the arguments that are pushed first are highest in the stack due to how the Game Boy's stack grows downwards. + +The function returns in DE. + + +## Variables and registers +C normally expects registers to be preserved across a function call. However in the case above as DE is used as the return value and HL is used for anything, only BC needs to be preserved. + +Getting at C variables is slightly tricky due to how local variables are allocated on the stack. However you shouldn't be using the local variables of a calling function in any case. Global variables can be accessed by name by adding an underscore. + + +## Segments +The use of segments for code, data and variables is more noticeable in assembler. GBDK and SDCC define a number of default segments - `_CODE`, `_DATA` and `_BSS`. Two extra segments `_HEADER` and `_HEAP` exist for the Game Boy header and malloc heap respectively. + +The order these segments are linked together is determined by crt0.s and is currently `_CODE` in ROM, then `_DATA`, `_BSS`, `_HEAP` in WRAM, with `STACK` at the top of WRAM. `_HEAP` is placed after `_BSS` so that all spare memory is available for the malloc routines. To place code in other than the first two banks, use the segments `_CODE_x` where x is the 16kB bank number. + +As the `_BSS` segment occurs outside the ROM area you can only use .ds to reserve space in it. + +While you don't have to use the `_CODE` and `_DATA` distinctions in assembler you may wish to do so consistancy. + diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md @@ -0,0 +1,328 @@ +@page docs_releases GBDK Releases + +The GBDK 2020 releases can be found on Github: +https://github.com/Zal0/gbdk-2020/releases + + +# GBDK 2020 Release Notes + +## GBDK 2020 4.0.2 + 2021/01/17 + - Includes SDCC snapshot build version 12016 (has a fix for duplicate debug symbols generated from inlined header functions which GBDK 4.0+ uses) + - Updated documentation + - Library was improved + - Linking with stdio.h does not require that much ROM now + - Default font is changed to the smaller one (102 characters), that leaves space for user tiles + - Fixed broken support for multiplying longs + - memset/memcpy minor enhancements + - safer copy-to-VRAM functions + - loading of 1bit data fixed, also now it is possible to specify pixel color + - Improved code generation for the GBDK Library with SDCC switch on by default: `--max-allocs-per-node 50000` + - fixed wrong parameter offsets in hiramcpy() (broken ram_function example) + - Multiple minor improvements + - New bankpack feature, allows automatic bank allocation for data and code, see banks_autobank example, feature is in beta state, use with care + - Lcc improvements + - Fixed option to specify alternate base addresses for shadow_OAM, etc + - Examples: Added bgb debug example + + +## GBDK 2020 4.0.1 + 2020/11/14 + - Updated API documentation + - IHX is checked for correctness before the makebin stage. That allows to warn about overwriting the same ROM addresses (SDCC toolchain does not check this anymore). + - Library was improved + - set_*_tiles() now wrap maps around horizontal and vertical boundaries correctly + - new fill_*_rect() functions to clear rectangle areas + - runtime initialization code now does not initialize whole WRAM with zeros anymore, that allows BGB to raise exceptions when code tries to read WRAM that was not written before. + - enhanced SGB support + - joypad_init() / joypad_ex() support for multiple joypads + - SGB border example + - _current_bank variable is updated when using bank switching macros + - Reorganized examples: each example is in separate folder now, that simplifies understanding. + - Lcc improvements + - Fix -S flag + - Fix default stack location from 0xDEFF to 0xE000 (end of WRAM1) + - Fix cleanup of .adb files with -Wf--debug flag + - Fix output not working if target is -o some_filename.ihx + + +## GBDK 2020 4.0 + 2020/10/01 + - GBDK now requires SDCC 4.0.3 or higher, that has fully working toolchain. Old link-gbz80 linker is not used anymore, sdldgb and makebin are used to link objects and produce binary roms; maccer tool is no longer needed either + - SDCC 4.0.3 has much better code generator which produces smaller and faster code. Code is twice faster + - SOURCE LEVEL DEBUGGING is possible now! Native toolchain produces *.CDB files that contain detailed debug info. Look for EMULICIOUS extension for vs.code. It supports breakpoints, watches, inspection of local variables, and more! + - SDCC 4.0.4 has fixed RGBDS support; library is not updated to support that in full yet, but it is possible to assemble and link code emitted by SDCC with RGDBS + - New banked trampolines are used, they are faster and smaller + - New (old) initialization for non-constant arrays do NOT require 5 times larger rom space than initialized array itself, SDCC even tries to compress the data + - Library was improved + - itoa/ltoa functions were rewritten, div/mod is not required now which is about 10 times faster + - sprite functions are inline now, which is faster up to 12 times and produces the same or smaller code; .OAM symbol is renamed into _shadow_OAM that allows accessing shadow OAM directly from C code + - interrupt handling was revised, it is now possible to make dedicated ISR's, that is important for time-sensitive handlers such as HBlank. + - printf/sprintf were rewritten and splitted, print functions are twice faster now and also requre less rom space if you use sprintf() only, say, in bgb_emu.h + - crash_handler.h - crash handler that allows to detect problems with ROMs after they are being released (adapted handler, originally written by ISSOtm) + - improved and fixed string.h + - many other improvements and fixes - thanks to all contributors! + - Revised examples + - Improved linux support + - Lcc has been updated + - it works with the latest version of sdcc + - quoted paths with spaces are working now + + +## GBDK 2020 3.2 + 2020/06/05 + - Fixed OAM initialization that was causing a bad access to VRAM + - Interrupt handlers now wait for lcd controller mode 0 or 1 by default to prevent access to inaccessible VRAM in several functions (like set_bkg_tiles) + - Several optimizations here and there + + +## GBDK 2020 3.1.1 + 2020/05/17 + - Fixed issues with libgcc_s_dw2-1.dll + + +## GBDK 2020 3.1 + 2020/05/16 + - Banked functions are working! The patcher is fully integrated in link-gbz80, no extra tools are needed. It is based on Toxa's work + - Check this post for more info + - Check the examples/gb/banked code for basic usage + - USE_SFR_FOR_REG is the default now check here why + https://gbdev.gg8.se/forums/viewtopic.php?id=697 + - Fixed examples that were not compiling in the previous version and some improvements in a few of them. Removed all warnings caused by changing to the new SDCC + - Fixed bug in lcc that was causing some files in the temp folder not being deleted + - Removed as-gbz80 (the lib is now compiled with sdasgb thanks to this workaround) + https://github.com/Zal0/gbdk-2020/commit/d2caafa4a66eb08998a14b258cb66af041a0e5c8 + - Profile support with bgb emulator + - Basic support including <gb/bgb_emu.h> and using the macros BGB_PROFILE_BEGIN and BGB_PROFILE_END. More info in this post + https://gbdev.gg8.se/forums/viewtopic.php?id=703 + - For full profiling check this repo and this post + https://github.com/untoxa/bgb_profiling_toolkit/blob/master/readme.md + https://gbdev.gg8.se/forums/viewtopic.php?id=710 + + +## GBDK 2020 3.0.1 + 2020/04/12 + - Updated SDCC to v.4.0 + - Updated LCC to work with the new compiler + + +## GBDK 2020 3.0 + 2020/04/12 + - Initial GBDK 2020 release + Updated SDCC to v4.0 + The new linker is not working so the old version is still there + There is an issue with sdagb compiling drawing.s (the JP in + line 32 after ".org .MODE_TABLE+4*.G_MODE" it's writing more + than 4 bytes invading some addresses required by input.s:41) + Because of this, all .s files in libc have been assembled + with the old as-gbz80 and that's why it is still included + + +# Historical GBDK Release Notes + +## GBDK 2.96 + 17 April, 2000 + Many changes. + - Code generated is now much more reliable and + passes all of sdcc's regression suite. + - Added support for large sets of local variables (>127 bytes). + - Added full 32 bit long support. + - Still no floating pt support. + +## GBDK 2.95-3 + 19th August, 2000 + + * Stopped lcc with sdcc from leaking .cdb files all across + /tmp. + * Optimised < and > for 16 bit varibles. + * Added a new lexer to sdcc. Compiling files with large + initalised arrays takes 31% of the time (well, at least + samptest.c does :) + + This is an experimental release for those who feel keen. The main change is a new lexer (the first part in the compilation process which recognises words and symbols like '!=' and 'char' and turns them into a token number) which speeds up compilation of large initialised arrays like tile data by a factor of three. Please report any bugs that show up - this is a big change. + + I have also included a 'minimal' release for win32 users which omits the documentation, library sources, and examples. If this is useful I will keep doing it. + +## GBDK 2.95-2 + 5th August, 2000 + Just a small update. From the README: + + * Added model switching support + --model-medium uses near (16 bit) pointers for data, and + banked calls for anything not declared as 'nonbanked' + --model-small uses near (16 bit) pointers for data and + calls. Nothing uses banked calls. 'nonbanked' functions + are still placed in HOME. Libraries are under lib/medium + and lib/small. + * Added the gbdk version to 'sdcc --version' + * Changed the ways globals are exported, reducing the amount + of extra junk linked in. + * Turned on the optimisations in flex. Large constant arrays + like tile data should compile a bit faster. + +## GBDK 2.95 + 22nd July, 2000 + * Fixed 'a << c' for c = [9..15] + * no$gmb doesn't support labels of > 32 chars. The linker now + trims all labels to 31 chars long. + * Fixed wait_vbl for the case where you miss a vbl + * Fixed + and - for any type where sizeof == 2 and one of the + terms was on the stack. This includes pointers and ints. Fixes + the text output bug in the examples. Should be faster now as + well. Note that + and - for longs is still broken. + * Fixed the missing */ in gb.h + * Added basic far function support. Currently only works for isas + and rgbasm. See examples/gb/far/* + * bc is now only pushed if the function uses it. i.e. something + like: + int silly(int i) + { + return i; + } + will not have the push bc; pop bc around it. + * Better rgbasm support. Basically: + o Use "sdcc -mgbz80 --asm=rgbds file.c" for each file.c + o Use "sdcc -mgbz80 --asm=rgbds crt0.o gbz80.lib gb.lib file1.o file2.o..." + + to link everything together. The .lib files are generated using + astorgb.pl and sdcc to turn the gbdk libraries into something + rgbds compatible. + The libraries are _not_ fully tested. Trust nothing. But give it + a go :) + * Ran a spell checker across the README and ChangeLog + + This is a recommended upgrade. Some of the big features are: + + Decent rgbds support. All the libraries and most of the examples can now compile with rgbds as the assembler. + Banked function support. It is now easier to break the 32k barrier from within C. Functions can live in and be called transparently from any bank. Only works with rgbds + Fixed some decent bugs with RSH, LSH, and a nasty bug with + and - for int's and pointers. + Various optimisations in the code generator. + + 7th July, 2000 + Information on float and long support. Someone asked about the state of float/long support recently. Heres my reply: + + long support is partly there, as is float support. The compiler will correctly recognise the long and float keywords, and will generate the code for most basic ops (+, -, &, | etc) for longs correctly and will generate the function calls for floats and hard long operations (*, /, %) correctly. However it wont generate float constants in the correct format, nor will it 'return' a long or float - gbdk doesn't yet support returning types of 4 bytes. Unfortunately its not going to make it into 2.95 as there's too much else to do, but I should be able to complete long support for 2.96 + +## GBDK 2.94 + 7th May, 2000 + Many fixes - see the README for more. + + 7th May - Library documentation up. A good size part of the libraries that go with gbdk have been documented - follow the HTML link above to have a look. Thanks to quang for a good chunk of the gb.h documentation. Please report any errors :) + * Fixed + \#define BLAH 7 // Unterminated ' error + in sdcpp + * Fixed + SCY_REG += 2, SCY_REG -= 5 + (add and subtract in indirect space) as they were both quite broken. + * externs and static's now work as expected. + * You can now specify which bank code should be put into using a + \#pragma e.g: + \#pragma bank=HOME + Under rgbds and asxxxx putting code in the HOME bank will force + the code into bank 0 - useful for library functions. The most + recent \#pragma bank= will be the one used for the whole file. + * Fixed an interesting bug in the caching of lit addresses + * Added support for accessing high registers directly using the + 'sfr' directive. See libc/gb/sfr.s and gb/hardware.h for an + example. It should be possible with a bit of work to make high + ram directly usable by the compiler; at the moment it is + experimental. You can test sfr's by enabling USE_SFR_FOR_REG=1 + * Added remove_VBL etc functions. + * Documented the libs - see the gbdk-doc tarball distributed + seperatly. + * Two dimensional arrays seem to be broken. + +## GBDK 2.93 + 6th April, 2000 + From the README + + * Added multi-bank support into the compiler - The old -Wf-boxx + and -Wf-baxx options now work + * Has preliminary support for generating rgbds and ISAS compatible + assembler. Try -W--asm=rgbds or -W--asm=isas. The ISAS code is + untested as I dont have access to the real assembler. + * RSH is fixed + * AND is fixed + * The missing parts of 2.1.0's libs are there. Note: They are + untested. + * The dscan demo now fully works (with a hack :) + * There is a bug with cached computed values which are later used + as pointers. When the value is first used as a BYTE arg, then + later as a pointer the pointer fails as the high byte was never + computed and is now missing. A temporary fix is to declare + something appropriate as 'volatile' to stop the value being + cached. See dscan.c/bombs() for an example. + +## GBDK 2.92-2 for win32 + 26th March, 2000 + This is a maintenance release for win32 which fixes some of the niggly install problems, especially: + * win32 only. Takes care of some of the install bugs, including: + - Now auto detects where it is installed. + This can be overridden using set GBDKDIR=... + - Problems with the installer (now uses WinZip) + - Problems with the temp directory + Now scans TMP, TEMP, TMPDIR and finally c: tmp + - cygwin1.dll and 'make' are no longer required + gbdk is now built using mingw32 which is win32 native + make.bat is automagically generated from the Makefile + - I've reverted to using WORD for signed 16 bit etc. + GBDK_2_COMPAT is no longer required. + + WORDS are now back to signed. GBDK_2_COMPAT is no longer needed. + Temporary files are created in TMP, TEMP, or TMPDIR instead of c: tmp + The installer is no more as it's not needed. There is a WinZip wrapped version for those with the extra bandwidth :). + gbdk autodetects where it is installed - no more environment variables. + cygwin1.dll and make are no longer required - gbdk is now compiled with mingw32. + + See the ChangeLog section in the README for more information. + + 21st March, 2000 + Problems with the installer. It seems that the demo of InstallVISE has an unreasonably short time limit. I had planed to use the demo until the license key came through, but there's no sign of the key yet and the 3 day evaluation is up. If anyone knows of a free Windows installer with the ability to modify environment variables, please contact me. I hear that temporarily setting you clock back to the 15th works... + + 18th March, 2000 + libc5 version available / "Error creating temp file" Thanks to Rodrigo Couto there is now a Linux/libc5 version of gbdk3-2.92 available - follow the download link above. At least it will be there when the main sourceforge site comes back up... Also some people have reported a bug where the compiler reports '*** Error creating temp file'. Try typing "mkdir c: tmp" from a DOS prompt and see if that helps. + +## GBDK 2.92 + 8th March, 2000 + Better than 2.91 :). Can now be installed anywhere. All the demos work. See the README for more. + * All the examples now work (with a little bit of patching :) + * Fixed problem with registers being cached instead of being + marked volatile. + * More register packing - should be a bit faster. + * You can now install somewhere except c: gbdk | /usr/lib/gbdk + * Arrays initialised with constant addresses a'la galaxy.c now + work. + * Fixed minor bug with 104$: labels in as. + * Up to 167d/s... + +## GBDK 2.91 + 27th Feb, 2000 + Better than 2.90 and includes Linux, win32 and a source tar ball. Some notes: + + Read the README first + Linux users need libgc-4 or above. Debian users try apt-get install libgc5. + All the types have changed. Again, please read the README first. + I prefer release early, release often. The idea is to get the bugs out there so that they can be squashed quickly. + I've split up the libs so that they can be used on other platforms and so that the libs can be updated without updating the compiler. One side effect is that gb specific files have been shifted into their own directory i.e. gb.h is now gb/gb.h. + + 23rd Feb, 2000 + First release of gbdk/sdcc. + This is an early release - the only binary is for Linux and the source is only available through cvs. If your interested in the source, have a look at the cvs repository gbdk-support first, which will download all the rest of the code. Alternatively, look at gbdk-support and gbdk-lib at cvs.gbdk.sourceforge.net and sdcc at cvs.sdcc.sourceforge.net. I will be working on binaries for Win32 and a source tar ball soon. Please report any bugs through the bugs link above. + + 31st Jan, 2000 + Added Dermot's far pointer spec. It's mainly here for comment. If sdcc is ported to the Gameboy then I will be looking for some way to do far calls. + + 8th Jan, 2000 + Moved over to sourceforge.net. Thanks must go to David Pfeffer for gbdk's previous resting place, www.gbdev.org. The transition is not complete, but cvs and web have been shifted. Note that the cvs download instructions are stale - you should now look to cvs.gbdk.sourceforge.net. + I am currently working on porting sdcc over to the Z80. David Nathan is looking at porting it to the GB. + + 6th Jan, 2000 + Icehawk wrote "I did write some rumble pack routines. Just make sure to remind people to add -Wl-yt0x1C or -Wl-yt0x1D or -Wl-yt0x1E depending on sram and battery usage. Find the routines on my site (as usual). =)" + + 18th Oct, 1999 + Bug tracking / FAQ up. Try the link on the left to report any bugs with GBDK. It's also the first place to look if your having problems. + +## GBDK 2.1.5 + 17th Oct, 1999 + + The compiler is the same, but some of the libraries have been improved. memset() and memcpy() are much faster, malloc() is fixed, and a high speed fixed block alternative malloc() was added. + diff --git a/docs/pages/sample_programs.md b/docs/pages/sample_programs.md @@ -0,0 +1,112 @@ +@page docs_sample_programs GBDK Sample Programs + + +GBDK includes several sample programs both in C and in assembly. They are located in the examples directory, and in its subdirectories. They can be built by typing make in the correnponding directory. + + +# banks (various projects) +There are several different projects showing how to use ROM banking with GBDK. + + +# comm +Illustrates how to use communication routines. + + +# crash +Demonstrates how to use the optional GBDK crash handler which dumps debug info to the Game Boy screen in the event of a program crash. + + +# colorbar +The colorbar program, written by Mr. N.U. of TeamKNOx, illustrates the use of colors on a Color GameBoy. + + +# dscan +Deep Scan is a game written by Mr. N.U. of TeamKNOx that supports the Color GameBoy. Your aim is to destroy the submarines from your boat, and to avoid the projectiles that they send to you. The game should be self-explanatory. The following keys are used: + + RIGHT/LEFT : Move your boat + A/B : Send a bomb from one side of your boat + START : Start game or pause game + + When game is paused: + + SELECT : Invert A and B buttons + RIGHT/LEFT : Change speed + UP/DOWN : Change level + + +# filltest +Demonstrates various graphics routines. + + +# fonts +Examples of how to work with the built in font and printing features. + + +# galaxy +A C translation of the space.s assembly program. + + +# gb-dtmf +The gb-dtmf, written by Osamu Ohashi, is a Dual Tone Multi-Frequency (DTMF) generator. + + +# irq +Illustrates how to install interrupt handlers. + + +# lcd isr wobble +An example of how to use the LCD ISR for visual special effects + + +# paint +The paint example is a painting program. It supports different painting tools, drawing modes, and colors. At the moment, it only paints individual pixels. This program illustrates the use of the full-screen drawing library. It also illustrates the use of generic structures and big sprites. + + Arrow keys : Move the cursor + SELECT : Display/hide the tools palette + A : Select tool + + +# rand +The rand program, written by Luc Van den Borre, illustrates the use of the GBDK random generator. + + +# ram_fn +The ram_fn example illustrates how to copy functions to RAM or HIRAM, and how to call them from C. + + +# rpn +A basic RPN calculator. Try entering expressions like 12 134* and then 1789+. + + +# samptest +Demonstration of playing a sound sample. + + +# sgb (various) +A collection of examples showing how to use the Super Game Boy API features. + + +# sound +The sound example is meant for experimenting with the soung generator of the GameBoy (to use on a real GameBoy). The four different sound modes of the GameBoy are available. It also demonstrates the use of bit fields in C (it's a quick hack, so don't expect too much from the code). The following keys are used: + + UP/DOWN : Move the cursor + RIGHT/LEFT : Increment/decrement the value + RIGHT/LEFT+A : Increment/decrement the value by 10 + RIGHT/LEFT+B : Set the value to maximum/minimum + START : Play the current mode's sound (or all modes if in control screen) + START+A : Play a little music with the current mode's sound + SELECT : Change the sound mode (1, 2, 3, 4 and control) + SELECT+A : Dump the sound registers to the screen + + +# space +The space example is an assembly program that demonstrates the use of sprites, window, background, fixed-point values and more. The following keys are used: + + Arrow keys : Change the speed (and direction) of the sprite + Arrow keys + A : Change the speed (and direction) of the window + Arrow keys + B : Change the speed (and direction) of the background + START : Open/close the door + SELECT : Basic fading effect + + + diff --git a/docs/pages/toolchain.md b/docs/pages/toolchain.md @@ -0,0 +1,179 @@ +@page docs_toolchain GBDK Toolchain + + +@anchor toolchain_overview +# Overview +GBDK 2020 uses the SDCC compiler along with some custom tools to build Game Boy ROMs. +- All tools are located under `bin/` +- The typical order of tools called is as follows. (When using lcc these steps are usually performed automatically.) + 1. Compile and assemble source files (.c, .s, .asm) with @ref sdcc and @ref sdasgb + 2. Optional: perform auto banking with @ref bankpack on the object files + 3. Link the object files into .ihx file with @ref sdldgb + 4. Validate the .ihx file with @ref ihxcheck + 5. Convert the .ihx file to a ROM file (.gb, .gbc) with @ref makebin + +To see individual arguments and options for a tool, run that tool from the command line with either no arguments or with `-h`. + +@anchor toolchain_faq +# Frequently Asked Questions +- How do I set the ROM's title? + - Use the @ref makebin `-yn` flag. For example with @ref lcc `-Wm-yn"MYTITLE"` or with @ref makebin directly `-yn "MYTITLE"`. The maximum length is up to 15 characters, but may be shorter. + - See "0134-0143 - Title" in @ref Pandocs for more details. + <!-- --> + +- How do I set SGB, Color only and Color compatibility in the ROM header? + - Use the following @ref makebin flags. Prefix them with `-Wm` if using @ref lcc. + - `-yc` : GameBoy Color compatible + - `-yC` : GameBoy Color only + - `-ys` : Super GameBoy compatible + <!-- --> + +- How do I set the ROM @ref MBC type? + - See @ref setting_mbc_and_rom_ram_banks + + +@anchor toolchain_changing_important_addresses +# Changing Important Addresses +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). + +@ref lcc will include the following linker defaults for @ref sdldgb if they are not defined by the user. + + - `_shadow_OAM` + - Location of sprite ram (requires 0xA0 bytes). + - Default `-Wl-g _shadow_OAM=0xC000` + + - `.STACK` + - Initial stack address + - Default `-Wl-g .STACK=0xE000` + + - `.refresh_OAM` + - Address to which the routine for refreshing OAM will be copied (must be in HIRAM). Default + - Default `-Wl-g .refresh_OAM=0xFF80` + + - `_DATA` + - Start of RAM section (starts after Shadow OAM) + - Default `-Wl-b _DATA=0xc0A0` + + - `_CODE` + - Start of ROM section + - Default `-Wl-b _CODE=0x0200` + + +@anchor toolchain_compiling_programs +# Compiling programs + +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: + + - Compile the C source 'source.c', assemble and link it producing the Gameboy image 'image.gb' + + lcc -o image.gb source.c + + - Assemble the file 'source.s' and link it producing the Gameboy image 'image.gb' + + lcc -o image.gb source.s + + - Compile the C program 'source1.c' and assemble it producing the object file 'object1.o' for later linking. + + lcc -c -o object1.o source1.c + + - Assemble the file 'source2.s' producing the object file 'object2.o' for later linking + + lcc -c -o object2.o source2.s + + - Link the two object files 'object1.o' and 'object2.o' and produce the Gameboy image 'image.gb' + + lcc -o image.gb object1.o object2.o + + - Do all sorts of clever stuff by compiling then assembling source1.c, assembling source2.s and then linking them together to produce image.gb. + + lcc -o image.gb source1.c source2.s + +Arguments to the assembler etc can be passed via lcc using -Wp..., -Wf..., -Wa... and -Wl... to pass options to the pre-processor, compiler, assembler and linker respectivly. Some common options are: + + - To generate an assembler listing file. + + -Wa-l + + - To generate a linker map file. + + -Wl-m + + - To bind var to address 'addr' at link time. + + -Wl-gvar=addr + +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. + + lcc -Wa-l -Wl-m -Wl-g_snd_stat=0xff26 -o image.gb hardware.c + + +@subsection Makefiles +Using Makefiles + +Please see the sample projects included with GBDK-2020 for a couple different examples of how to use Makefiles. + +You may also want to read a tutorial on Makefiles. For example: +https://makefiletutorial.com/ +https://www.tutorialspoint.com/makefile/index.htm + + +@anchor lcc +# lcc +lcc is the compiler driver (front end) for the GBDK/sdcc toolchain. +It can be used to invoke all the tools needed for building a rom. +If preferred, the individual tools can be called directly. +- the `-v` flag can be used to show the exact steps lcc executes for a build +- lcc can compile, link and generate a binary in a single pass: `lcc -o somerom.gb somesource.c` + + +@anchor sdcc +# sdcc +SDCC C Source compiler +- Arguments can be passed to it through @ref lcc using `-Wf-<argument>` and `-Wp-<argument>` (pre-processor) + + +@anchor sdasgb +# sdasgb +SDCC Assembler for the gameboy +- Arguments can be passed to it through @ref lcc using `-Wa-<argument>` + + +@anchor bankpack +# bankpack +Automatic Bank packer + +When enabled, automatically assigns banks for object files where bank has been set to `255`, see @ref rom_autobanking. +Unless an alternative output is specified the given object files are updated with the new bank numbers. +- Can be enabled by using the `-autobank` argument with @ref lcc. +- Must be called after compiling/assembling and before linking +- Arguments can be passed to it through @ref lcc using `-Wb-<argument>` + +Limitations +- `__banked` functions cannot be called from within the same source file they are declared in. +- With data it is easier, because if you access data from the code in the same bank you don’t need to switch the bank (access to `__bank_*` symbol). + + +@anchor sdldgb +# sdldgb +The SDCC linker for the gameboy. + +Links object files (.o) into a .ihx file which can be processed by @ref makebin +- Arguments can be passed to it through @ref lcc using `-Wl-<argument>` + + +@anchor ihxcheck +# ihxcheck +IHX file validator + +Checks .ihx files produced by @ref sdldgb for correctness. +- It will warn if there are multiple writes to the same ROM address. This may indicate mistakes in the code or ROM bank overflows +- Arguments can be passed to it through @ref lcc using `-Wi-<argument>` + + +@anchor makebin +# makebin +IHX to ROM converter + +Converts .ihx files produced by @ref sdldgb into ROM files (.gb, .gbc). +- Arguments can be passed to it through @ref lcc using `-Wm-<argument>` + diff --git a/docs/pages/using_gbdk.md b/docs/pages/using_gbdk.md @@ -0,0 +1,160 @@ +@page docs_using_gbdk Using GBDK + + +# Interrupts +Interrupts allow execution to jump to a different part of your code as soon as an external event occurs - for example the LCD entering the vertical blank period, serial data arriving or the timer reaching its end count. For an example see the irq.c sample project. + +Interrupts in GBDK are handled using the functions @ref disable_interrupts(), @ref enable_interrupts(), @ref set_interrupts(UBYTE ier) and the interrupt service routine (ISR) linkers @ref add_VBL(), @ref add_TIM, @ref add_LCD, @ref add_SIO and @ref add_JOY which add interrupt handlers for the vertical blank, timer, LCD, serial link and joypad interrupts respectively. + +Since an interrupt can occur at any time an Interrupt Service Request (ISR) cannot take any arguments or return anything. Its only way of communicating with the greater program is through the global variables. When interacting with those shared ISR global variables from main code outside the interrupt, it is a good idea to wrap them in a `critical {}` section in case the interrupt occurs and modifies the variable while it is being used. + +Interrupts should be disabled before adding ISRs. To use multiple interrupts, _logical OR_ the relevant IFLAGs together. + +ISRs should be kept as small and short as possible, do not write an ISR so long that the Game Boy hardware spends all of its time servicing interrupts and has no time spare for the main code. + +For more detail on the Game Boy interrupts consider reading about them in the @ref Pandocs. + +## Available Interrupts +The GameBoy hardware can generate 5 types of interrupts. Custom Interrupt Service Routines (ISRs) can be added in addition to the built-in ones available in GBDK. + + - VBL : LCD Vertical Blanking period start + - The default VBL ISR is installed automatically. + - See @ref add_VBL() and @ref remove_VBL() + + - LCD : LCDC status (such as the start of a horizontal line) + - See @ref add_LCD() and @ref remove_LCD() + - Example project: `lcd_isr_wobble` + + - TIM : Timer overflow + - See @ref add_TIM() and @ref remove_TIM() + - Example project: `tim` + + - SIO : Serial Link I/O transfer end + - The default SIO ISR gets installed automatically if any of the standard SIO calls are used. These calls include add_SIO(), remove_SIO(), send_byte(), receive_byte(). + - The default SIO ISR cannot be removed once installed. Only secondary chained SIO ISRs (added with add_SIO() ) can be removed. + - See @ref add_SIO() and @ref remove_SIO() + - Example project: `comm` + + - JOY : Transition from high to low of a joypad button + - See @ref add_JOY() and @ref remove_JOY() + +## Adding your own interrupt handler +It is possible to install your own interrupt handlers (in C or in assembly) for any of these interrupts. Up to 4 chained handlers may be added, with the last added being called last. If the remove_VBL() function is to be called, only three may be added for VBL. + +Interrupt handlers are called in sequence. To install a new interrupt handler, do the following: + + 1. Write a function (say foo()) that takes no parameters, and that returns nothing. Remember that the code executed in an interrupt handler must be short. + 2. Inside a `__critical { ... }` section, install your interrupt handling routines using the add_XXX() function, where XXX is the interrupt that you want to handle. + 3. Enable interrupts for the IRQ you want to handle, using the set_interrupts() function. Note that the VBL interrupt is already enabled before the main() function is called. If you want to set the interrupts before main() is called, you must install an initialization routine. + +See the `irq` example project for additional details for a complete example. + +## Returning from Interrupts and STAT mode +By default when an Interrupt handler completes and is ready to exit it will check STAT_REG and only return at the BEGINNING of either LCD Mode 0 or Mode 1. This helps prevent graphical glitches caused when an ISR interrupts a graphics operation in one mode but returns in a different mode for which that graphics operation is not allowed. + +You can change this behavior using nowait_int_handler() which does not check @ref STAT_REG before returning. Also see @ref wait_int_handler(). + + +# What GBDK does automatically and behind the scenes + +## OAM (VRAM Sprite Attribute Table) +GBDK sets up a Shadow OAM which gets copied automatically to the hardware OAM by the default V-Blank ISR. The Shadow OAM allows updating sprites without worrying about whether it is safe to write to them or not based on the hardware LCD mode. + +## Font tiles when using stdio.h +Including @ref stdio.h and using functions such as @ref printf() will use a large number of the background tiles for font characters. If stdio.h is not included then that space will be available for use with other tiles instead. + +## Default Interrupt Service Handlers (ISRs) + - V-Blank: A default V-Blank ISR is installed on startup which copies the Shadow OAM to the hardware OAM and increments the global @ref sys_time variable once per frame. + - Serial Link I/O: If any of the GBDK serial link functions are used such as @ref send_byte() and @ref receive_byte(), the default SIO serial link handler will be installed automatically at compile-time. + + +# Copying Functions to RAM and HIRAM + +The `ram_function` example project included with GBDK demonstrates copying functions to RAM and HIRAM. + +It is possible to copy functions to RAM and HIRAM (using the memcpy() and hiramcpy() functions), and execute them from C. The compiler automatically generates two symbols for the start and the end of each function, named start_X and end_X (where X is the name of the function). This enables to calculate the length of a function when copying it to RAM. Ensure you have enough free space in RAM or HIRAM for copying a function. + +There are basically two ways for calling a function located in RAM, HIRAM, or ROM: + + - Declare a pointer-to-function variable, and set it to the address of the function to call. + - Declare the function as extern, and set its address at link time using the -Wl-gXXX=# flag (where XXX is the name of the function, and # is its address). + +The second approach is slightly more efficient. Both approaches are demonstrated in the `ram_function.c` example. + + +# Mixing C and Assembly + +You can mix C and assembly (ASM) in two ways as described below. For additional detail see the @ref links_sdcc_docs. + +## Inline ASM within C source files + +Example: + + __asm__("nop"); + +Another Example: + + void some_c_function() + { + // Optionally do something + __asm + (ASM code goes here) + __endasm; + } + + +## In Separate ASM files + +@todo This is from GBDK 2.x docs, verify it with GBDK-2020 and modern SDCC + +It is possible to assemble and link files written in ASM alongside files written in C. + + - A C identifier `i` will be called `_i` in assembly. + - Results are always returned into the `DE` register. + - Parameters are passed on the stack (starting at `SP+2` because the return address is also saved on the stack). + - Assembly identifier are exported using the `.globl` directive. + - You can access GameBoy hardware registers using `_reg_0xXX` where `XX` is the register number (see `sound.c` for an example). + - Registers must be preserved across function calls (you must store them at function begin, and restore them at the end), except `HL` (and `DE` when the function returns a result). + +Here is an example of how to mix assembly with C: + +`main.c` + + main() + { + WORD i; + WORD add(WORD, WORD); + + i = add(1, 3); + } + +`add.s` + + .globl _add + _add: ; WORD add(WORD a, WORD b) + ; There is no register to save: + ; BC is not used + ; DE is the return register + ; HL needs never to be saved + LDA HL,2(SP) + LD E,(HL) ; Get a in DE + INC HL + LD D,(HL) + INC HL + LD A,(HL) ; Get b in HL + INC HL + LD H,(HL) + LD L,A + ADD HL,DE ; Add DE to HL + LD D,H + LD E,L + ; There is no register to restore + RET ; Return result in DE + + +# Known Issues and Limitations + +## SDCC + - Const arrays declared with `somevar[n] = {x}` will __NOT__ get initialized with value `x`. This may change when the SDCC RLE initializer is fixed. Use memset for now if you need it. + + - SDCC banked calls and @ref far_pointers in GBDK only save one byte for the ROM bank, so for example they are limtied to __bank 15__ max for MBC1 and __bank 255__ max for MBC5. See @ref banked_calls for more details. + diff --git a/gbdk-lib/include/gb/drawing.h b/gbdk-lib/include/gb/drawing.h @@ -5,8 +5,22 @@ Legendary overhall by Jon Fuge <jonny@q-continuum.demon.co.uk> Commenting by Michael Hope - Note that the standard text printf() and putchar() cannot be used + Note: The standard text printf() and putchar() cannot be used in APA mode - use gprintf() and wrtchr() instead. + + Note: Using drawing.h will cause it's custom VBL and LCD ISRs + (`drawing_vbl` and `drawing_lcd`) to be installed. + + ---- + + __Important note for the drawing API :__ + + The Game Boy graphics hardware is not well suited to frame-buffer + style graphics such as the kind provided in `drawing.h`. + Due to that, __most drawing functions (rectangles, circles, etc) will + be slow__ . When possible it's much faster and more efficient + to work with the tiles and tile maps that the Game Boy hardware is + built around. */ #ifndef __DRAWING_H #define __DRAWING_H diff --git a/gbdk-lib/include/gb/hardware.h b/gbdk-lib/include/gb/hardware.h @@ -1,6 +1,8 @@ /** @file gb/hardware.h Defines that let the GB's hardware registers be accessed - from C. See the Pan doc for what to set them to. + from C. + + See the @ref Pandocs for more details on each register. */ #ifndef _HARDWARE_H #define _HARDWARE_H @@ -9,60 +11,60 @@ #define __REG extern volatile __sfr -__REG P1_REG ; /* Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ -__REG SB_REG ; /* Serial IO data buffer */ -__REG SC_REG ; /* Serial IO control register */ -__REG DIV_REG ; /* Divider register */ -__REG TIMA_REG ; /* Timer counter */ -__REG TMA_REG ; /* Timer modulo */ -__REG TAC_REG ; /* Timer control */ -__REG IF_REG ; /* Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ -__REG NR10_REG ; /* Sound register */ -__REG NR11_REG ; /* Sound register */ -__REG NR12_REG ; /* Sound register */ -__REG NR13_REG ; /* Sound register */ -__REG NR14_REG ; /* Sound register */ -__REG NR21_REG ; /* Sound register */ -__REG NR22_REG ; /* Sound register */ -__REG NR23_REG ; /* Sound register */ -__REG NR24_REG ; /* Sound register */ -__REG NR30_REG ; /* Sound register */ -__REG NR31_REG ; /* Sound register */ -__REG NR32_REG ; /* Sound register */ -__REG NR33_REG ; /* Sound register */ -__REG NR34_REG ; /* Sound register */ -__REG NR41_REG ; /* Sound register */ -__REG NR42_REG ; /* Sound register */ -__REG NR43_REG ; /* Sound register */ -__REG NR44_REG ; /* Sound register */ -__REG NR50_REG ; /* Sound register */ -__REG NR51_REG ; /* Sound register */ -__REG NR52_REG ; /* Sound register */ -__REG LCDC_REG ; /* LCD control */ -__REG STAT_REG ; /* LCD status */ -__REG SCY_REG ; /* Scroll Y */ -__REG SCX_REG ; /* Scroll X */ -__REG LY_REG ; /* LCDC Y-coordinate */ -__REG LYC_REG ; /* LY compare */ -__REG DMA_REG ; /* DMA transfer */ -__REG BGP_REG ; /* BG palette data */ -__REG OBP0_REG ; /* OBJ palette 0 data */ -__REG OBP1_REG ; /* OBJ palette 1 data */ -__REG WY_REG ; /* Window Y coordinate */ -__REG WX_REG ; /* Window X coordinate */ -__REG KEY1_REG ; /* CPU speed */ -__REG VBK_REG ; /* VRAM bank */ -__REG HDMA1_REG ; /* DMA control 1 */ -__REG HDMA2_REG ; /* DMA control 2 */ -__REG HDMA3_REG ; /* DMA control 3 */ -__REG HDMA4_REG ; /* DMA control 4 */ -__REG HDMA5_REG ; /* DMA control 5 */ -__REG RP_REG ; /* IR port */ -__REG BCPS_REG ; /* BG color palette specification */ -__REG BCPD_REG ; /* BG color palette data */ -__REG OCPS_REG ; /* OBJ color palette specification */ -__REG OCPD_REG ; /* OBJ color palette data */ -__REG SVBK_REG ; /* WRAM bank */ -__REG IE_REG ; /* Interrupt enable */ +__REG P1_REG ; /**< Joystick: 1.1.P15.P14.P13.P12.P11.P10 */ +__REG SB_REG ; /**< Serial IO data buffer */ +__REG SC_REG ; /**< Serial IO control register */ +__REG DIV_REG ; /**< Divider register */ +__REG TIMA_REG ; /**< Timer counter */ +__REG TMA_REG ; /**< Timer modulo */ +__REG TAC_REG ; /**< Timer control */ +__REG IF_REG ; /**< Interrupt flags: 0.0.0.JOY.SIO.TIM.LCD.VBL */ +__REG NR10_REG ; /**< Sound Channel 1 Sweep */ +__REG NR11_REG ; /**< Sound Channel 1 Sound length/Wave pattern duty */ +__REG NR12_REG ; /**< Sound Channel 1 Volume Envelope */ +__REG NR13_REG ; /**< Sound Channel 1 Frequency Low */ +__REG NR14_REG ; /**< Sound Channel 1 Frequency High */ +__REG NR21_REG ; /**< Sound Channel 2 Tone */ +__REG NR22_REG ; /**< Sound Channel 2 Volume Envelope */ +__REG NR23_REG ; /**< Sound Channel 2 Frequency data Low */ +__REG NR24_REG ; /**< Sound Channel 2 Frequency data High */ +__REG NR30_REG ; /**< Sound Channel 3 Sound on/off */ +__REG NR31_REG ; /**< Sound Channel 3 Sound Length */ +__REG NR32_REG ; /**< Sound Channel 3 Select output level */ +__REG NR33_REG ; /**< Sound Channel 3 Frequency data Low */ +__REG NR34_REG ; /**< Sound Channel 3 Frequency data High */ +__REG NR41_REG ; /**< Sound Channel 4 Sound Length */ +__REG NR42_REG ; /**< Sound Channel 4 Volume Envelope */ +__REG NR43_REG ; /**< Sound Channel 4 Polynomial Counter */ +__REG NR44_REG ; /**< Sound Channel 4 Counter / Consecutive and Inital */ +__REG NR50_REG ; /**< Sound Channel control / ON-OFF / Volume */ +__REG NR51_REG ; /**< Sound Selection of Sound output terminal */ +__REG NR52_REG ; /**< Sound Master on/off */ +__REG LCDC_REG ; /**< LCD control */ +__REG STAT_REG ; /**< LCD status */ +__REG SCY_REG ; /**< Scroll Y */ +__REG SCX_REG ; /**< Scroll X */ +__REG LY_REG ; /**< LCDC Y-coordinate */ +__REG LYC_REG ; /**< LY compare */ +__REG DMA_REG ; /**< DMA transfer */ +__REG BGP_REG ; /**< BG palette data */ +__REG OBP0_REG ; /**< OBJ palette 0 data */ +__REG OBP1_REG ; /**< OBJ palette 1 data */ +__REG WY_REG ; /**< Window Y coordinate */ +__REG WX_REG ; /**< Window X coordinate */ +__REG KEY1_REG ; /**< CPU speed */ +__REG VBK_REG ; /**< VRAM bank */ +__REG HDMA1_REG ; /**< DMA control 1 */ +__REG HDMA2_REG ; /**< DMA control 2 */ +__REG HDMA3_REG ; /**< DMA control 3 */ +__REG HDMA4_REG ; /**< DMA control 4 */ +__REG HDMA5_REG ; /**< DMA control 5 */ +__REG RP_REG ; /**< IR port */ +__REG BCPS_REG ; /**< BG color palette specification */ +__REG BCPD_REG ; /**< BG color palette data */ +__REG OCPS_REG ; /**< OBJ color palette specification */ +__REG OCPD_REG ; /**< OBJ color palette data */ +__REG SVBK_REG ; /**< WRAM bank */ +__REG IE_REG ; /**< Interrupt enable */ #endif /* _HARDWARE_H */ diff --git a/gbdk-lib/include/gbdk-lib.h b/gbdk-lib/include/gbdk-lib.h @@ -1,29 +1,6 @@ /** @file gbdk-lib.h Settings for the greater library system. */ -/** @mainpage Game Boy Development Kit 2020 API (gbdk-lib) documentation - - The following pages document much of the API for GBDK 2020. - They were automatically generated from the header files using Doxygen. - - - For the rest of the documentation, see (link to main GBDK docs here) - - - - - - - - - __Historical Information and Links from the original doc authors:__ - - Thanks to quang for many of the comments to the gb functions. Some - of the comments are ripped directly from the Linux Programmers - manual, and some directly from the pan/k00Pa document. - - <a href="http://quangdx.com/">quangDX.com</a> - - <a href="http://gbdk.sourceforge.net/">The original gbdk homepage</a> - - <a href="http://www.devrs.com/gb/">Jeff Frohwein's GB development page.</a> - A extensive source of Game Boy related information, including GeeBee's GB faq and the pan/k00Pa document. - -*/ #ifndef GBDK_LIB_INCLUDE #define GBDK_LIB_INCLUDE diff --git a/gbdk-lib/include/stdio.h b/gbdk-lib/include/stdio.h @@ -26,6 +26,9 @@ void putchar(char c); Does not return the number of characters printed. Currently supported: + \li \%hx (char as hex) + \li \%hu (unsigned char) + \li \%hd (signed char) \li \%c (character) \li \%u (unsigned int) \li \%d (signed int)

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