Как засунуть ZX Spectrum в SEGA Mega Drive и не очуметь: Рассказ об аппаратных тупиках.
На первый взгляд задача кажется тривиальной: берём картридж на базе чипа FPGA Altera Cyclone IV (EP4CE15F23C8N), поднимаем внутри кристалла ядро Z80, подкидываем BIOS, мапим порты — и готово. Запускай Dizzy или Elite.
Воодушевлённый этой идеей, взялся за работу и действительно написал работающую базу всего за 3 дня! Логика ядра внутри ПЛИС работала, игры запускались, кнопки на геймпаде нажимались, а из телика "шёл звук". Победа казалась близкой, и я поспешил: «Почти готово, ZXS на Сеге работает!».
Но радовался таки не долго. А именно ровно до тех пор, пока не наткнулся на классический тестер ZXS, где классический спектрумовский эффект FLASH (мигание текста или элементов интерфейса за счет инверсии цвета чернил INK и бумаги PAPER). Как только игра попыталась мигнуть атрибутами, картинка развалилась на куски.
Я упёрся в глухую стену аппаратных ограничений видеопроцессора Сеги (SEGA VDP).
...
Немного лирики... Вот приблизительный внешний вид реализации на тот момент:

Снимем розовые очки... Да, внутри Sega Mega Drive физически распаян чип Z80. Но использовать его для прямого запуска ZXS не особо реально. У сеговского Z80 своя специфическая обвязка, изолированная шина и жёстко заданные порты данных, которые абсолютно несовместимы с архитектурой и таймингами оригинального ZXS. Попытка переключить его на рельсы ZXS без тотального контроля над логикой сигналов это провал.
Единственный рабочий путь — разворачивать полноценное ядро Z80 с нуля внутри кристалла FPGA, тактируя его от системного генератора.
Но как только ядро завелось, перед нами встаёт главная архитектурная проблема: как подружить пиксельный мир ZX Spectrum с тайловым миром Сеги.
Пиксели против тайлов: Логика проецирования кадра.
Спектрум рисует картинку классическим попиксельным методом (bitmap, где один байт задаёт строку из 8 пикселей). Сега же устроена принципиально иначе: она вообще не умеет выводить графику отдельными точками на экране — только готовыми тайлами (матрицами 8 × 8 пикселей).
Чтобы превратить один экран в другой, у нас есть только один путь: сделать всю полезную рабочую область ZX Spectrum набором уникальных тайлов для Сеги. Простая математика разрешения 256 × 192 пикселя даёт нам сетку 32 × 24 блока.
Итого рабочая область экрана: 32 × 24 = ровно 768 уникальных тайлов.
С областью бордюра (Border) на первый взгляд получается схитрить. Вместо того чтобы генерировать мегабайты графики, мы выделяем под бордюр всего один-единственный тайл Сеги. Видеоконтроллер консоли просто размножает его, заполняя всё внешнее пространство вокруг экрана.

