Overview
We've ported the Fruit Jam Arcade Machine/Console Emulator to ESP32!
Pew pew! 👾 Do you wanna play a game of pixel-accurate Space Invaders 🛸, even when you can't remember where you put your original 1978 Taito or Midway arcade cabinet. Or maybe Mr. or Ms. Pac-Man 🍒 is more your speed? Heck yesh! Donkey Kong 🦍? Check. Galaga ✨? YES! How about some 🍔 Burger Time 🍟? Totally!! Lunar Rescue 🌕 perhaps? LET'S DO THIS!!!
What about a dedicated Game Boy or Nintendo Entertainment System (NES) with microSD card cartridges?
Rather than running them on the Intel 8080 or Zilog Z80 or MOS 6502-based arcade PCBs, these are native Arduino ports for the Feather ESP32 v2 + 2.4" TFT FeatherWing, which loads your original game ROMs from a microSD card at boot. The video is output to the TFT LCD color display with I2S audio sent to a speaker via the MAX98357A 3W Class D Amp breakout.
This single arcade machine port architecture is a contrast to the MAME (Multiple Arcade Machine Emulator) concept in a couple of key ways. One, it runs on a microcontroller instead of a computer + operating system, so your game boots up instantly and requires no fiddling around and associated overhead. And two, you get one game, and one game only at a time to play on your machine, so you can stop rage-quitting and launching something else!
Wii or SNES/NES Classic Controller
These official Nintendo controllers made for the Wii/WiiU and NES Classic/SNES Classic consoles are excellent and they communicate over I2C. This allows you to use real controllers without the need for a USB Host.
Get real OEM controllers on auction sites or local game stores, the clones are hit-and-miss.
Page last edited October 04, 2026
Text editor powered by tinymce.
Code
The Adafruit Arcade Machines library for Arduino contains example games for Feather ESP32 V2 (and Fruit Jam, but that's in a different guide).
These ports were created using Claude Code. See the bottom of this page for development notes from the porting sessions.
The project source code lives here on GitHub. There are instructions at the bottom of this page for compiling and flashing your board inside the Arduino IDE. But rather than compile it, you can download the latest .bin releases here for:
- Space Invaders
- Lunar Rescue
- Galaga
- Pac-Man
- Ms. Pac-Man
- Donkey Kong
- Burger Time
and consoles:
- Nintendo Game Boy
- Nintendo Entertainment System
Head to the latest release and scroll down to the Assets section. Click on the .bin file you want to download.
Install the Game .bin
You can use the Web Serial ESPTool to program the .bin file onto the Feather by following the instructions shown here.
Alternatively, you can install command line esptool on your computer as shown here and then run this command from a shell:
esptool.py --chip esp32 --port /dev/cu.SLAB_USBtoUART write_flash 0x0 btime_featheresp32.bin
SD Card setup
Format your microSD card as FAT32/MBR. Create two top level directories on the card:
- /rom/
- /samples/
File naming in /rom/: files are loaded in reverse alphabetical order starting at ROM address 0x0000. The standard MAME chip naming (.h → .g → .f → .e) naturally maps to the correct addresses. Other compatible ROMs will work as long as their chip files sort in the right order, or as a single flat 8 KB binary.
The rom/ directory represents the four memory chips on the original hardware, designated as slots h, g, f,e A typical ROM set will look like this:
/rom/
invaders.h
invaders.g
invaders.f
invaders.e
The samples/ directory contains WAV samples (we aren't emulating the original sound chip that synthesized the sounds in real-time, but instead play back samples of the originals):
/samples/
0.wav
1.wav
...
9.wav
Boot-time Errors
Errors show up as a solid-colored screen:
| Screen color | Meaning |
|---|---|
| Red | SD card missing or won't mount (check it's inserted and formatted FAT32 with an MBR partition scheme, not GPT/exFAT) |
| Yellow | Card mounted OK, but /rom/ had no usable ROM files, or every sample in /samples/ failed to load |
| (no color — game runs) | Everything loaded fine |
Per Game Assets
Here are the required assets for your SD card per game. Your best bet legally speaking is to acquire the ROM chips from an original arcade PCB and dump the ROMs onto your computer.
Lunar Rescue
/rom/
lrescue.1 (0x0000)
lrescue.2 (0x0800)
lrescue.3 (0x1000)
lrescue.4 (0x1800)
lrescue.5 (0x4000)
lrescue.6 (0x4800)
/samples/
alienexplosion.wav
rescueshipexplosion.wav
beamgun.wav
thrust.wav
bonus2.wav
bonus3.wav
shootingstar.wav
stepl.wav
steph.wav
/prom/
7643-1.cpu
Galaga
/rom/
gg1-1b.3p
gg1-2b.3m
gg1-3.2m
gg1-4b.2l
gg1-5b.3f
gg1-7b.2c
gg1-9.4l
gg1-11.4d
gg1-10.4f
prom-5.5n
prom-4.2n
prom-3.1c
prom-1.1d
Pac-Man
/rom/
pacman.6e
pacman.6f
pacman.6h
pacman.6j
pacman.5e
pacman.5f
82s123.7f
82s126.1m
82s126.3m
82s126.4a
Ms. Pac-Man
/rom/
pacman.6e pacman.6f pacman.6h pacman.6j <- Pac-Man program ROMs
u5 u6 u7 <- aux board ROMs
5e 5f <- graphics ROMs
82s123.7f 82s126.4a 82s126.1m <- colour + waveform PROMs
Donkey Kong
/rom/
c_5et_g.bin c_5ct_g.bin c_5bt_g.bin c_5at_g.bin <- Z80 program
v_5h_b.bin v_3pt.bin <- tile ROMs
l_4m_b.bin l_4n_b.bin l_4r_b.bin l_4s_b.bin <- sprite ROMs
c-2k.bpr c-2j.bpr v-5e.bpr <- palette + colour-code PROMs
s_3i_b.bin s_3j_b.bin <- 8035 program + sample ROM
Burger Time
/rom/
aa04.9b aa06.13b aa05.10b aa07.15b <- main 6502 program
ab14.12h <- sound 6502 program
aa12.7k ab13.9k ab10.10k <- charset #1 AND sprites
ab11.12k aa8.13k ab9.15k (same bytes, two layouts)
ab00.1b ab01.3b ab02.4b <- charset #2 (background tiles)
ab03.6b <- background TILEMAP, not gfx
Game Boy
On your SD card create a directory named cart and put your game's .gb file inside of it. Note, you can't use .zip files.
/cart/
LinksAwakening.gb
Once you've played a game the console will add files next to the game:
/cart/
LinksAwakening.gb
LinksAwakening.sav <- battery save (games that have one)
LinksAwakening.fruitjam.cfg <- settings used on the Fruit Jam
LinksAwakening.feather.cfg <- settings used on the Feather
NES
On your SD card create a directory named cart and put your game's .nes file inside of it. Note, you can't use .zip files.
/cart/
SuperMarioBros.nes
Once you've played a game the console will add files next to the game:
/cart/
SuperMarioBros.nes
SuperMarioBros.sav <- battery save (games that have one)
SuperMarioBros.fruitjam.cfg <- settings used on the Fruit Jam
SuperMarioBros.feather.cfg <- settings used on the Feather
Here's how to setup, compile, and flash from with the Arduino IDE:
-
Install the esp32 board core (Espressif's, via Boards Manager — add
https://espressif.github.io/arduino-esp32/package_esp32_index.jsonas an additional board URL first). -
Install this library exactly as above. Its dependencies differ from the Fruit Jam's: this board needs
SdFat - Adafruit ForkandAdafruit ILI9341(which pulls inAdafruit GFXandAdafruit BusIO), and does not needPicoDVI - Adafruit Fork. I2S audio comes from the core's ownESP_I2S, so there is nothing to install for sound. -
Select board Adafruit Feather ESP32 V2.
-
Prepare the SD card exactly as for the Fruit Jam (FAT32, MBR) and put it in the FeatherWing's microSD slot.
-
File → Examples → Adafruit Arcade Machines → Games →
_featheresp32, and upload over USB serial.
Page last edited October 04, 2026
Text editor powered by tinymce.
Handheld Build
Place and Solder TFT Header Pins
Follow the Fritzing diagram to place the two short Feather header pin rows on the top side of the Perma Proto board with their longer side facing upwards. This is the set of pins the TFT will connect to.
Fit the TFT FeatherWing onto the pins to hold them in place, then flip the board over and solder them.
Place and Solder Feather Pins and Header Sockets
Follow the Fritzing diagram to place the two short Feather header sockets on the back side of the board.
Then, push the short feather header pins into those, and then set the Feather on top of those pins as shown.
Solder the Feather header pins to the Feather.
Flip the board over, using the Feather (and some tape or silicone band) to hold the sockets in place. Then, solder the sockets in place onto the Perma Proto board.
Add I2S Amp
Use the provided header pins to solder the I2S 2W Class D M98357A Mono amplifier as shown in the Fritzing diagram.
Flip the board over (securing the amp in place from falling out with tape or a silicone band) and solder the pins from the other side as well.
Trim the excess amp header pin length with diagonal cutters.
Add Pull Up Resistors
Add the four pull up resistors from the four buttons to the 3.3V rail as shown in the Fritzing diagram. A value of around 10K works well for these, but anything from 4.7K to 22K is great.
After soldering, trim the excess leads.
Wire Power and Ground
Following the Fritzing diagram, wire the power and ground rails from the Feather 3V and GND pins respectively. Then, connect both sides of the Perma Proto board's power and ground rails.
Go to Ground
Next, follow the circuit diagram to run all of the button ground wires to one of the two ground rails.
Solder the wires in place and trim the excess leads.
I've Got the Power!
Now, run a red wire jumper from the 3.3V rail to the VIN pin on the amp.
You could choose to run the amp power from the BAT pin if you only were planning to use the handheld with the LiPoly battery plugged in, but if you try to run it from USB power and there's no battery plugged in, the amp will be starved by the low current charge level. The 3.3V rail works well and is the most versatile power source for this build.
I2S Wiring
Wire up the three I2S pins from the amp to the Feather. Remove the Feather from the board first as shown.
Speaker
Cut the connector from the end of the speaker, then trim a bit of insulation from each wire. Unscrew the screw terminals and then place the wire ends into their respective sides (red to +, black to -). Screw the terminal blocks down to secure the wires.
Optional Protective Foam
You can cut EVA foam to fit against the board where you'll grip it and another piece between the battery and board. Use double-stick foam tape to secure them.
Optional Controller
With your handheld built you can optionally plug in a Wii Classic Controller (or NES/SNES Classic Controller) over I2C using the Wii Nunchuck breakout and a STEMMA QT cable.
Or, go wireless with the 8BitDo NES/SNES/SFC Classic dongle and a compatible Bluetooth controller such as the 8BitDo SFC30 Pro.
Page last edited October 04, 2026
Text editor powered by tinymce.
Play Games
Plug in your prepared microSD card into the microSD card reader on the TFT FeatherWing. Turn the FeatherWing's ON/OFF switch to ON.
Screen Orientation
If your game graphics are upside down or sideways, press the ROTATE button until it is correct.
Put in a Quarter
Press the COIN button to add credits. You'll need two coins if you want to play pass-and-play two player games.
Press either the Player One or Player Two button to select the number of players.
Have Fun
Go make some burgers, or eat some pellets, or save the moon, or jump some barrels. It's up to you!
Battery Life
You should get about 8-10 hours of battery life, so it's perfect for those long road trips when you want to really focus on mastering Galaga. Just plug a USB power cable into the Feather to recharge.
Swap Games
Unlike the typical multiple game emulator, this is designed to be a single-game machine. However, you can upload a different game to the Feather and change out the SD card when you're ready to focus on Ms. Pac-Man, say, or one of the other games that's been ported.
Page last edited October 04, 2026
Text editor powered by tinymce.
Mini TV Build
Who says handhelds need to be handheld? This variant flips the handheld console concept on its head and turns the thing into an integrated console/TV set that you play with a controller. If you bring this on the plane and set it up on your tray table everyone will be jealous of you and you'll probably get a free extra stroopwafle.
Feather Headers
Place two sets of header pins in the Feather. Press them into the TFT FeatherWing for spacing and then solder them to the Feather.
Add Speaker
Solder the mini speaker's red wire to the amp positive (+) and the speaker's black wire to the amp negative (-) pad.
Amp Wires
Prep the five wires for the amp breakout by cutting 4" lengths and trimming some insulation from each end. Tin the wires.
Solder these wires (as shown in the Fritzing diagram):
- Red to 3V
- Black to GND
- Blue to 13
- Gray to 12
- White to 27
Amp Wires II: Auditory Bugaloo
Solder the wires to the amp now:
- Red to Vin
- Black to GND
- Gray to LRC
- White to BCLCK
- Blue to DIN
Wii Nunchuck Adapter
Plug the Wii Nunchuck adapter into the STEMMA QT port on the Feather or FeatherWing with a STEMMA QT cable.
Testing, Testing 1, 2, 3...
This is a terrific time to flip the TFT FeatherWing's ON/OFF switch to the on position to make sure everything's working.
Enable Switch
So you can turn the device on and off once it's enclosed, you'll add a slide switch.
Clip one outer leg from the slide switch. Then, tin the remaining two legs with solder.
Cut two 3" lengths of wire, then strip a bit of insulation from each end and tin the wires.
Solder the two wires to the two switch legs.
Solder the two wires (order doesn't matter) to the GND and En pin on the Feather TFT as shown.
3D Case
Print the files linked below in PLA filament with standard settings. Extra points for translucent PLA because it looks super rad.
Assembly
Place the battery in the case as shown.
Peel the sticker adhesive protection film and place it in the base of the case.
Feed the controller end through the opening and plug it into the Wii Nunchuck Adapter.
Charge
The battery should be good for 8-10 hours of game play. You can charge it by plugging in a USB C power cable.
Page last edited October 04, 2026
Text editor powered by tinymce.