English version

Небольшое предисловие

Я начал интересоваться Spectrum-демосценой во второй половине 90-х. Всё это было и раньше, но в России сцена, как мне кажется, стала заметнее после первых Enlight. Моё первое демопати - Chaos Constructions’00. После этого я несколько лет участвовал в разных сценовых событиях.

Тогда многие работали на настоящих Spectrum. Эмуляторы ещё не были обычной частью процесса. Боль отладки и остальные демомейкинговые страдания казались естественными и неизбежными. Потом реальных машин стало меньше, а работать на современном ПК стало удобнее. Редакторы стали лучше, эмуляторы получили новые функции, но отладка всё равно отнимала много времени.

Со временем я стал меньше следить за сценой и начал в основном программировать за деньги. Но разработка мне всё ещё нравится. Особенно когда хорошую идею удаётся довести до конца. Программирование осталось моим хобби, просто теперь не хочется тратить всё свободное время на изнурительную отладку и бесконечные оптимизации.

За это время изменились и инструменты. Когда-то компьютеры программировали через тумблеры и перфокарты. Сравнение грубое, но смысл понятен. Потом появились языки программирования. Теперь есть инструменты, которые могут писать код вместе с нами или за нас. Для меня это ещё один способ программировать. Дебатов вокруг этого много, но статья не про них.

Я, как и многие, не люблю нейрослоп. Вокруг хватает низкосортного мусора, который делают только потому, что теперь это можно сделать быстро. Не нравится мне и привычка называть вайбкодерами всех, кто активно применяет ИИ в разработке. Термин уже успели испортить люди, которые хотели на всём этом заработать.

К тому, что я предлагаю, вайбкодинг имеет мало отношения. Многие из нас годами изучали Spectrum и знают его лучше, чем технологии, с которыми работают за деньги. Эти знания помогают ставить точные задачи и отличать хороший результат от случайного. Я предлагаю посмотреть на знакомую разработку под другим углом и попробовать сделать что-то почти без ручного написания кода.

Мне захотелось попробовать такой подход именно в Spectrum-демосцене. Коммерции здесь почти нет, поэтому эти инструменты никого не уволят и не заменят. Мы тратим это время на себя. Вы остаётесь собой, но теперь у вас под рукой возможности Сайруса, Киберджека и ТМК, вместе взятые. Почему бы не оставить больше времени на творчество?

О чём речь

Идея простая: на время меньше думать о каждой строке Z80-кода и больше заниматься идеей, устройством проекта и тем, что должно получиться в итоге.

Это не значит, что платформу можно совсем не знать, а агенту поручить всё подряд. Чем лучше вы знаете Spectrum, тем точнее сможете объяснить задачу и оценить результат. Зато можно заметно сократить самую утомительную часть работы: сборку, запуск, проверку гипотез и поиск ошибок в машинном коде.

Для этого нужен xspeccy-mcp - MCP-сервер поверх ядра эмулятора Xpeccy. Он даёт ИИ-агенту доступ к эмулятору как к инструменту: загрузить снапшот, прогнать код, снять скриншот, поставить точку останова, прочитать память, измерить время кадра и снять профиль. Агент не просто предполагает, что его код должен работать. Он может проверить это в настоящем ядре эмулятора.

Сначала - небольшая база знаний

Контекст агента не бесконечен. Во время долгой работы он сжимается, и часть конкретики теряется. Агент может забыть, где лежит таблица, какой банк сейчас переключается или почему нельзя занимать определённый адрес.

Поэтому основные сведения лучше сразу положить в репозиторий. Сложная система не нужна. Хватает нескольких Markdown-файлов с понятными именами и коротким оглавлением:

  • особенности целевой машины: модель, объём памяти, тайминг, прерывания;
  • карта памяти и назначение банков;
  • правила сборки и запуска;
  • заметки о графике, музыке, форматах ресурсов;
  • известные ограничения и проблемы.

Это рабочая память проекта, а не ещё одна документация по Z80. В неё стоит писать не только принятые решения. Полезно сохранять и причины отказа: почему оптимизация не подошла или почему свободная на вид область памяти оказалась занятой.

