Проект с открытым исходным кодом S3-MSX-PC Ивана Сварковского реализует bare-metal эмулятор MSX2+, работающий на микроконтроллере ESP32-S3 и выводящий 64-цветное VGA через простую резисторную лестницу R-2R. Это форк эмулятора Retro-Go для ODROID-GO и других устройств на ESP32, но с различными оптимизациями.
Он был протестирован на стандартной плате ESP32-S3 с одним ядром, обрабатывающим игровую логику, и другим — вывод видео и аудио. VGA реализован через хитроумную резисторную сеть, преобразующую цифровые данные в аналоговый сигнал, понятный любому старому монитору, в то время как аудио основано на сигма-дельта модуляции с многоступенчатым PDM-фильтром. Порт USB Host на плате позволяет подключать клавиатуру.
Основные возможности прошивки S3-MSX-PC:
- Ядро эмуляции – fMSX 6.0 — полная поддержка MSX1 / MSX2 / MSX2+
- Видеовыход
- VGA 640×480@60 Гц, 16-битный параллельный RGB через LCD_CAM
- Глубина цвета – 64 цвета (2 бита на канал: R, G, B)
- Аудио – стерео PDM с аппаратной защитой от опустошения буфера
- USB Host
- Клавиатуры с поддержкой plug-and-play
- Задержка ввода – ~2–4 мс (USB с прерываниями, программный антидребезг отключен)
- Оптимизация ESP32-S3
- Оптимизация ядра Z80 – Стандартный диспетчер опкодов на switch/case убивает предсказатель ветвлений Xtensa, поэтому Иван реализовал вычисляемые переходы (Threaded Code) для привязки переменных PC и ICount непосредственно к физическим 32-битным регистрам.
- Палитры MSX предварительно сдвигаются при инициализации для прямого отображения на выводы GPIO R-2R лестницы. Периферия LCD_CAM ESP32 используется для переброски пикселей через DMA на монитор, с использованием аппаратного флага lcd_byte_order=1 для перестановки байтов без затрат CPU.
- Борьба с задержками PSRAM – Иван интегрировал тактово-точные студийные аудиочипы (PSG, SCC, OPLL), но удалил 400 КБ таблиц поиска из PSRAM. Они были заменены на однотактовые целочисленные сдвиги битов, а основные таблицы размером 11 КБ были закреплены в DRAM_ATTR.
- Сжатие состояний без использования кучи – Стандартный zlib вызывает сбой ESP32-S3 при сохранении 4.4 МБ состояний машины, поэтому Иван написал собственный потоковый сжиматель LZ77 («Delta-Stride LZ»), который понимает геометрию MSX VRAM (шаги 128/256 байт). Он выполняет вертикальный проход XOR-дельта с поиском повторений и передает поток напрямую на SD-карту, используя ровно 0 байт кучи RAM.
Проект использует фреймворк ESP-IDF v5.4.4. Прошивка S3-MSX-PC тестировалась на отладочной плате DIYables ESP32-S3 с модулем ESP32-S3-WROOM-1-N16R8 ( $4 на AliExpress , $12 на Amazon ), но должна работать на большинстве других плат ESP32-S3 с аналогичным объёмом флеш-памяти и PSRAM. Вам также потребуется добавить несколько резисторов и конденсаторов для VGA-видеовыхода и PDM-аудиофильтра, а также разъёмы USB и VGA, распаянные в соответствии со схемой ниже.

Результат получился немного запутанным, хотя его, вероятно, можно было бы улучшить, используя макетную плату. Сначала я подумал, что что-то вроде платы Olimex ESP32-SBC-FabGL может быть лучшим вариантом, поскольку на ней уже есть разъём VGA. Однако она основана на ESP32 с ядрами LX6, и Иван сообщил нам, что «заставить стандартный эмуляторный код (на базе fMSX) плавно работать на ESP32-S3 потребовало серьёзной модификации архитектуры для обхода задержек PSRAM и остановок конвейера Xtensa LX7». Так что любой код, специфичный для LX7, может не работать.
Исходный код, бинарный релиз, инструкции и «техническое погружение» с фрагментами кода и метриками компиляции вы найдёте на GitHub . Ах да, ещё там можно посмотреть несколько коротких видео, подтверждающих, что прошивка действительно работает…
Выражаем свою благодарность источнику, с которого взята и переведена статья, сайту cnx-software.com.
Оригинал статьи вы можете прочитать здесь.


