Anemoia-ESP32 is a rewrite and port of the Anemoia Nintendo Entertainment System (NES) emulator running directly on the ESP32.
It is written in C++ and is designed to bring classic NES games to the ESP32.
This project focuses on performance, being able to run the emulator at native speeds and with full audio emulation implemented. However, games with complex mappers may induce a small speed loss.
Anemoia-ESP32 is available on GitHub under the GNU General Public License v3.0 (GPLv3).
Anemoia-ESP32.mp4
This project is proudly sponsored by NextPCB. Their support helps fund the development and continuation of this project, and I'm very grateful to have them as my first ever sponsor.
Want to make a PCB? NextPCB offers PCB fabrication and assembly services with fast turnaround times and affordable pricing to help bring your electronics projects to the next level.
- Performance
- Compatibility
- Hardware Overview
- Controls
- Getting Started
- How to Build and Upload
- Contributing
- License
Anemoia-ESP32 is heavily optimized to achieve native NES speeds on the ESP32, running at ~60.098 FPS (NTSC) with 1 frame skip and full audio emulation enabled.
Here are the performance benchmarks for several popular NES games.
Note
The following benchmarks show average framerates recorded over 8192 frames (~2 minutes) of emulation time. Some games, such as Kirby's Adventure, which frequently switch banks may experience significant FPS drops in certain sections.
| Game | Mapper | Average FPS |
|---|---|---|
| Super Mario Bros. | NROM (0) | 60.10 FPS |
| Contra | UxROM (2) | 60.10 FPS |
| The Legend of Zelda | MMC1 (1) | 60.10 FPS |
| Mega Man 2 | MMC1 (1) | 60.10 FPS |
| Castlevania | UxROM (2) | 60.10 FPS |
| Metroid | MMC1 (1) | 60.10 FPS |
| Kirby’s Adventure | MMC3 (4) | 59.57 FPS |
| Donkey Kong | NROM (0) | 60.10 FPS |
As of now, Anemoia-ESP32 has implemented six major memory mappers:
- Mapper 0
- Mapper 1
- Mapper 2
- Mapper 3
- Mapper 4
- Mapper 69
Totalling to around 79% of the entire NES game catalogue.
If you'd like to check if a certain game is supported, visit
NesCartDB and search for the game on the
right-hand side of the site. Select the specific game version
and look for the iNES Mapper number in the cart properties.
The game should be supported if the iNES Mapper number is in the list
of implemented mappers above.
Feel free to open an issue if a game has glitches or fails to boot.
Anemoia-ESP32 requires a dual-core ESP32 with a minimum of 1 MB flash memory and NO PSRAM IS REQUIRED.
- ESP32
- e.g. ESP32-DevKitC or ESP32-WROOM-32
- A 240x320 SPI TFT screen (no touch needed)
- Either an ST7789-based screen as depicted, or
- an ILI9341-based screen with 240x320 pixels
- Audio Amplifier
- e.g. a PAM8403 or PAM8302
- Speaker
- MicroSD card module
- 8 Tactile push buttons, or
- Supported Controller
- NES controller
- SNES controller
- PS1 controller
- PS2 controller
Note
ST7789-based displays are recommended as they seem to fare better with 80MHz SPI speeds and are the most compatible. ILI9341-based screens may experience screen problems at higher SPI speeds.
| Signal | ESP32 Pins |
|---|---|
| MOSI | GPIO23 |
| MISO | -1 (N/A) |
| SCLK | GPIO18 |
| CS | GPIO5 |
| DC | GPIO2 |
| RST | EN |
| Signal | ESP32 Pins |
|---|---|
| MOSI | GPIO13 |
| MISO | GPIO12 |
| SCLK | GPIO14 |
| CS | GND |
Important
If using this 3.3V microSD card module, the pull-up resistor on MISO (GPIO12) must be removed. GPIO12 is a bootstrapping pin (MTDI) that must be LOW during boot. The external pull-up on the microSD module conflicts with the boot strapping process, preventing the ESP32 from booting correctly.
| Signal | ESP32 Pins |
|---|---|
| Input | GPIO25 |
There are currently three input methods: Tactile push buttons, an NES/SNES controller, and a PS1/PS2 controller.
| Signal | ESP32 Pins |
|---|---|
| A | GPIO19 & GND |
| B | GPIO26 & GND |
| Left | GPIO32 & GND |
| Right | GPIO33 & GND |
| Up | GPIO15 & GND |
| Down | GPIO4 & GND |
| Start | GPIO27 & GND |
| Select | GPIO16 (RX2) & GND |
| Signal | ESP32 Pins |
|---|---|
| Clock | GPIO32 |
| Latch | GPIO33 |
| Data | GPIO35 |
| Signal | ESP32 Pins |
|---|---|
| Data | GPIO32 |
| Command | GPIO33 |
| Attention | GPIO26 |
| Clock | GPIO27 |
Also connect the power and ground lines if using a controller. Most controllers should work fine from 3.3V power supply.
Cheap Yellow Displays (CYD) are an all-in-one ESP32 board that comes with most of the hardware needed in this project already integrated, making it ideal for Anemoia-ESP32. Because of the limited pins brought out by the CYD, it is only practical to use a NES controller.
Hardware Needed:
- Cheap Yellow Display
- NES/SNES controller
- Speaker (optional) - Can be attached with a 1.25mm JST connector to "SPEAK" or soldered directly
| Signal | ESP32 Pins |
|---|---|
| Clock | GPIO22 (CN1/P3) |
| Latch | GPIO27 (CN1) |
| Data | GPIO35 (P3) |
The schematics, PCB design files, enclosures, and 3D models are available in the /hardware and /3d-model folder.
A PCB that provides a clean, organized way to connect and manage all peripheral modules in one place.

