GBDK-2020: a C toolchain for retro consoles that outgrew its Game Boy origins
An updated version of GBDK, C compiler, assembler, linker and set of libraries for the Nintendo Gameboy, Nintendo Entertainment System, Sega Master System, Sega Game Gear.
At a glance
- What is it?
- The project most people meet as a Game Boy C compiler now targets seven machines across three processor families, and the repository explains exactly how the compiler underneath had to be patched to get there.
- Who is it for?
- GBDK-2020 is at its best when you want to write C, ship a real cartridge, and stay inside one project for more than one machine. The patched SDCC is not incidental plumbing, it is the reason banked code and multi-console targets work at the same time, and the top-level Makefile makes that concrete with three ports and a platform list that maps one to one onto the hardware the README advertises.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A Game Boy toolchain that learned three more consoles
GBDK started life as a Game Boy development kit, and the reason a modern fork exists at all is the compiler underneath it. The README is direct about the motivation: people had been complaining about GBDK's problems for years, and nearly all of them traced back to the age of the SDCC compiler it shipped with. Version 2.96 in the old SourceForge repository is the stated starting point for this repository.
What came out of that rebuild is a kit for three processor families. The repository description names them as sm83, z80 and 6502 based consoles, and the top-level Makefile turns the same idea into configuration:
PORTS=sm83 z80 mos6502
PLATFORMS=gb ap duck gg sms msxdos nes nes-m30-s-lomem nes-m30-s-win nes-m30-f nes-m2-h nes-m2-v
EXAMPLE_DIRS=$(PLATFORMS)
EXAMPLE_DIRS+= cross-platform megaduckRead that list as a machine list. `gb` is the Game Boy and Game Boy Color, `ap` is the Analogue Pocket, `duck` is the Mega Duck and Cougar Boy, `gg` and `sms` are the Game Gear and Master System, and the seven `nes-` entries are memory bank variants of the NES. `msxdos` appears because MSX-DOS is listed in the README as experimental rather than finished. The version number in the same file is `VER = 4.5.0`, matching the most recent tagged release.
The default branch is `develop`, the repository is not archived, and the last push was on 2026-09-28. It carries 2300 stars and 147 forks, which for a project whose audience is people writing 8-bit cartridge software is a substantial following.
Why the compiler had to be patched rather than updated
The single most useful thing in this repository is the explanation of what had to change in SDCC before other consoles could be supported. The README states that a custom build of SDCC is used, with patches, specifically to support Sega Game Gear and Master System plus the Nintendo NES. Those patches live in a separate repository, `gbdk-2020-sdcc`, with the build recipe under that repository's own `.github/workflows` directory.
That is an unusual and honest arrangement. Most toolchains would either vendor a patched compiler or quietly ship a binary with no account of the deltas. Here the patches are named, versioned and publicly built.
There is also a compatibility break worth knowing about before you upgrade anything. The default calling convention changed in SDCC 4.2, and support for it starts at GBDK-2020 4.1.0. Projects still on older GBDK versions are pointed at SDCC build 12539 or lower. The compiler driver `lcc` is the piece that fronts the current toolchain, and it is what the example builds actually invoke, so the calling convention question is really a question about what your project was compiled with rather than about the driver itself.
What release 4.5.0 added for hardware that was previously awkward
The 4.5.0 release, published on 2025-12-28, is mostly a list of things that used to require assembly or manual workarounds. Three stand out.
HRAM variable allocation arrived for sm83 with a worked example. On Game Boy hardware HRAM is fast, tiny, and awkward to place by hand, so making it a first-class target is a real convenience rather than a cosmetic one. The same release added SRAM bank support through a `#pragma dataseg DATA_<N>` directive on sm83 and z80, which is how you address cartridge save memory that spans more than one bank. It also added zx0 compression plus a `zx0_decompress()` routine for both ports, meaning the ROM space squeeze that every Game Boy developer hits has an in-tree answer now.
The graphics converter got attention too. `png2asset` can now log its conversion arguments into the generated `.c` and `.h` files, and a new `-use_metafile` option reads arguments from a sidecar `<inputfile>.meta` file instead of the command line. For asset pipelines that invoke the converter repeatedly, moving the flags out of the shell script is the difference between a maintainable build and a long string of quoted arguments.
The release also shipped three new examples: a Game Boy MBC5 rumble cart, an SMS NMI handler, and a Mega Duck laptop printer integration. Smaller changes include improved `get_bkg_xy_addr()` and `get_win_xy_addr()` helpers, better performance for banked calls, a corrected parameter order for `set_tile_submap()`, and a Game Gear interrupt link control constant renamed from `GGEXT_NINIT` to `GGEXT_NINT`, which is the kind of typo rename that would silently break existing code if you did not notice the notes.
Release 4.4.0 and the work of making the NES target real
The 4.4.0 release, published on 2025-05-19, reads as a consolidation release for the NES and the 6502 port. It updated the bundled compiler to SDCC 4.5.0 and improved NES support across the board.
Two changes stand out for anyone targeting the NES. A new `makenes` utility finalises the iNES ROM header, and the release notes say it is called automatically by `lcc`. That matters because a cartridge that builds but ships with a malformed header simply does not boot, and having the toolchain do it removes a manual step that is easy to forget. Alongside it, the NES library gained `delay()` and `reset()`, and LCD interrupt handling was tightened, including smaller palette function code size and a change making `LCD bkg_scroll_y` relative to the current scanline for better compatibility with Game Boy hardware and third party LCD interrupt handlers.
That scroll change is the kind of detail that ends someone's afternoon. Code written against the old absolute behaviour will scroll differently, and the release notes are the place to find out. The same release also added timer interrupt emulation through `add_TIM()` and `remove_TIM()` for NES, SMS and Game Gear, which is how you emulate timer-driven behaviour on hardware that has no programmable timer of its own.
It also broadened hardware coverage with a Linux ARM 64 build, and added Game Boy MBC7 accelerometer and MBC3 real time clock examples plus Mega Duck laptop keyboard, RTC and speech examples.
Building from source needs a patched compiler first
The README's position on building is blunt: unless you are recompiling to fix a bug, you do not need to build GBDK. Most people download a release archive and work from the examples folder, building with `compile.bat` on Windows or `make` elsewhere. The sources in the repository are only for people rebuilding the kit itself.
The build path is still documented, and it reads as a five step list with one hard prerequisite. On Windows you need mingw. Then you fetch the patched SDCC builds from the separate `gbdk-2020-sdcc` repository, create an `SDCCDIR` environment variable pointing at that install, and run `make` from the repository root. The Linux note is the sharpest warning in the README: do not use package managers, because the stock build will not work and you need either a compiled version or a nightly.
The Makefile confirms the shape of that build. It combines the SDCC, library and support builds, and it resolves a host toolchain prefix per platform:
TARGETCC = $(TOOLSPREFIX)gcc
TARGETRANLIB = $(TOOLSPREFIX)ranlib
ifeq ($(OS_TARGET),Win_x32)
TOOLSPREFIX = i686-w64-mingw32-
endif
ifeq ($(OS_TARGET),Win_x64)
TOOLSPREFIX = x86_64-w64-mingw32-
endifIt also guards on a minimum Doxygen version and picks up the host operating system with `HOSTOS = $(shell uname -s)` for naming the output archive, and installs to `TARGETDIR = /opt/gbdk`. The library source lives in `gbdk-lib/`, the toolchain utilities in `gbdk-support/`, and third-party licensing in `licenses/`, which is where you would look to understand what you are shipping.
Where the repository stops and the online docs begin
The repository is honest about its own scope. It tells you what is supported, which builds exist, how to get the patched compiler, and where to ask for help, and it links out for everything else. The Getting Started section on gbdk.org is named as the place to begin, and the links and third-party tools page is where emulators, graphics tools and music drivers are collected.
That division is sensible because the interesting material for a new user is not in the repository at all. Which emulator to use, how to structure a project, how to handle interrupts on a specific cartridge mapper, those are tutorial questions, and they are answered on the documentation site. The repository also points at three Discord servers and two forums, including a `#gbdk` channel on gbdev, which is a reasonable place to take a question the docs do not answer.
There is also a gallery of games and programs built with the kit, with filters for open source and cart releases. That is more useful than it sounds. Reading someone else's GBDK project tells you what a good layout looks like far faster than the getting started guide does.
One caveat about release notes. There is a rolling `gbdk-next` tag holding pre-release binaries marked explicitly as for development purposes and not officially supported, with a history of dated build commits struck through as newer ones land. Treat it as a way to see what is coming, not as something to ship a game with.
Editorial conclusion
GBDK-2020 is at its best when you want to write C, ship a real cartridge, and stay inside one project for more than one machine. The patched SDCC is not incidental plumbing, it is the reason banked code and multi-console targets work at the same time, and the top-level Makefile makes that concrete with three ports and a platform list that maps one to one onto the hardware the README advertises. The weak spot is the build-from-source path, which assumes a patched compiler you have to fetch from a second repository before anything compiles. Start from a release tarball, build the examples folder with make, and read the migration notes before moving between major versions, since the calling convention change in SDCC 4.2 and the newer fixed versus relative LCD scroll behaviour both change how existing code behaves.
Frequently asked questions
Which consoles does GBDK-2020 support?
The README lists the Game Boy and Game Boy Color, Analogue Pocket, Sega Master System and Game Gear, Mega Duck and Cougar Boy, and the NES. MSX-DOS is listed as experimental and not yet fully functional. The top-level Makefile encodes the same list as platform identifiers such as gb, ap, duck, gg, sms and the nes variants.
Do I need to compile GBDK-2020 from source to make a game?
No. The README says explicitly that unless you are recompiling to fix a bug you do not need to build GBDK. Download a release archive, unzip it, then build the examples folder with compile.bat on Windows or make elsewhere. The sources are only needed if you want to rebuild the kit with a patched SDCC.
What is the patched build of SDCC that GBDK-2020 depends on?
GBDK-2020 uses a custom SDCC build with patches so that Sega Game Gear and Master System plus the Nintendo NES can be supported. Those patches and the build recipe live in the separate gbdk-2020-sdcc repository. On Linux the README warns against package managers, since the stock SDCC build will not work and you need a compiled or nightly build.
Which version of GBDK supports the newer SDCC calling convention?
The default calling convention changed in SDCC 4.2, and support for it begins with GBDK-2020 4.1.0. Projects on older GBDK versions should stay on SDCC build 12539 or lower. Each release also has a migration notes section covering that kind of breakage.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gbdk-2020-gbdk-2020)