План казался надёжным: мы просто гоним 768 тайлов рабочей области и 1 тайл бордюра в видеопамять (SEGA VDP) каждый VBLANK. И вот тут-то физика шины данных рушит всю задумку.
Три аппаратных тупика, которые топят эмулятор.
Попытка реализовать эту схему в лоб показала, что пропускная способность шины данных Сеги в эту математику не помещается.
1. Физический предел VBLANK.
Каждый тайл Сеги весит 32 байта. Массив из 768 тайлов — это 24 576 байт (24 КБ) чистых данных. В режиме NTSC (60 Гц) обратный ход луча VBLANK длится ничтожно мало, и DMA Сеги способен протолкнуть в VRAM максимум ~7.3 КБ. Нам нужно засунуть 24 КБ, а влезает 7. Мы отстаём более чем в три раза! (В PAL-регионе на 50 Гц окно пошире, но ситуацию в целом это не спасает).
Более того, чтобы на экране не возникало уродливых визуальных разрывов (tearing), копировать графику нужно строго синхронно с VBLANK самого Спектрума, попадая в его родные тайминги. При попытке размазать передачу 768 тайлов на несколько кадров Сеги в лоб, экран при первом же глобальном FLASH-мигании порвался ровно на четыре части.
2. "Пытка бордюром" HBLANK.
Тот самый единственный тайл бордюра должен уметь менять свой цвет на любой оттенок из палитры Спектрума (INK/PAPER). Причём делать это не раз в кадр, а на ходу — строго каждый HBLANK (во время обратного хода строки), чтобы отобразить кассетные полосы загрузки. Времени на строку у Сеги настолько мало, что обновить целый тайл в этот момент физически невозможно! Нужно подменять цвета палитры на лету, устраивая гонку за лучом.
3. Контрольный выстрел: Оверлей клавиатуры
На Спектруме без клавиатуры невозможно сделать вообще ничего — даже игру не запустишь (классическое Press ANY key или выбор джойстика в меню). А значит, нам нужно выводить поверх игры экранный оверлей с виртуальной клавиатурой. И эти ассеты — тоже тайлы! То есть к нашим несчастным, не влезающим в шину 24 КБ графики, добавляется необходимость успевать копировать ещё и оверлей с клавиатурой.
Эволюция багов:
Понимая, что 24 КБ за раз не пролазят, я попробовал применить промежуточный видеобуфер. Идея казалась логичной: пусть генератор в FPGA считает тайлы порциями, а мы будем скармливать их Сеге по частям.
Результат? Ошибка реализации и новый визуальный баг. Картинка перестала дробиться на 4 части, но теперь стало конкретно хуже! Вообще "ШЛЯПА"!!!
Как в итоге был обманут VBLANK Сеги и запущен AY-звук?
Разгадка крылась в создании специализированного видеоконтроллера ZX_SEGA_VIDEO прямо внутри ПЛИС, который взял на себя роль «переводчика» и буферного моста между двумя мирами. Вместо того чтобы гонять «сырые» тайлы по шине DMA Сеги каждый кадр, видеоядро внутри FPGA непрерывно слушает обращения Z80 к памяти, вычисляет изменения атрибутов и генерирует тайловую сетку аппаратно на лету.
Он напрямую подключен к физическим линиям слота Сеги (VA, VD), подсовывая консоли нужные данные ровно в те микросекунды, когда пришло время заваливать VDP данными.
Воодушевленный тем как это заработало, решил добавить в кристалл кастомное ядро YM2149, Для исключения цифрового хрипа и перегрузок (клиппинга) была реализована схема знакового стерео-микширования ABC с безопасным сдвигом амплитуды:
Заключение.
Система работает: ромы загружаются мгновенными снапшотами, музыка из AY-3-8910 звучит без перегрузок, а виртуальная экранная клавиатура позволяет запускать старую добрую классику прямо на 16-битной консоли.
Упрощенная схема реализации:

И в завершении: А как же честное «проигрывание кассет»?
Реализовав ядро Z80, победив экран и заставив "железку" стабильно переваривать мгновенные слепки памяти .sna, подумал... Постойте-ка... Я выстроил такой сложнейший и навороченный огород для отрисовки бордюра на HBLANK, но ведь в SNA-файлах картинка просто появляется на экране мгновенно! Весь этот аппаратный конвейер бордюра фактически простаивает. А как же честное, олдскульное проигрывание кассетных образов .tzx? Как же эти "ламповые", бегущие по бордюру полосы, под которые мы замирали в детстве (и ждать завершения которых бесило)?
Без этого Спектрум — не Спектрум.
Аппаратный магнитофон на FIFO
Чтобы реализовать честную загрузку с «кассеты» прямо внутри FPGA, программной реализации "парсера" TZX со стороны ARM было мало — из-за задержек шины и доступа к SDIO (чтение с SD карты) звук EAR уплывал, и загрузка сбоила. Тут необходим специализированный модуль с аппаратным проигрывающим FIFO-буфером, тактируемый строго от нашего системного метронома:
Теперь появился выбор. Хочется играть здесь и сейчас, — выбираем .Z80 или .SNA, система мгновенно заливает образ, и мы сразу в игре.
А вот если хочется "лампового" эффекта ностальгии, используем .TZX... Включается аппаратный плеер и по бордюру Сеги начинают бежать те самые сине-красные и желто-синие кассетные полосы, раздается тот самый незабываемый цифровой скрежет (LOAD "" и запускаем кассету). И всё это работает на реальном 16-битном Mega Drive.
Проект, который начинался как «прогулка» чуть не утонул в аппаратных ограничениях, однако превратился в полноценный, честный и хардкорный трибьют двум великим платформам нашего детства.
На этом закругляюсь. Удачного дня! Отличного настроения! И доброго здоровья!
Комментарии (24)