A PCB that offers a more complete, permanent, and compact handheld by using discrete ICs instead of breakout modules.

These are the recommended parts to use for this project.
These are affiliate links. Buying through them helps support me at no extra cost to you. Thank you for your support.
- ESP32
- 240x320 ST7789 Display
- PAM8403 Amplifier Module
- MicroSD Card Module
- TP4056 Charging Module
- S09 Buck Converter
- SS12F17 Slide Switch
- 12×12×7.3mm Tactile Push Buttons
- 40mm Speaker
Press Start + Select simultaneously in a game to open the menu.
| NES Button | SNES Buttons |
|---|---|
| A | B, A, R |
| B | Y, X, L |
| Start | Start |
| Select | Select |
| Up | D-Pad Up |
| Down | D-Pad Down |
| Left | D-Pad Left |
| Right | D-Pad Right |
| NES Button | PS1/PS2 Buttons |
|---|---|
| A | R1, R2, R3, X, O |
| B | L1, L2, L3, Square, Triangle |
| Start | Start |
| Select | Select |
| Up | D-Pad Up |
| Down | D-Pad Down |
| Left | D-Pad Left |
| Right | D-Pad Right |
No software installation required.
- Visit the Web Flash website.
- Connect your ESP32 via USB.
- Click Flash and select your ESP32's COM port.
Note
Web flashing requires a Chromium-based browser (Chrome, Edge, Opera) with WebSerial support. Firefox is not supported.
- Build and upload the
Anemoia-ESP32.inoprogram into the ESP32 following the How to build and upload instructions below.
- Format your microSD card to
FAT32. - Put .nes game roms inside the root of the microSD card.
- Insert the microSD card into the microSD card module.
- Power on the ESP32 and select a game from the file select menu.
Either use git clone https://github.com/Shim06/Anemoia-ESP32.git on the command line to clone the repository or use Code → Download zip button and extract to get the files.
- Download and install the Arduino IDE.
- In File → Preferences → Additional boards manager URLs , add:
https://espressif.github.io/arduino-esp32/package_esp32_index.json- Download the ESP32 board support
v3.2.1through Tools → Board → Boards Manager .
Important
Make sure to download version 3.2.1, as different board versions may have worse performance.
- Download the
SdFatandTFT_eSPIlibraries from Tools → Manage Libraries .
Copy and paste the TFT_eSPI configuration file into the TFT_eSPI folder.
- Navigate to your Arduino Libraries folder:
(Default location):
Documents/Arduino/libraries/TFT_eSPI - Copy your desired
User_Setup.hfile in the/User_Setupsfolder from this repository intoTFT_eSPI/and overwrite the file. Optionally, edit the#definepins as desired.
Note
If using a screen with the ILI9341 driver, open User_Setup.h in a text editor and comment out #define ST7789_DRIVER and uncomment #define ILI9341_DRIVER.
// #define ST7789_DRIVER
#define ILI9341_DRIVER- Locate your ESP32 Arduino platform directory. This is typically at:
\Users\{username}\AppData\Local\Arduino15\packages\esp32\hardware\esp32\{version}\- Copy the
platform.txtfile from this repository and paste into that folder. This file defines additional compiler flags and optimizations used by Anemoia-ESP32.
Warning
Backup your platform.txt file if you have your own custom settings already.
- Connect your ESP32 via USB.
- In the Arduino IDE, go to Tools → Board and select your ESP32 board (e.g., ESP32 Dev Module).
- Click Upload or press
Ctrl+Uto build and flash the emulator. Optionally, edit the#definepins as desired.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the GNU General Public License v3.0 (GPLv3) - see the LICENSE file for more details.