После сжатия контекста агент сможет перечитать эти файлы и продолжить работу. Их можно дополнять и переносить между похожими проектами. Человеку они тоже пригодятся: через неделю не придётся восстанавливать весь ход работы по коммитам.

Собирать туда весь интернет не надо. Несколько коротких файлов с точными правилами полезнее одного огромного текста. Для внешней информации достаточно ссылки и даты, когда её проверяли.

Планирование: идти от простого к сложному

Здесь нет нового метода разработки. Сначала появляется идея, потом список частей, отдельные прототипы и сборка в целое. Так же работает человек или обычная команда.

Для такого эксперимента лучше не начинать с кода. Опишите картинку, движение, ограничения по памяти, примерную частоту обновления, музыку и порядок сцен. Затем попросите агента разбить задачу на части и задать вопросы по тому, что осталось неясным.

Можно сказать, что вы временно берёте на себя роли продуктового владельца и архитектора. Для хобби-проекта это звучит слишком официально, но смысл простой: вы решаете, что должно получиться, из каких частей это собрать и в каком порядке их делать.

Например, вместо просьбы “сделай красивый быстрый эффект” лучше сказать: нужен туннель с двухбуферным экраном, без готового видео, с конкретной палитрой, в лимите памяти и с понятным запасом времени на кадр. На Spectrum такие ограничения важны. Красиво и быстро сами по себе не являются техническим заданием.

Подключение xspeccy-mcp

xspeccy-mcp нужно один раз клонировать, собрать и подключить к среде агента. В репозитории для этого есть команда python3 build.py --smoke. Она скачает поддерживаемую версию Xpeccy, соберёт сервер и прогонит тесты. Можно указать и уже скачанные исходники Xpeccy. На Windows для сборки нужен MinGW-w64, а не MSVC.

Xpeccy меняется, поэтому лучше брать версию, указанную в репозитории xspeccy-mcp. Если перейти на другую версию, интеграцию, возможно, придётся поправить. Агент может разобраться с изменениями, но после этого надо заново прогнать тесты и проверить рабочий снапшот.

Сервер работает без окна и не привязан к реальному времени. После подключения агент сможет сам запускать сборку и эмулятор столько раз, сколько потребуется.

Как меняется разработка

Цикл остаётся тем же: правка, сборка, запуск и проверка. Только теперь агент может пройти его сам и сразу исправить найденную ошибку.

В xspeccy-mcp для этого есть несколько особенно полезных операций:

  • загрузка снапшота и запуск до нужного кадра или метки;
  • брейкпоинты, регистры, чтение и запись памяти, дизассемблер;
  • PNG реального кадрового буфера и запись GIF;
  • screen_digest для сравнения атрибутов или всей экранной памяти до и после правки;
  • frame_cost для замера кадра, числа прерываний, бюджета и запаса;
  • profile для разбивки времени по участкам кода;
  • метки из файла символов sjasmplus и пошаговая отладка по исходнику после загрузки .lst.

Скриншот сохраняется в файл, который агент затем открывает и смотрит. screen_digest не заменяет просмотр, но быстро показывает, изменились ли байты экрана на проверенных кадрах.

Замеры идут в ядре Xpeccy. Учитываются прерывания, ожидание в halt, геометрия кадра и текущая машина. Перед работой надо явно выбрать модель, набор ПЗУ и конфигурацию экрана. В логах был случай, когда неверный ROM set ломал рабочие эффекты ещё во время инициализации.

У многих эффектов перед первым кадром строятся таблицы. Если начать замер раньше, в профиль попадёт инициализация, а на скриншоте может быть чёрный экран. Поэтому сначала надо дойти до main_loop или своей метки главного цикла и сохранить новый снапшот. Дальше все замеры можно начинать с него.

Работающее решение ещё не значит, что оно устраивает автора. Всё равно нужно смотреть на сцену и менять темп, форму, цвет или логику. Инструмент снимает ручную проверку кода, но не принимает творческие решения.

Память и скорость

В Spectrum-проекте приходится следить, где лежат код, экраны, таблицы, буферы, графика и музыка. Сдвиг одной части может затереть другую, причём ошибка иногда проявляется только через несколько кадров.

Поэтому карту памяти лучше вести с начала работы. Размер кода можно взять из листинга, области данных - из объявлений в исходниках, а адреса сверить по файлу меток. Состояние после инициализации проверяется чтением памяти через MCP. Так можно заметить то, чего не видно по одному исходнику: временная на вид таблица иногда нужна и во время показа.

Со скоростью порядок такой же. Сначала снимается frame_cost, потом profile показывает дорогие участки. После одной небольшой правки повторяются замер и сравнение экрана. Если цифры стали лучше, а картинка осталась прежней, правку можно оставить. Иначе она откатывается, а причина записывается в лог.

Расчёт по таблице тактов всё равно полезен при планировании. Но итог лучше снимать на собранном коде в эмуляторе. В реальной работе даже небольшой простой в halt или переход через границу ещё одного прерывания может изменить вывод об оптимизации.

Юзкейс: демо

В этой демо к началу сборки были готовы две части: девять отдельных сцен и туннельный фон. Перед их объединением обе части собрали с листингом. По листингу посчитали код, а области данных выписали из исходников. Затем через frame_cost измерили фон и каждую сцену, а через profile разложили кадр фона по процедурам. После этого составили карту всех восьми банков.

Разбор показал важную вещь: по памяти всё помещалось, а по времени кадра нет. Запаса фона не хватало на музыку, наложение и самую тяжёлую сцену. Поэтому сначала выбрали схему банков и вариант наложения, а уже потом начали писать общий движок.

Первый общий кадр сделали в самом простом виде: отдельный модуль прерываний и банков, два буфера для маски и изображения, отдельный проход наложения. Сначала проверили правильность. Замороженный фон совпал с исходным по дампам, а длинный прогон прошёл больше двух тысяч кадров. Только после этого наложение объединили с выводом фона и поменяли раскладку текстуры. Кадр подешевел примерно на 33 тысячи тактов, а screen_digest совпал на трёх полных проходах интерлейса.

Музыку сжали ZX0 и после распаковки сравнили все байты. Отдельно обнаружилась ошибка в размещении: сжатый блок сначала попал на таблицы, построенные во время инициализации. После исправления сцены добавлялись по таблице сценария, а рабочие шаги сохранялись отдельными коммитами. В конце демо прогнали целиком и отдельно проверили синхронизацию по номерам прерываний.

Для общего примера схема такая: сначала рабочие части, потом размеры, такты и карта памяти, затем простой общий вариант, проверка и только после неё оптимизация.

Логи - часть результата

Агента лучше сразу попросить вести журнал разработки. Достаточно записывать цель правки, решение, измерения, способ проверки, неудачные варианты и следующий шаг. В этой работе был общий DEVLOG и отдельные логи прототипов. Благодаря им было видно, что уже измеряли, какие варианты откатили и почему.

Лог не должен быть пересказом диалога. Нужны факты, по которым человек или агент сможет продолжить работу после паузы.

Итог

Я вижу здесь большой потенциал именно для Spectrum-сцены. Пределы стандартного железа давно примерно понятны, как и основные способы к ним приблизиться. Поэтому интерес уже не в том, кто ещё немного быстрее вращает кубик. Новый результат чаще даёт идея: форма, подача, необычный приём или сочетание эффектов.

Понимание платформы при этом никуда не делось. Spectrum всё ещё не прощает ошибок с памятью, таймингом и прерываниями. Но с xspeccy-mcp он стал немного добрее.

Вы задаёте идею и ограничения, а агент пишет и проверяет код. Часы на поиск трёх байтов, которые наехали на соседнюю таблицу, можно потратить на саму демо.


Исходники и установка: github.com/alffcpu/xspeccy-mcp

Демо, о которой шла речь: CPU, DOCKS, U