feyd12
15.07.2026 19:03Решил ответить на некоторый хейт по развитию возможностей флеш-картриджа в виде полноценной статьи?

shiru8bit
15.07.2026 19:03Есть трюк с повторным использованием одного тайла для разных блоков малоцветной графики: в одном битплане один бит, в другом другой, и с разными палитрами в разных местах экрана отображается разная графика из одного и того же тайла. Если графика двухцветная, можно запихать 4 тайла в один 16-цветный. Но пока не удаётся придумать, можно ли выжать из этого подхода что-нибудь полезное для нужд эмуляции экрана ZX.

ramfactory Автор
15.07.2026 19:03Эммм, тут мы получаем что нужно кроме прокачки тайлов вливать ещё и карты тайлов, а это ещё больше данных. Спекртумовский FLASH на всю область видео задаст максимум нагрузки, а ещё есть у 128к "прикол", можно сменить целиком весь экран за один присест переместив видимую область из одного куска видео памяти в другую.

shiru8bit
15.07.2026 19:03Идея в том, чтобы 16-цветных тайлов стало меньше при том же количестве визуальной информации в них. Чтобы вливать 384 тайла вместо 768, например. Если бы это была чисто монохромная графика без цвета, в тех же 256 на 192, это было бы 6 килобайт вместо 24, что укладывается в один VBlank. Но как в такой схеме сделать цветовые атрибуты, мне придумать не удалось.

kmatveev
15.07.2026 19:03Когда я дочитал то того места, в котором вы объясняете, что тайлы не успевают записаться за VBLANK, я хотел предложить копировать их построчно в процессе отрисовки кадра: копировать строку тайлов незадолго до того, как видеоконтроллер Sega начнёт отрисовывать соответствующие строки экрана. Но ваш вариант с отслеживанием обращений к видеопамяти ещё круче.

ramfactory Автор
15.07.2026 19:03Можно скопировать максимум 32 байта на одну строку HBLANK. На всю "ширину" строки, нам нужно 320/2 байт. Не пролезет.

Error1024
15.07.2026 19:03С одной стороны интересно, а с другой стороны 0 реальных технических подробностей.
И сильный запах ИИ от текста.
В целом круто, поражен на какие масштабные проекты способен ИИ.
BiTL
А ссылок никаких не будет?
feyd12
Ссылок на что конкретно?
Держите статью с обзором возможностей, если это нужно:
https://habr.com/ru/articles/1035910
BiTL
Ну, вот есть у меня Sega Mega Drive, что я должен сделать чтобы запускать на нем игры с ZX Spectrum? Я так и не понял, автор статьи сделал работающий эмулятор на картридже? Где его взять?
lleo_aha
Такой же вопрос остался после прочтения статьи. Даже ссылок на "где купить" не было.
Итого, в статье из комментов у нас есть некий "супер картридж от масяни" для которого автор сделал эмулятор спектрума? Или нет? Или не сделал?
feyd12
Я вам дал ссылку на статью с обзором карика чуть выше, там все ссылки есть, почитайте. Михаил из скромности, видимо, не указывает на свой труд ссылку.
Новую версию ОС с эмулем Спектрума он, как следует из статьи, скоро выкатит для данного продукта (InviteDrive v6 Max)
ramfactory Автор
Ну, смотрите, ссылка где купить сразу подпадает под хаб "я пиарюсь". Карт довольно известный Invite DRIVE V6 MAX. Прошу прощение за недоинформированность, согласно правилам действую.
lleo_aha
Значит не стесняйтесь, давайте ссылку на Ваш проект. Мы будем только рады!
ramfactory Автор
https://ivd6max.ramfactory.com/
lleo_aha
ну это же не ссылка на спек эмулятор проект, эх
BiTL
ну стоило бы наверное хоть как-то в статье разжевать для тупых (как я). Хотя бы намекнуть - доступен ли этот проект для пользователей? Или скоро будет? И в каком виде?