I’m excited to announce the project I’ve been working on for the last year and a half: Game Bub, an open-source FPGA based retro emulation handheld, with support for Game Boy, Game Boy Color, and Game Boy Advance games.
Play Video:
Game Bub can play physical cartridges, as well as emulated cartridges using ROM files loaded from a microSD card. Game Bub also supports the Game Link Cable in both GB and GBA modes for multiplayer games. I designed the hardware with a number of bonus features, like video out (HDMI) via a custom dock, a rumble motor, real-time clock (for certain games). Additionally, the hardware is designed with extensibility in mind, allowing future software improvements to expand its capabilities.
Game Bub has a custom-designed 6 layer PCB featuring a Xilinx XC7A100T FPGA with integrated memory, display, speakers, rechargable battery, GB/GBA cartridge slot, all packaged up in a custom 3D-printed enclosure.
This writeup is a detailed description of how I developed and built Game Bub. I also wrote up a document explaining the architecture of Game Bub, which is a much shorter read if you’re only interested in the technical details.
Check out the instructions, code, and design files on GitHub. Note that building a Game Bub unit is fairly complex. If you might be interested in buying a complete Game Bub kit, please fill out this form to help me gauge interest.
Introduction
I first started thinking about this project while I was finishing up work on my previous Game Boy FPGA emulator in mid-2023.
I had a lot of fun implementing a Game Boy at the hardware level, and I started thinking about how far I could take the project. I was using a Pynq-Z2 development board, which was definitely the right way to get started, but it came with a lot of limitations.
I had to use an external monitor for audio/video, and an external gamepad for input, but a real Game Boy, of course, is a portable handheld. I also wanted to add Game Boy Advance support, but the memory architecture of the Pynq-Z2 had access latency that was just barely acceptable for the Game Boy, and would have been completely unacceptable for the Game Boy Advance. I also wanted to make something less “hacky”: a real device that I could play and give to people, not just a bare PCB.
Furthermore, while there are open-source FPGA retrogaming projects (e.g. MiSTer), there doesn’t appear to be anything open-source that supports physical Game Boy and Game Boy Advance cartridges, let alone an open-source handheld device.
Thus, I somewhat naively set out to design what would become by far my most complex electrical engineering and hardware design project to date.
Goals
I set out some goals for the project:
- Build a standalone, rechargable battery-powered FPGA handheld
- Minimize cost and complexity by using off-the-shelf components wherever possible
- Capable of playing Game Boy, Game Boy Color, and Game Boy Advance games
- Capable of using physical cartridges, or emulating cartridges (reading ROM files off of a microSD card)
- Easy to use: graphical menu and in-game overlay
- Integrated display and speakers, with headphone support
- Integrated peripherals (rumble, real-time clock, accelerometer) for emulated cartridges
- HDMI video output support for playing on a big screen
- Decent looking design with good ergonomics
- Expansion opportunities in the future: support for more systems, Wi-Fi, etc.
And finally, since I was building this project for fun and learning, I wanted to be able to fully understand every single component of the system. I wanted to use my own emulator cores (e.g. not just port them from MiSTer), do my own board design, and write my own drivers to interface with peripherals.
A brief rant about FPGA retrogaming
There’s a lot of misleading marketing and hype out there around FPGA retrogaming. Some claim that FPGA retrogaming devices are not emulators (because they supposedly “act like [the system] at the gate level”), that they achieve “perfect accuracy”, or that they’re superior to software emulators.
In my opinion, this is blatantly wrong and actively harmful. FPGA retrogaming devices are emulators: they pretend to be something they’re not. And they’re only as accurate as they’re programmed to be, since they’re recreations. An FPGA can make certain aspects of accuracy easier to achieve, but it doesn’t guarantee it.
Software emulators can be extremely accurate. Furthermore, perfect accuracy (if it’s even possible) is by no means a requirement to play an entire system’s library of games. Some people claim that FPGA emulators are the only way to “preserve” a system, but I’d argue that software emulators are a significantly more accessible (no special hardware needed!) way to further this goal.
I believe that FPGA emulators have only one real advantage over software emulators: they can more easily interface with original hardware, such as physical cartridges or other consoles via link cables.
I did this project not because I think that FPGA emulators are inherently better than software emulators, but because I think they’re interesting and fun to build.
High-level design
I began work on the project by doing some initial research and sketching out a high level design.
My previous FPGA emulator project used a Xilinx Zynq chip, which integrates FPGA fabric (“PL”) with a dual-core ARM processor running Linux (“PS”). I implemented the entire emulator on the FPGA, and used the Linux system to configure the FPGA, render the UI, and load ROM files from the filesystem.
I decided to keep this same division of responsibilities: using the FPGA to do the core emulation, with a separate processor to do support tasks. However, to make the overall design easier to reason about, I decided to to use an FPGA-only chip (without any hard processor cores), and an external microcontroller (MCU) to do the tasks that the ARM cores did before.
The FPGA would consume input, directly interface to the game cartridges (through level shifters to support both the 3.3 volt GBA and 5 volt Game Boy), and output audio and video to the speakers and display. The MCU would handle the UI, read ROM files from the microSD card, initialize peripherals (display, DAC, IMU), handle power sequencing, and load the FPGA configuration.
I wanted to have Wi-Fi and Bluetooth support: Wi-Fi for software updates, and the possibility of emulating the Game Boy Advance Wireless Adapter, and Bluetooth to support wireless game controllers (when connected to an external display). To reduce complexity (and avoid the need for careful RF design), I looked only for complete Wi-Fi/Bluetooth modules with integrated antennas.
An early block diagram I sketched out
I also drew out rough sketches of what the final device might look like: placement of buttons, screen, speakers, ports, cartridge slot, and battery. I settled on a vertical Game Boy Color-esque design (as opposed to a horizontal Game Boy Advance-style design), because I felt that this would maximize the space in the back of the device for full-size Game Boy Color cartridges and a battery.
Component selection and compromises
After sketching out the goals and high level design, I started component selection: picking out each non-trivial component of the system, evaluating features and requirements (e.g. how they communicate, power consumption and voltages needed).
Since I intended to have this manufactured and assembled at JLCPCB, I strongly preferred parts that were available in their part library. One technique I even used for narrowing down part choices was finding the relevant category in their part search, and sorting by their stock count.
Microcontroller
I initially planned to use an RP2040 microcontroller, with a separate ESP32-WROOM module to support Wi-Fi and Bluetooth.
The ESP32 supports both Bluetooth Classic and LE, which is essential for supporting a wide range of controllers, and the RP2040 has USB host support, to support wired controllers.
During the schematic design process, I ended up simplifying the RP2040 + ESP32 combination to just a single ESP32-S3 module for a few reasons:
- I started running out of GPIOs on the RP2040, and I was dedicating 4 of them (2 for UART, 1 for reset, 1 for booting in firmware download mode) to communication with the ESP32. Plus, the ESP32-S3 has more GPIOs overall.
- I wanted to write the MCU firmware in Rust, and the ESP32-S3 had support for the Rust standard library (via ESP-IDF and esp-idf-hal). This seemed like it would be easier to get the software up and running.
- Fewer components means easier routing and assembly
- The ESP32-S3 has an SDIO module (for interfacing with the microSD card), and FAT filesystem support (via ESP-IDF). It would be possible to do this with the RP2040 PIO, but having a proper peripheral and driver for this makes it a lot easier.
- The ESP32-S3 is more powerful than the RP2040, and would probably be able to render a smoother UI.
However, the ESP32-S3 has one main disadvantage compared to the original ESP32: it doesn’t have Bluetooth Classic support, only LE. This would greatly limit the range of supported wireless controllers, but I believed the compromise was worth it. I also decided to scrap USB host support, because supporting USB-C dual role (switchable device or host) would have added a lot of additional complexity.
If the RP2350 microcontroller (the successor to the RP2040) had been available when I started this project, I may very well have chosen it, since it has even more power, PIO blocks, memory, and GPIO pins. I might have paired it with an RM2 radio module for Wi-Fi and Bluetooth.
Display
I wanted a display that would support integer scaling for the Game Boy Advance, which has a 240×160 pixel screen. I was also looking for a screen roughly on the order of 3.0-3.5 inches wide (diagonal), to be comfortable to hold in the hand.
I found the ER-TFT035IPS-6 LCD module from EastRising, with a 3.5 inch display, and a 320×480 pixel resolution. This allows for a 2x integer scale for the Game Boy Advance (and a 2x scale plus centering for the 160×144 Game Boy display). This checked off almost all of the boxes: integer scaling, a good size, available at a reasonable price, pretty good documentation (for the ILI9488 LCD controller).

ER-TFT035IPS-6 LCD module
The main issue, which actually ended up being fairly annoying, is that it’s a 320×480 display, not 480×320. Meaning, it’s oriented in portrait mode, not landscape. I rotated the device 90 degrees to fit in a landscape orientation, but this created two issues:
- In landscape orientation, the bottom of the display (containing the LCD driver chip and the flex cable) faces to the left or the right, which means that larger bazels are required on the left and right of the display to center the “active area” of the LCD within the handheld.
- In landscape orientation, the display refreshes from left to right, not top to bottom.
The problem with refreshing from left to right is that the Game Boy and Game Boy Advance (and almost every other system) refresh from top to bottom. This means that the display can’t be refreshed perfectly in sync with the game (zero buffering), and single buffering leads to unsightly diagonal tearing. Instead, I had to use triple buffering, where the game is writing to one framebuffer, the LCD driver is reading from another buffer, and there’s one spare swap buffer. This increases the amount of memory used – and because it needed to be accessed by both the game and LCD driver simultaneously (dual port), it needed to be stored in internal block RAM in the FPGA, a scarce resource.
So, even though the Game Boy emulator uses <10% of the total logic resources of the FPGA, and the Game Boy Advance uses around 30%, I had to use a large (more expensive, and power hungry) FPGA so that I had enough block RAM.
I
8 Comments
giancarlostoro
If Nintendo wouldn't sue you for selling these, I'd say shut up and take my money. I do wonder if they'll definitely try to sue? Its really a shame, I never thought I'd see a project like this in my lifetime in all honesty. I would love to have something that lets me just keep playing my physical gameboy games indefinitely, so even if a truck crushes my gameboy, its nice knowing I can always print a new one.
I would love to see this done with the Super Nintendo.
wwwtyro
I love the idea of open source hardware, but one issue I struggle with is – what happens when one or more components go out of production?
I suppose one solution is that the maintainers could update their component list (which might involve more than one component because of compatibility issues?). But what if I'm in the middle of purchasing the components only to discover I can't get them all? Maybe the maintainers could sell component kits? That might be a nice way to fund their work. Not sure if that would run into issues with IP laws, though.
agg23
Very nice. I'm always happy to see new FPGA implementations of retro computing hardware. I've wanted to try Chisel, but have never gotten around to it.
ConanRus
Why only GB/GBA? Mister FPGA support lot's of cores which can use the same Screen and controls: NES, SNES, various Sega consoles, C64, MSX etc.
And any cheap Chinese retro-console of the same sort support even more of them. So from a practical standpoint I don't see any advantage of this (no doubt cool) project.
bsimpson
Designing your own boards and writing the emulator is super impressive! I like the clear case too! :)
It's a good week for homebrew handhelds. Someone posted a cool one on reddit yesterday built with a Raspberry Pi:
https://old.reddit.com/r/Handhelds/comments/1in0svx/my_pi_5_…
ecshafer
I don't really know if this is a stupid idea or not, I don't really have hardware experience. But the older systems, say NES, SNES, Genesis etc are pretty simple systems. Patents also have a lifetime. Why aren't we getting recreations of the hardware via a SOC sold that near-perfectly emulates the system? The FPGA projects are as close as I see this happening, but FPGAs are pretty expensive I imagine compared to some 40 year old cpu design and 1kb of ram.
ogoffart
Awesome project! Really cool to see that the UI is built with Rust and Slint, the GUI framework I’m working on. https://github.com/slint-ui/slint
sitkack
What is the total cost for a pcb populated with components? Probably around 60-70 qty 100?
I appreciate the blog post and the writeup, it might be nice to include it in the repo.
I have been toying with a similar design, with many of the same choices. Although for the system controller pair, I'd go with RP2350B and ESP32-C61 (I think). It would be nice if there was an optional chip and pad layout to support legacy or classic BT.
Another option would be to have a USB port and support something like https://www.8bitdo.com/usb-wireless-adapter-2/ to enable legacy controllers.
It looks like supporting legacy BT while noble, could be a project killing sidequest (if you didn't already have it done!) Another out, would be exposing an SPI connection internally so someone could hack in a controller of their choice.