RISC-V-SoC for the Original Game Boy - Part 1
How to run RISC-V code on the original Game Boy with an FPGA-based SoC
As the release of the first block-buster FPS PC Game “DOOM” is celebrating its 31st birthday today, it has been ported to probably the widest range of hardware platforms, official and unofficial. In fact, “Can it run DOOM?” has become a cultural phenomenon, a meme, but also a challenge to hackers and makers, game developers and hardware enthusiasts. At Synogate, we specialize in acceleration of algorithms in dedicated hardware circuits, and felt the need to address the final frontier in this challenge: The original 1989 Nintendo Game Boy. Using our open-source Hardware Construction Library Gatery, we built a System-on-Chip (SoC) for hardware accelerated execution of software inside a Game Boy cartridge with an open-source RISC-V CPU running on a reconfigurable chip, or Field-programmable Gate Array (FPGA).
We’re excited to share our journey of developing our “BFC”, a cartridge that runs RISC-V compiled games (and other software) on the original Game Boy. Our goal is to breathe new life into this classic console by providing a tool for makers, hackers, developers and enthusiasts to work, tinker and play with it. Huge thanks to everyone who supported us!
- Project Background
- System Design
- Programmable logic
- The CPU
- Software Development
- Interfacing with the Game Boy
- Graphics
- Music Implementation
- SPU Development
- Controls
- Results and Achievements
- Outlook
Project Background
As software developers turned digital circuit designers, we admire the degree of control that HDLs (Hardware Description Languages) offer, while also missing the productivity and accessibility of modern software development tools. Accepting that the world does not need yet another HDL, we built our own C++ based Hardware Construction Library offering us both precision and productivity and made it free and open-source, because the world needs a better tool for chip design, and we wanted to build a community around our tool. For that, we needed attention, and also a little challenge. So what better project than running a hugely popular open-source retro game (that’s also a hardware benchmark-turned-meme) on an open-source CPU on a reconfigurable chip?
System Design
The idea was born back in 2021, when people where confined to their homes, watching Tiger King. We had just started working with Gatery, and very excited by its potential, looking for a cool project to show off its potential. Running Doom on an FPGA seemed to be the perfect idea (to most of us, at least) - but “unfortunately” Sylvain Munaut had already done this, and very well at that. So, we had to go one step further. With FPGA’s compute density and retro gaming in mind, the idea to try our luck with the Game Boy was born - the technical challenge of interfacing with hardware from 1989 being the icing on the cake of the project. Our goal was to develop a platform to show off Gatery’s capabilities by building a platform to run custom code on an unmodified Game Boy, and publish everything under open-source license to enable people to develop their own Game Boy games, at roughly the price of a used Game Boy. One of the strengths of Gatery is the ability to develop in an agile way, allowing for exploration rather than up front waterfall planning. To this end, we decided to do the port in several stages and let optimizations be guided by measurements rather than assumptions.
Programmable logic
Back when we started the project, a pandemic-induced chip shortage was wreaking havoc, as some of our readers might remember (Ever Given, anyone?). Luckily, friends in high places were able to supply us with some very nice devboards equipped with Intel® Cyclone® 10 and MAX® 10 FPGA chips (thank you!!) - both relatively capable FPGAs in a small form factor with lots of IO-pins, for a very affordable price.
For a later iteration, we decided to go for a German FPGA, CologneChip’s GateMate. This required switching to 1.8V logic, which in turn required switching from SDRAM to DDR2-SDRAM. On the upside, the lower power requirements allow the cartridge with the CologneChip FPGA to run without external power source, making it a truly independent system.
The CPU
Back in 1993, the desktop computers on which Doom was built and barely running, had upwards of 12 MHz CPU clock speed and 4 MB of RAM. The Game Boy’s CPU in contrast was by even those standards ridiculously underpowered with a 8-bit CPU running at 4 MHz and about 8 KB CPU-RAM. The lowest of today’s microcontrollers have better specs. To run Doom, the Game Boy’s CPU would therefore not play any role at all.
The main cool thing about FPGAs is that you can implement any circuit that the fabric’s capacity allows. This, although not intuitive at first, includes a CPU. RISC-V is an open-source instruction set with a considerable community. For our project, that was a perfect fit. We implemented a 4 stage pipelined RISC-V rv32i with custom instructions for fixed point multiplications, and compiled Doom’s C source code for it.
Software Development
Doom’s source code, released by id software in 1997, had always been designed with portability in mind. We compiled the Doom executable for RISC-V, and were able to run it in simulation on a PC. Finally, we added a micro-SD card slot to store it as an ELF file, alongside the assets in the WAD files.
Interfacing with the Game Boy
The games of the original Game Boy were stored on cartridges to be plugged into it. While most cartridges just contained a ROM of the game, the bus was actually designed to support various gadgets and peripherals. To connect it to the Game Boy, our team started to design a custom “motherboard” that would host the devboards, connect to the Game Boy’s bus, and fit into the Game Boy cartridge. The motherboard contains the connector for the Game Boy bus as well as level shifters to convert between the 5V of the Game Boy and the 3.3V of the Intel® FPGAs. For the address lanes, we use digital multiplexers to simultaneously do the level shifting and reduce the amount of required IO pins on the FPGA. The Game Boy bus is running only at 1 MHz, giving the FPGA plenty of time to read half the address lanes, then switch over the multiplexers, and then read the other half of the lanes. The Game Boy firmware is somewhat complicated and probably warrants a blog post of its own. It is stored in a block-RAM on the FPGA from which the Game Boy streams it through the Game Boy bus. On top of that, as the Game Boy CPU is barely fast enough to copy the frames, let alone coordinate with the GPU, we had to hand write the Game Boy assembly code in such a way that while copying, it matches the timing constraints blindly. Intermixed in this, the Game Boy polls the control inputs and reports their status to status registers in the FPGA. The ELF-loader firmare in an on-chip ROM initializes the system on startup. Oh, and we also added a USB port on the top for debugging.
Graphics
Even with the RISC-V (rv32i) running at 48 Mhz, it aches under the load of the game. After all, it was a blockbuster for a reason, setting new standards for immersion with the huge and rich ingame world. As software-only implementation, we could not get it to run with more than 2 frames per second - even non-gamers will know that this is not enough for an enjoyable gaming experience. This is another point where Gatery excels: We took everything “expensive”, i.e. compute-heavy, out of the software, and implemented it as digital circuits: Hardware acceleration! All of the actual game logic and rendering is happening in the FPGA, while the Game Boy must be fed a firmware that fetches rendered frames from the cartridge, displays them, and feeds control input back to the cartridge. The game is rendered in its original resolution: 320x200 @ 8b/pixel with a 256-element color palette. Then the aspect ratio of DOOM is considered by converting to 320x240, before downscaling to the Game Boy’s resolution of 160x120 @ 24b/pixel. To adapt colors to the original Game Boy’s display with 3 shades of gray and green, we dithered to 2b/pixel, before shuffling output into 8x8 tiles.
Music Implementation
Finally, the Game Boy connector has one analog pin: An analog audio input, and since this is Doom after all, we decided to dedicate one IO-pin and low-pass filter to it. Doom without Doom music is just not really Doom. With help from friends, we worked on extracting music code from Chocolate Doom, implementing it on our platform, and also worked on building the Sound Processing Unit (SPU) and integrating it with the rest of the system. The music implementation was a significant challenge, but by using a combination of software and hardware components, we eventually succeeded in playing the iconic Doom soundtrack by Robert Prince on our Game Boy SoC - which neither the Game Boy’s speakers nor the sound card were designed to play. The sound quality might therefore be debatable - but it’s there!!!
SPU Development
First, the bad news: SPU is still WIP. Currently, we implemented a second RISC-V core with custom instructions to emulate OPL3. The plan is to implement OPL3 as hardware.
Controls
To make it short: The original Game Boy does not have enough buttons to play Doom. With 4-directional d-pad and 4 buttons, you cannot assign all the necessary actions: moving, turning, strafing, firing, interacting, pausing, and switching weapons (let alone IDDQD!). Our first iteration was the idea of a friend: left and right for strafing (which when fighting is more important than turning), and double-tapping for rotating. However, we found that this confused testers. In the second iteration, this was therefore replaced by holding down the “B” button for strafing, still allowing to strafe quickly to evade incoming projectiles, and rotating with simple left and right press.
Results and Achievements
We’re proud to announce that our Game Boy SoC is now capable of playing Doom with music and sound effects. The cartridge had its independence day with the FPGA image loaded from flash and auto-loading the executable from SD card.
Outlook
With everything from the RTL design, to the bitfiles for the FPGAs, to the PCB design released open-source, the community now has the possibility to interact with our project on all levels: from playing and modding DOOM, to other games and programs, to the digital circuit design which the CPU and the hardware accelerators are implemented in.
Please let us know what you think about our project, and which aspects you are interest in for future, more in-depth posts.