Ivan Svarkovsky’s S3-MSX-PC open-source project implements a bare-metal MSX2+ emulator running on an ESP32-S3 microcontroller and outputting 64-color VGA via a simple R-2R resistor ladder. It’s a fork of the Retro-Go emulator for ODROID-GO and other ESP32 devices, but with various optimizations.
It was tested on an off-the-shelf ESP32-S3 board with one core handling the game logic and the other video and audio output. VGA is implemented through a clever resistor network that converts digital data into an analog signal that any old monitor understands, while audio relies on Sigma-Delta modulation with a multi-stage PDM filter. The USB host port on the board allows for the connection of a keyboard.
S3-MSX-PC firmware highlights:
- Emulation Core – fMSX 6.0 — Full MSX1 / MSX2 / MSX2+ support
- Video Output
- VGA 640×480@60Hz, 16-bit parallel RGB via LCD_CAM
- Color Depth – 64 colors (2 bits per channel: R, G, B)
- Audio – PDM Stereo with hardware underrun protection
- USB Host
- Plug-and-play keyboards
- Input Latency – ~2–4 ms (USB interrupt-driven, software debounce bypassed)
- ESP32-S3 optimization
- Z80 Core Optimization – The standard switch/case opcode dispatcher kills the Xtensa branch predictor, so Ivan implemented Computed Gotos (Threaded Code) instead to pin the PC and ICount variables directly to physical 32-bit registers.
- MSX palettes are pre-shifted during init to map directly to the GPIO pins of the R-2R ladder. The ESP32’s LCD_CAM peripheral is used to DMA-blast pixels to the monitor, utilizing the hardware lcd_byte_order=1 flag for zero-CPU-cost byte swapping.
- Fighting PSRAM Latency – Ivan integrated cycle-accurate studio audio chips (PSG, SCC, OPLL), but removed 400KB of PSRAM lookup tables. They were replaced with 1-cycle integer bit-shifts, and the core 11KB tables were locked into DRAM_ATTR.
- Zero-Heap State Compression – Standard zlib crashes the ESP32-S3 when saving 4.4MB machine states, so Ivan wrote a custom streaming LZ77 compressor (“Delta-Stride LZ”) that understands the MSX VRAM geometry (128/256-byte strides). It performs a vertical rep-match XOR-delta pass and streams directly to the SD card, using exactly 0 bytes of heap RAM.
The project uses the ESP-IDF v5.4.4 framework. The S3-MSX-PC firmware was tested on a DIYables ESP32-S3 development board with an ESP32-S3-WROOM-1-N16R8 module ($4 on AliExpress, $12 on Amazon), but it should work on most other ESP32-S3 boards with similar flash and PSRAM capacity. You’ll also need to add a few resistors and capacitors for VGA video output and the PDM audio filter, plus the USB and VGA connectors wired as shown in the schematic below.
The result is a bit messy, although it could probably be cleaned up using a breakboard. I initially thought something like the Olimex ESP32-SBC-FabGL board might be a better option since there’s already a VGA connector. However, it’s based on ESP32 with LX6 cores, and Ivan told us that “getting standard emulator code (based on fMSX) to run smoothly on the ESP32-S3 required heavily modifying the architecture to bypass PSRAM latency and Xtensa LX7 pipeline stalls”. So any LX7-specific code might not work.
You’ll find the source code, binary release, instructions, and a “technical deep dive” with code snippets and compilation metrics on GitHub. Oh, and you can also watch a few short videos there proving the firmware indeed works…

Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress. We also use affiliate links in articles to earn commissions if you make a purchase after clicking on those links.






