Anemoia turns a low-cost ESP32 into a full speed NES emulator

Running an NES emulator on a modern PC isn’t difficult. Doing it on a low-cost ESP32 is a different story. The chip has limited memory, modest processing power and none of the comforts you’d expect from a desktop computer. Yet Anemoia-ESP32 manages to run a wide selection of NES games at roughly their original speed, complete with sound, controller support, save states and several display options. That’s the impressive part. It doesn’t rely on expensive hardware or a large single-board computer. The emulator runs on a compact dual-core microcontroller that you can buy for very little money. Performance sits at about 60.1 frames per second in NTSC mode across games such as Super Mario Bros., Contra, The Legend of Zelda, Mega Man 2, Castlevania and Metroid. Kirby’s Adventure, which puts heavier demands on memory handling, runs just below 60 FPS on average

Running an NES emulator on a modern PC isn’t difficult. Doing it on a low-cost ESP32 is a different story. The chip has limited memory, modest processing power and none of the comforts you’d expect from a desktop computer. Yet Anemoia-ESP32 manages to run a wide selection of NES games at roughly their original speed, complete with sound, controller support, save states and several display options. That’s the impressive part. It doesn’t rely on expensive hardware or a large single-board computer. The emulator runs on a compact dual-core microcontroller that you can buy for very little money. Performance sits at about 60.1 frames per second in NTSC mode across games such as Super Mario Bros., Contra, The Legend of Zelda, Mega Man 2, Castlevania and Metroid. Kirby’s Adventure, which puts heavier demands on memory handling, runs just below 60 FPS on average.

Clever performance choices make it possible

The ESP32 runs at 240 MHz and includes 520 KB of SRAM. That sounds reasonable until you start dividing the memory between graphics, sound, game data, system code and emulator state. A full 256 × 240 image stored in 16-bit colour would use around 120 KB on its own. That’s a big chunk of the available memory. Anemoia-ESP32 avoids that problem by not storing a complete frame. Instead, it processes and buffers a small number of scanlines at a time, then sends them to the display in batches.

It’s a smart trade-off. Direct memory access moves the image data to the screen without making the processor handle every transfer itself. While that happens, the main CPU can continue working on the next part of the game.

The emulator also handles the NES picture processing unit one horizontal line at a time. It doesn’t try to recreate every individual graphics cycle with perfect accuracy. That reduces the workload and keeps most games running smoothly, although titles that depend on unusual mid-scanline effects may not display exactly as intended. The second ESP32 core has a real job too. It handles audio processing and controller input, leaving the main core to focus on the CPU and graphics emulation.

Compiler tuning adds another useful boost. Optimisation reportedly raised peak performance from around 58 FPS to approximately 66 FPS, giving the emulator enough breathing room to maintain its target speed during normal play.

ROM caching keeps larger games moving

Game data creates another challenge. Many NES ROMs are larger than the ESP32’s available free memory, so the emulator can’t simply load everything into RAM. It has to bring in different sections of the game as they’re needed.

Reading those sections directly from a microSD card can cause delays, especially in games that switch memory banks several times during a single frame. Anemoia-ESP32 uses a least-recently-used cache to solve this. Frequently accessed memory banks remain in RAM, while older ones get removed when the emulator needs space. Most of the time, that’s enough.

For more demanding games, the emulator can copy one ROM into a dedicated section of the ESP32’s flash storage. It can then access the game through memory mapping, which is much faster than repeatedly reading from a microSD card. There’s a downside. Rewriting internal flash too often can shorten its lifespan, so this mode makes more sense for a favourite game than for constant swapping.

Compatibility covers much of the NES library

The emulator currently supports six major cartridge mappers. Together, they account for an estimated 79 per cent of the NES game catalogue. That won’t cover every release, but it includes many of the system’s best-known titles.

ROM files load from a FAT32-formatted microSD card, and the emulator includes full audio support and save states. Recent fixes also address several practical issues, including boot loops, settings that didn’t survive a restart and display problems at lower TFT transfer speeds. These aren’t glamorous changes, but they matter. A fast emulator isn’t much use if it crashes during setup or forgets its configuration every time you switch it off.

Plenty of options for custom builds

The basic hardware requirements are simple. You need a dual-core ESP32 with at least 1 MB of flash. PSRAM isn’t required. For video, the emulator supports 240 × 320 TFT screens based on the ST7789 or ILI9341 controllers. The ST7789 is the better option for high-speed 80 MHz SPI operation.

Composite video output is available too. That lets you connect the ESP32 to a television or monitor with an RCA input, although you can’t use composite and TFT output at the same time. Control options are just as flexible. You can wire eight basic buttons directly to the board or connect original-style NES, SNES, PlayStation 1 and PlayStation 2 controllers. Serial input also supports keyboards, touch controls and USB gamepads through compatible hardware. Small ESP32 boards with built-in screens offer the easiest route to a handheld. Custom circuit boards and enclosure designs can turn the same project into something more permanent.

Small hardware, serious results

Anemoia-ESP32 doesn’t aim for cycle-perfect emulation. That would be unrealistic on this hardware. Instead, it focuses on speed, practical compatibility and efficient use of limited resources. Scanline rendering saves memory. DMA keeps display transfers moving. The second core handles sound and input. ROM caching reduces storage delays. Each decision removes a bottleneck.

The result is a compact NES emulator that runs many major games at full speed on hardware that fits in your hand. It’s not a replacement for a high-end emulator, and it doesn’t pretend to be. It’s a focused piece of engineering that gets a surprising amount from a very small chip.

Spread the love
error: