Завершить разделение SDK и внешних проектов

This commit is contained in:
Александр Петров
2026-09-16 10:01:43 +03:00
parent 0e74aaa7ee
commit 2e7ffd64a4
1965 changed files with 373 additions and 201393 deletions
+6
View File
@@ -279,6 +279,12 @@ Quick wins:
## Прочий backlog
- [ ] **Несколько одновременных экземпляров MAME и MCP bridge (отдельная
задача, позже).** Проверить два изолированных процесса с разными
дискетами/CHD/state и двумя MCP-сессиями; в протоколе явно связывать
команду с PID/session ID, не допускать ответа от чужого процесса,
проверить сброс/exit и одновременные команды. До успешного end-to-end
теста параллельная работа MAME через MCP не гарантируется.
- [ ] factoring parse_argv из crt0/crt0_banked в общий argv.s
- [ ] `restore SP on EXIT` (паттерн z88dk +pps) — проверить нужность
- [x] ~~CI: MAME с -aviwrite для screenshot-сравнения без человека~~
+1 -1
View File
@@ -2,7 +2,7 @@
Статус: **не начато**, задача на будущее. Обвязка уже готова и обкатана —
`testkit/` (см. `testkit/README.md`); первый потребитель —
`applications/PoP/roomtest/tests-host/`. Этот документ — про то, как накрыть
`../Applications/PoP-Archive/roomtest/tests-host/`. Этот документ — про то, как накрыть
тем же способом основной продукт репозитория.
## Что это НЕ заменяет
+1 -1
View File
@@ -387,7 +387,7 @@ User's ISR НЕ должен:
## Phase 1 acceptance
- `examples/irq_test/` — счётчик тиков растёт с 50 Hz
- `../Examples/irq_test/` — будущий пример: счётчик тиков растёт с 50 Hz
- Клавиатура продолжает работать через DSS chain (можно прервать тест клавишей)
- Корректный exit — DSS shell получает управление обратно без crash
- Работает во всех memory modes (tiny, small, big, huge)
+2 -2
View File
@@ -2,7 +2,7 @@
Как правильно читать клавиатуру в play-цикле: что даёт платформа, чего
она НЕ даёт, и какие паттерны использовать. Выжато из порта Prince of
Persia (applications/PoP/roomtest) и отладки багов «залипание клавиш»
Persia (`../Applications/PoP-Archive/roomtest`) и отладки багов «залипание клавиш»
(2026-07-16) и «отвал Shift» (2026-07-22).
## Почему не ESTEX
@@ -130,4 +130,4 @@ kbd_raw_close(); // вернуть клавиатуру DSS (ест
сохраняются), см. libc/kbd/kbd_raw_sync.c.
Связанные документы: docs/mame-autotest.md, docs/im2_isr_design.md,
docs/converted/IvanMak.txt §9.4, applications/PoP/docs/PORT_PLAN.md §2.
docs/converted/IvanMak.txt §9.4, `../Applications/PoP-Archive/docs/PORT_PLAN.md` §2.
+5 -5
View File
@@ -269,7 +269,7 @@ tests/bgi_img.
колоночный accel-проход: STOP между чтением и записью позволяет безопасно
сменить Port_Y, промежуточный RAM-буфер не нужен). Копия = скролл + heal
цели (банк 0x50). Открывшуюся полосу |d| не заполняют — возвращают в
*dirty (NULL = не нужно). Пример: examples/scroll.
*dirty (NULL = не нужно). Пример: `../Examples/scroll`.
Для произвольных EMM-данных, которые затем маппятся в W0,
`gfx_w0_page_prepare(page)` устанавливает IRQ/NMI-стабы в `0x38/0x66` и
запоминает штатную DSS-страницу. `atlas_load()` вызывает её автоматически.
@@ -306,7 +306,7 @@ banked-функции; только volatile-глобалы и быстрая р
## <kbd_raw.h> — эксклюзивный raw-канал клавиатуры (вектор 0xFF, свой путь)
Мотивация — applications/PoP/docs/PORT_PLAN.md §2: ESTEX
Мотивация — `../Applications/PoP-Archive/docs/PORT_PLAN.md` §2: ESTEX
kbhit/getch/getkey/kbd_mod_state — событийные, без held-state для
обычных (не модификаторных) клавиш. Decode make/break (PS/2 Scan Code
Set 2: `0xF0` — префикс отпускания, `0xE0` — префикс расширенной
@@ -332,7 +332,7 @@ UP/DOWN/RIGHT — из этого сделан ОШИБОЧНЫЙ вывод «
нажать». На самом деле причина была в неудачном таймінге снимков
относительно дуги прыжка, а не в отсутствии сигнала. Подтверждено
брейкпоинтом в отладчике MAME (adress уровня приложения на входе в
код `jumping=1` в `applications/PoP/poc/poc.c`): `press_key('up')`
код `jumping=1` в `../Applications/PoP-Archive/poc/poc.c`): `press_key('up')`
ЧЕСТНО доходит до raw-декодера и триггерит код прыжка — брейкпоинт
сработал ровно один раз за одно удержание клавиши (это же заодно
подтвердило фикс двойного триггера через `up_prev` edge-detect в
@@ -373,7 +373,7 @@ FIFO SIO — 3 байта, и рассчитывать на «каждый ба
опрос луча, а это ~2/3 периода кадра. Проверено: 35 нажатий стрелки с
зажатым Shift → 35 дошедших make против 9 из 10 без хука. Остаточные
редкие потери возможны (пачка целиком внутри DI-окна одного accel-прохода);
полный протокол и что делать дальше — `applications/PoP/roomtest/TASKS_CLOSED.md`,
полный протокол и что делать дальше — `../Applications/PoP-Archive/roomtest/TASKS_CLOSED.md`,
задача KBD-1.
**ГЛАВНОЕ СЛЕДСТВИЕ:** пока `kbd_raw_open()` активен, `kbhit/getch/getkey/
@@ -387,7 +387,7 @@ MAME дёргает ОБЕ клавиатуры (PC ms_naturl + ZX-матриц
одновременно — наблюдался паразитный незатухающий бит от ZX-пути
(обычный код без EXT-префикса, застревал в DOWN) — не воспроизводится
на реальном сценарии (только PC/AT-клавиатура, без матрицы, см.
applications/PoP/docs/PORT_PLAN.md §2 — пользователь подтвердил, что
`../Applications/PoP-Archive/docs/PORT_PLAN.md` §2 — пользователь подтвердил, что
матрица на Sprinter давно не используется). Для будущих MAME-тестов
этой функции — бить только по `:kbd:ms_naturl:*`, не через
удобный `press_key` (или перепроверить точную семантику полей моста).
+39 -33
View File
@@ -17,21 +17,21 @@ make -C tests/bgitest
# запустить в MAME, снять экран, выйти по таймауту
python3 toolchain/mame_interactive.py tests/bgitest/bgitest.exe \
--snap 12,14 --timeout 16
--mame-home /путь/к/MAME/runtime --snap 12,14 --timeout 16
```
Инструмент сам:
1. проверит, что нет висящих копий MAME;
2. положит `.exe` на дискету A: (`mame/v306/IMG/mc.img`);
1. соберёт отдельную временную FAT12-дискету с `.exe`;
2. создаст отдельные каталоги MAME для cfg/NVRAM/diff/snapshot;
3. запустит MAME с драйвером `sprinter`;
4. дождётся приглашения `C:\>` и **напечатает `a:\bgitest.exe` + Enter**
(эмулируя нажатия клавиш);
4. в момент `--launch-at` **напечатает `a:\bgitest.exe` + Enter**
(эмулируя нажатия клавиш); выбирайте время после загрузки DSS;
5. снимет скриншоты в указанные секунды эмулированного времени;
6. завершит сессию по таймауту;
7. выведет пути к PNG-скриншотам.
Скриншоты лежат в `mame/v306/snap_auto/sprinter/` (`0000.png`, `0001.png`,
…). Их читает Claude визуально (инструментом Read) — текст с экрана
Скриншоты лежат в `build/mame-autotest/<session>/sprinter/` (`0000.png`,
`0001.png`, …) относительно каталога запуска. Их можно читать визуально — текст с экрана
программно НЕ распознаётся.
---
@@ -40,7 +40,8 @@ python3 toolchain/mame_interactive.py tests/bgitest/bgitest.exe \
```
python3 toolchain/mame_interactive.py [exe] [--data f ...] \
[--launch-at T] [--step "T:TEXT" ...] [--snap t1,t2,...] [--timeout N]
[--mame-home DIR] [--mame-bin FILE] [--launch-at T] \
[--step "T:TEXT" ...] [--snap t1,t2,...] [--timeout N]
```
| Аргумент | Назначение |
@@ -51,6 +52,9 @@ python3 toolchain/mame_interactive.py [exe] [--data f ...] \
| `--step "T:TEXT"` | в момент `T` сек напечатать `TEXT`. Можно много раз — диалог с уже запущенной программой. В `TEXT`: `\n`=Enter, `\t`=Tab; заглавные и символы через Shift — автоматически. |
| `--snap t1,t2,...` | секунды эмуляции для скриншотов. По умолчанию: `launch_at+4` и `+6` (для `exe`), либо сразу после последнего ввода. |
| `--timeout N` | секунд эмуляции до принудительного выхода. По умолчанию — чуть позже последнего скриншота. |
| `--mame-home DIR` | установленная среда MAME; можно задать переменной `MAME_HOME`. |
| `--mame-bin`, `--mame-rompath`, `--mame-dss-image`, `--mame-system-hdd-image`, `--mame-bios` | выбор отдельных частей профиля; соответствуют `MAME_*` из окружения. |
| `--snapshot-dir DIR` | локальный каталог кадров вместо `build/mame-autotest`. |
**Важно:** все времена — это **секунды эмулированного времени от старта
машины** (не от нажатий, их «нет»). Загрузка DSS до `C:\>` занимает
@@ -72,7 +76,7 @@ python3 toolchain/mame_interactive.py tests/menu/menu.exe \
--step "13:2\n" --snap 15 --timeout 17
# 4. Тест с файлом-данными на дискете
python3 toolchain/mame_interactive.py examples/mdview2/mdview2.exe \
python3 toolchain/mame_interactive.py /путь/к/Examples/mdview2/mdview2.exe \
--data doc.md --step "13:mdview2 doc.md\n" --snap 16 --timeout 18
```
@@ -82,11 +86,12 @@ python3 toolchain/mame_interactive.py examples/mdview2/mdview2.exe \
### 3.1 Запуск MAME
Нативный `mame.arm` (arm64) в `mame/v306/`, драйвер `sprinter`, BIOS
v3.06. Полный набор аргументов зашит в `COMMON_ARGS` внутри скрипта:
две дискеты (A: наш `mc.img`, B: DSS 1.71u), два HDD-образа (система +
медиа), CD-ROM, ZX-Bus карта NeoGS, `-video opengl -window`,
`-snapshot_directory`, `-autoboot_script <сгенерированный .lua>`.
Профиль `MAME_HOME` выбирает `mame.arm`, `roms/`, DSS-дискету и системный
CHD. A: — временная дискета этого запуска; B: — DSS. При наличии в
установленной среде CD/NeoGS/медиа скрипт подключает их как необязательные
устройства. `-cfg_directory`, `-nvram_directory`, `-diff_directory` и
`-snapshot_directory` указывают в изолированный каталог сессии;
`-autoboot_script` получает сгенерированный Lua-файл.
### 3.2 Ввод с клавиатуры — ключевой момент
@@ -118,7 +123,7 @@ AT-клавиатуре есть (поле `P2.1`/0x4) — путь `a:\name.exe
### 3.3 Тайминг (Lua)
Генерируется `_interactive_gen.lua`, который через
Временный Lua-файл через
`emu.register_periodic` на каждом кадре сверяет **эмулированное время** и
проигрывает события ввода, снимает скриншоты и завершает сессию.
@@ -132,32 +137,33 @@ AT-клавиатуре есть (поле `P2.1`/0x4) — путь `a:\name.exe
### 3.4 Скриншоты
`manager.machine.video:snapshot()` пишет PNG в каталог из
`-snapshot_directory` (`mame/v306/snap_auto/sprinter/`). Скрипт перед
запуском чистит этот каталог, потом печатает пути к готовым файлам.
Claude открывает их инструментом Read (визуальный анализ).
`-snapshot_directory` внутри `build/mame-autotest/<session>/sprinter/`.
Каждый запуск создаёт свой каталог и печатает пути к PNG; другие сессии не
затрагиваются.
### 3.5 Завершение сессии
Два рубежа, чтобы MAME гарантированно не «завис»:
Два рубежа, чтобы MAME гарантированно завершился:
- в Lua: при `elapsed >= timeout``manager.machine:exit()` (чистый
выход);
- снаружи: shell-обёртка `timeout <N+8> ./mame.arm …` как страховка.
- снаружи: `subprocess` ожидает с ограничением wall-clock времени, затем
завершает только собственный процесс MAME.
---
## 4. Предпосылки (окружение)
- **MAME**: `mame/v306/mame.arm` + образы в `mame/v306/IMG/`
(`mc.img` — наш перезаписываемый A:, `dss171u.img`, HDD `.chd`, CD
`.iso`). Каталог `mame/` целиком в `.gitignore` — поэтому инструмент
живёт в `toolchain/`, а не рядом с MAME.
- **MAME**: задайте `MAME_HOME=/путь/к/MAME/runtime` с бинарником,
`roms/`, `IMG/dss171u.img` и `IMG/sp_hdd_sys.chd`. Исходники fork не нужны.
- **Загрузка должна доходить до `C:\>`.** `system.bat` на системном
диске НЕ должен автоматически запускать Flex Navigator или приложение —
иначе мы не попадём на командную строку и ввод уйдёт в чужую программу.
(Это файл на HDD-образе, вне репозитория; правится один раз.)
- **Нет висящих копий MAME.** Несколько одновременных инстансов пишут в
один `mc.img` и дают недостоверный результат. Скрипт проверяет это сам
(`pgrep`), но при ручных запусках MAME — проверяйте `ps aux | grep mame`.
- **Одновременный запуск нескольких MAME не проверялся.** Автотест создаёт
отдельные A:, state и снимки и при необходимости копирует системный CHD,
но это ещё не доказывает корректность параллельной работы. Особенно не
гарантируется работа нескольких процессов через MCP bridge: выбор процесса,
идентификатор сессии и арбитраж требуют отдельной проверки.
---
@@ -237,14 +243,14 @@ end
анимацией/звуком, где скриншотов мало. Пока не подключено к скрипту.
- **Ручная отладка ввода.** Запуск MAME с `-console` даёт интерактивный
Lua-REPL — удобно нащупывать поля/тайминги вживую перед скриптованием.
- **Второй видеорежим/варианты BIOS** — при необходимости менять
`COMMON_ARGS`.
- **Второй видеорежим/варианты BIOS** — выбирать `MAME_BIOS` или отдельные
аргументы профиля.
## 10. Тайминги MCP-моста (run_bridge.sh) — НЕ ждать дольше
## 10. Архивные тайминги старого MCP-моста
Запуск через `mame/v306/run_bridge.sh` + `bridge_cmd.sh` / MCP `mame-z80`.
Паузы ниже — измеренные на этой машине; ждать дольше бессмысленно, а
привычка ставить `sleep 30..60` съедает минуты на каждый прогон:
Ниже сохранены измерения прежнего ручного запуска через `run_bridge.sh` и
`bridge_cmd.sh`. Они не задают таймауты нового автотеста и DAP: автотест
использует изолированные носители, а DAP ждёт стабильный prompt DSS в VRAM.
| шаг | пауза ПОСЛЕ шага |
|-----|------------------|
+3
View File
@@ -293,6 +293,9 @@ host-моста пока не готова: FileBridge использует `fcn
живой bridge-тест не использует такой скрипт. Повторная загрузка autoboot
на reset защищена от дублирования callback. Старый mamebridge параллельно
с sdbgbridge не загружать: общая арбитрирующая сессия ещё не реализована.
Два одновременно запущенных процесса MAME через MCP bridge не проверялись;
корректная маршрутизация команд между ними не гарантируется. Это отдельная
отложенная задача в [TODO.md](TODO.md).
## Размерный регресс и оставшаяся работа
+5 -3
View File
@@ -55,8 +55,10 @@ CLI или MCP.
[sprinter-cc](../bin/sprinter-cc), [app.mk](../app.mk),
[mame_interactive.py](../toolchain/mame_interactive.py),
[bank.s](../runtime/bank.s), [crt0_banked.s](../runtime/crt0_banked.s).
Локальная интеграция: `mame/sources/MAME/plugins/mamebridge/init.lua`,
`mame/sources/MAME/src/mame_mcp.py`.
MAME fork теперь самостоятельный проект: `MAME/plugins/mamebridge/init.lua`,
`MAME/src/mame_mcp.py`; среда запуска задаётся `MAME_HOME`, а исходники
fork приложению не нужны. Расширение VS Code находится в отдельном
`VSCode-Sprinter`; Python DAP backend остаётся в SDK.
## 2. Доказательства и пределы выводов
@@ -559,7 +561,7 @@ Stdout адаптера содержит только DAP, диагностик
### 8.3 Разработка и запуск из редактора
**Архитектурное решение:** Sprinter-специфичный цикл реализуется собственным
расширением `toolchain/vscode-sprinter-debug`. Готовые C/C++ или clangd можно
расширением `VSCode-Sprinter`. Готовые C/C++ или clangd можно
использовать для подсветки, completion и навигации, а VS Code Tasks и Debug UI
— как стандартные интерфейсы. Они не знают ABI SDCC/Z80, пакет
`.sprinter-cc-*`, DSS, банковую адресацию и протокол MAME, поэтому не могут
+1 -1
View File
@@ -41,7 +41,7 @@
## Сборка и запуск
```bash
make -C examples/mdview
make -C ../Examples/mdview
```
Запуск на целевой системе:
+68 -34
View File
@@ -1,7 +1,7 @@
# Разделение Sprinter-CC, MAME и приложений
Статус: реализация. Контракт SDK и локальных образов готов; выделение Git
репозиториев и физический перенос выполняются. Дата: 2026-09-15.
Статус: физическое разделение выполнено; завершаются локальные коммиты,
проверка документов и публикация Sprinter-CC. Дата обновления: 2026-09-16.
## Цель и границы
@@ -26,24 +26,40 @@ MAME приложению не нужны.
└── VSCode-Sprinter/ # Git-репозиторий расширения VS Code
```
Имена `C-Compiler`, `Volkov` и `PoP-Archive` пока локальные; адреса Git remote
новых репозиториев будут добавлены после создания доступных для записи URL.
Имена `C-Compiler`, `Volkov` и `PoP-Archive` приняты для локальной раскладки;
адреса Git remote новых репозиториев будут добавлены после создания доступных
для записи URL.
Отсутствие remote не мешает сохранить независимую локальную историю. Папка
`Applications/` не становится общим репозиторием: каждый продукт имеет свою
историю, релизы, игнорируемые ресурсы и тесты. Физическое расположение рядом
удобно, но не входит в контракт сборки.
Локальные точки истории после разделения:
| Репозиторий | Split/base | Итоговый локальный commit |
|---|---|---|
| Examples | `502d735` | `a76852d` |
| SprPoP | `4507ba9` | `bd300b3` |
| Volkov | `a71e3c5` | `3c1956b` |
| PoP-Archive | `716c639` | `54d0b3d` |
| VSCode-Sprinter | `68a821e` | `901d91a` |
| MAME | baseline `b0c4527c`, backend/MCP `fe7ee37a` | `37b89b78` |
Первые пять base-коммитов получены из подготовительного коммита Sprinter-CC
через `git subtree split`; поэтому их история прослеживается до исходного
монорепозитория. У выделенных репозиториев пока нет настроенных remote.
## Что принадлежит каждому проекту
| Проект | Что остаётся/переходит | Причина |
|---|---|---|
| Sprinter-CC | `bin/`, `runtime/`, `libc/`, `libbgi/`, `lib/`, общие `toolchain/`, `tests/`, `testkit/`, `app.mk`, справочник API, платформенные исследования, `release_docs/`, рецепт SDCC в `third_party/` | Это target SDK, его ABI, инструменты и собственные регрессионные тесты. libc/libbgi пока остаются вместе: их версия и ABI тесно связаны с `sprinter-cc`; дальнейшее выделение возможно после стабильного интерфейса. |
| MAME | Нынешний `mame/sources/MAME` со своим Git, изменения драйвера/OSD, патч debugger backend, общие `mamebridge` и `mame_mcp.py`, рецепты stock/sdbg сборок | Изменения ядра и общий транспорт MCP должны проверяться и выпускаться вместе с конкретной ревизией MAME. |
| Examples | Нынешние `examples/balls`, `mdview`, `mdview2`, `rpgwalk`, `scroll`, `space` и относящиеся к ним ресурсы/документы | Это демонстрации SDK с общей версией. Один репозиторий избегает множества мелких релизов. |
| SprPoP | Всё `applications/SprPoP/`: исходники, конверторы, тесты, собственные ресурсы и планы | Уже почти автономное приложение; оригинальные ресурсы и дальше остаются внешними. |
| Volkov | Всё `applications/Volkov/`: исходники, сценарии MAME, собственные тестовые носители и документы | Продукт и его проверки должны развиваться без дерева тулкита. |
| PoP-Archive | `applications/PoP/` как архив прежних PoC/roomtest и исследований | Не смешивать прежнюю историю с активным SprPoP. Если архив не нужен как рабочий клон, сохранить Git-историю и документы в отдельном архивном репозитории. |
| VSCode-Sprinter | Нынешний `toolchain/vscode-sprinter-debug`: extension, задачи сборки, конфигурации и тесты клиентской части | У расширения свои версии, упаковка VSIX и цикл обновления. Отладочный Python backend остаётся в SDK. |
| MAME | Выделенный `../MAME` со своим Git, изменения драйвера/OSD, патч debugger backend, общие `mamebridge` и `mame_mcp.py`, рецепты stock/sdbg сборок | Изменения ядра и общий транспорт MCP должны проверяться и выпускаться вместе с конкретной ревизией MAME. |
| Examples | Выделенный `../Examples`: `balls`, `mdview`, `mdview2`, `rpgwalk`, `scroll`, `space` и относящиеся к ним ресурсы/документы | Это демонстрации SDK с общей версией. Один репозиторий избегает множества мелких релизов. |
| SprPoP | Всё из прежнего `applications/SprPoP/`: исходники, конверторы, тесты, собственные ресурсы и планы | Уже почти автономное приложение; оригинальные ресурсы и дальше остаются внешними. |
| Volkov | Всё из прежнего `applications/Volkov/`: исходники, сценарии MAME, собственные тестовые носители и документы | Продукт и его проверки должны развиваться без дерева тулкита. |
| PoP-Archive | Прежний `applications/PoP/` как архив PoC/roomtest и исследований | Не смешивать прежнюю историю с активным SprPoP. Архив сохранён самостоятельным рабочим репозиторием. |
| VSCode-Sprinter | Выделенный `../VSCode-Sprinter`: extension, задачи сборки, конфигурации и тесты клиентской части | У расширения свои версии, упаковка VSIX и цикл обновления. Отладочный Python backend остаётся в SDK. |
`applications/DN/DosNavigator` и вложенные чужие клоны в PoP/Volkov —
референсы, не Sprinter-приложения. Их не превращать в продуктовые репозитории
@@ -67,8 +83,8 @@ MAME приложению не нужны.
переноса такой путь может случайно указывать на чужой каталог.
`MAME_HOME` — необязательный для сборки путь к подготовленной **среде запуска**
MAME, а не к его исходникам. Стандартные пути соответствуют нынешнему
`mame/v306` и допускают переопределение из окружения, аргументов `make` или
MAME, а не к его исходникам. Стандартные пути внутри `MAME_HOME` задают
контракт установленной среды и допускают переопределение из окружения, аргументов `make` или
локального игнорируемого файла настроек. Если `MAME_HOME` не задан,
необходимые пути можно указать отдельно; отсутствие обоих источников
диагностировать в цели запуска, не превращая пустое значение в `/mame.arm`:
@@ -103,7 +119,9 @@ DAP-launch должны брать один источник настройки,
`IMG/mc.img` и `IMG/test_hdd.chd` больше не являются выходами сборки
приложения. `make hdd` готовит локальный образ; `make run` запускает его
без `mame-link`. Для нескольких сценариев создавать отдельные носители и
state-каталоги, чтобы параллельный запуск не перезаписывал чужой тест.
state-каталоги, чтобы один запуск не перезаписывал чужие файлы. Одновременная
работа нескольких процессов MAME, особенно с MCP bridge, не проверялась и
не гарантируется; отдельная отложенная задача есть в [TODO.md](TODO.md).
Конфигурация разработчика не содержит абсолютных личных путей в Git.
Для `.img` нужен упаковщик из SDK; для `.chd` нынешний `make_hdd.sh`
дополнительно использует внешние `mtools` и `chdman`. Зафиксировать эти
@@ -179,16 +197,13 @@ MAME документируются вместе; extension не копируе
## История Git, внешние ресурсы и совместимость
До выделения репозиториев инвентаризировать незакоммиченные/неотслеживаемые
файлы в корне и отдельный dirty checkout MAME. Среди новых файлов сейчас
находятся DAP, extension, MCP-плагин, MAME patch и документы: простое
`git subtree split` по старому HEAD их потеряет. Сначала сохранить работу
в подходящих коммитах/ветках или проверенных патчах; не сбрасывать и не
перезаписывать пользовательские изменения. Затем выделить историю
`examples/`, `applications/SprPoP/`, `applications/Volkov/` и PoP через
`git subtree split` либо `git filter-repo`, проверяя состав каждого нового
Git дерева. Для MAME использовать его существующую историю, а не историю
родительского SDK, где `mame/` игнорируется.
Перед выделением были инвентаризированы незакоммиченные/неотслеживаемые
файлы в корне и отдельный dirty checkout MAME. Работу DAP, extension,
MCP-плагина, MAME patch и документов сначала сохранили в подготовительном
коммите. Истории `examples/`, `applications/SprPoP/`,
`applications/Volkov/` и PoP выделены через `git subtree split`, после чего
каждый результат импортирован как `main` самостоятельного Git-репозитория.
MAME сохранил свою исходную историю и не получил историю родительского SDK.
Новый `.gitignore` каждого проекта покрывает собственные `.exe`, объекты,
debug packages, носители, снимки, внешние источники и секреты локального
@@ -207,47 +222,66 @@ debug packages, носители, снимки, внешние источник
## Порядок работ и критерии готовности
1. **Зафиксировать текущую базу.** Список tracked/untracked файлов,
1. **Выполнено — зафиксировать текущую базу.** Список tracked/untracked файлов,
отдельный Git MAME, лицензии/внешние ресурсы, базовые результаты сборок
и smoke-тестов. Сохранить незавершённую отладочную и прикладную работу.
Критерий: никакой исходник не теряется при выделении истории.
2. **Стабилизировать контракт SDK.** В `app.mk` разделить build и run,
2. **Выполнено — стабилизировать контракт SDK.** В `app.mk` разделить build и run,
реализовать `SPRINTER_ROOT`, `MAME_HOME` и переопределения, упаковку
локального образа с проверкой `mtools`/`chdman`, общий профиль путей
и диагностику отсутствующих файлов. Перевести автотесты/launcher без
переноса дерева.
Критерий: приложение собирается без MAME и запускается с нестандартным
`MAME_BIN`/ROM/DSS/System HDD.
3. **Подготовить MAME отдельно.** Сохранить fork с точной baseline-revision,
3. **Выполнено локально — подготовить MAME отдельно.** Сохранить fork с точной baseline-revision,
stock/sdbg сборки и проверенным способом подготовки `MAME_HOME`.
Перенести MAME patch/общий MCP к их владельцу, проверить обоих провайдеров.
Критерий: два бинарника существуют одновременно, ROM/CHD и state не
коммитятся, patched DAP launch проверен.
4. **Выделить Examples.** Переписать относительные пути и источник RPG
4. **Выполнено — выделить Examples.** Переписать относительные пути и источник RPG
графики, определить формат релиза SDK+Examples. Критерий: каждый пример
собирается из собственного клона Examples при одном `SPRINTER_ROOT`,
локальные диски не затрагивают MAME или соседние проекты.
5. **Выделить приложения по одному.** Сначала SprPoP как наиболее близкий
5. **Выполнено — выделить приложения по одному.** Сначала SprPoP как наиболее близкий
к автономному контракту, затем Volkov с локальным viewer fixture, затем
архив PoP с его референсами. Переписать тесты и run-скрипты, сохраняя
их документы и историю. Критерий: каждый продукт собирается и проходит
доступные host/MAME проверки из изолированного клона без Examples и
других приложений.
6. **Выделить extension.** Научить VS Code находить SDK DAP независимо от
6. **Реализовано; остаётся ручная проверка установленного VSIX после разделения — выделить extension.** Научить VS Code находить SDK DAP независимо от
workspace, запускать build/run/debug приложения и показывать ошибки
разрешения путей/версий. Проверить VSIX в отдельном workspace SprPoP
или Volkov, а не только в `C-Compiler`. Критерий: F5 строит debug package,
ждёт DSS, доходит до `main`, принимает breakpoint/logpoint и клавиатуру;
опция родного окна MAME работает на macOS. Windows остаётся явно
ограниченной до отдельной реализации host transport.
7. **Очистить SDK и документы.** Заменить корневые цели, release-скрипт,
7. **Завершается — очистить SDK и документы.** Заменить корневые цели, release-скрипт,
README, `AGENTS.md`, инструкции автотеста/отладки и рабочие ссылки.
Проверить `make`, `make -C libc`, `make -C libbgi`, `make size-check`,
SDK host/sdbg tests и отдельные проекты. Критерий: в SDK нет tracked
приложений/примеров и игнорируемого вложенного MAME; инструкции используют
новые пути, а архивные исследования остаются доступны.
Каждый этап заканчивается проверкой в отдельном клоне и просмотром Git diff,
а не одним успешным запуском в старом общем дереве. Реальные переносы,
новые Git remote и публикация релизов выполняются отдельной задачей после
согласования этого плана.
## Проверка реализации на 2026-09-16
Успешно выполнены сборка SDK (`make`), отдельные сборки libc/libbgi,
создание `build/media/toolkit-tests.img`, release-smoke, 36 Python-тестов
source debugger (один platform skip), 12 тестов extension, все Examples,
SprPoP в обычном и `SRC_DEBUG=1` режимах с локальным CHD, 17 host-наборов
SprPoP, Volkov и PoP-Archive PoC. Живые последовательные DAP-прогоны
подтвердили patched `sdbg`, stock MAME с `osx`, клавиатурный ввод,
`SDBG_LOG` в обеих консолях и запуск SprPoP с собственного `hard2` до
`main`.
`make size-check` пока не принят: текущий baseline показывает 12 старых
увеличений (обычно +9 байт, `openenv` +188) и несколько исчезнувших прежних
тестов. Реорганизация не меняла libc/libbgi, поэтому эталон автоматически не
перезаписывался; расхождения нужно разобрать отдельно. После разделения ещё
нужна ручная проверка установленного VSIX в чистом workspace. Несколько
одновременных MAME, маршрутизация MCP между ними и Windows transport остаются
явно непроверенными сценариями.
Каждый этап заканчивается проверкой в отдельном репозитории и просмотром Git
diff. Новые Git remote для выделенных репозиториев и публикация их релизов
остаются отдельной задачей. MAME пока не публикуется: существующий `origin`
доступен только для чтения. Sprinter-CC публикуется в своём прежнем remote.
+5 -5
View File
@@ -335,7 +335,7 @@ while (game) {
}
```
Курсор мыши (пример examples/, не API): то же самое с
Курсор мыши (пример в отдельном репозитории `../Examples`, не API): то же самое с
`GFX_BANK_SPRITE`; фон под курсором живёт в ОЗУ-копии, никакой
getimage/буфер не нужен. Перерисовка — из главного цикла по
`mouse_getxy()`.
@@ -451,7 +451,7 @@ getimage/буфер не нужен. Перерисовка — из главн
цела (проверки A/B PASS). size-check: роста существующих программ
нет (новые модули тянутся только пользователями API).
Демо **examples/balls** (2026-07-11): 8 разноцветных шаров 16×16
Демо **../Examples/balls** (2026-07-11): 8 разноцветных шаров 16×16
(по спрайту на цвет, прозрачные углы) над чёрно-белой шахматкой;
скорости 1..4 привязаны к кадрам (gfx_wait_vsync, speed = кадров на
шаг: 50/25/~17/12.5 px/с — подтверждено покадровыми скриншотами),
@@ -463,7 +463,7 @@ getimage/буфер не нужен. Перерисовка — из главн
Требует зеркалирования палитры в палитру 1 (initgraph грузит EGA
только в 0) и координат drawn[2][N] per-page. Побочно ушли и
одно-кадровые артефакты перекрытий/снапшотов.
- **Фаза C — пример курсора** (examples/): мышь + putsprite/gfx_heal,
- **Фаза C — пример курсора** (`../Examples`): мышь + putsprite/gfx_heal,
он же живой тест temp-режима.
- Документация: libc-reference (раздел «Спрайты»), обновить TODO.
@@ -505,7 +505,7 @@ getimage/буфер не нужен. Перерисовка — из главн
## 9.1 Эскиз managed-движка: sprite_t + retained-модель (v2, НЕ реализовано)
Мотивация — опыт examples/balls (2026-07-11): при двойной буферизации
Мотивация — опыт `../Examples/balls` (2026-07-11): при двойной буферизации
приложение обязано помнить, где каждый спрайт РЕАЛЬНО нарисован на
КАЖДОЙ из двух страниц (drawn[2][N]), и соблюдать двухпроходную
дисциплину «heal все → блит все». Оба правила легко нарушить (heal по
@@ -643,7 +643,7 @@ src[0] предчитывался до армирования и подстав
перед триггером.
**ФИКС СНЯТ 2026-07-13.** Точная dev-MAME (сборка разработчиков
Sprinter, `mame/sources/MAME`) эмулирует ПЛМ, подавляющую CPU-байт
Sprinter, `../MAME`) эмулирует ПЛМ, подавляющую CPU-байт
триггера при активном burst'е — квирк был артефактом стоковой MAME
0.283. Проверено pixel-точно: tests/blitw, col0 @(200,150) = 0x02
GREEN по байтам VRAM (read_vram через MCP-мост). Для heal фикс был
+43 -13
View File
@@ -15,8 +15,8 @@
## Какие расширения нужны
Для build/run/debug используется собственное расширение этого проекта —
`toolchain/vscode-sprinter-debug`. Только оно знает формат source-debug
Для build/run/debug используется отдельный проект `VSCode-Sprinter`. Только
его расширение знает формат source-debug
пакета, загрузку приложения через DSS, банки Sprinter и DAP-сессию MAME.
Microsoft C/C++ или clangd можно поставить дополнительно ради completion,
@@ -41,7 +41,7 @@ pyenv exec make -C tests/hello SRC_DEBUG=1
Из корня репозитория откройте VS Code с распакованным расширением:
```sh
code --extensionDevelopmentPath="$PWD/toolchain/vscode-sprinter-debug" "$PWD"
code --extensionDevelopmentPath="/путь/к/VSCode-Sprinter" "$PWD"
```
Если команда `code` не добавлена в `PATH`, на macOS этого проекта доступен
@@ -50,10 +50,16 @@ code --extensionDevelopmentPath="$PWD/toolchain/vscode-sprinter-debug" "$PWD"
```sh
"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" \
--new-window \
--extensionDevelopmentPath="$PWD/toolchain/vscode-sprinter-debug" \
--extensionDevelopmentPath="/путь/к/VSCode-Sprinter" \
"$PWD"
```
В локальных настройках workspace задайте `sprinterDebugger.sdkRoot` и
`sprinterDebugger.mameHome`. Первый указывает на установленный C-Compiler,
второй — на среду `MAME/runtime` с бинарником, ROM и DSS/CHD. Для выбора
stock/sdbg или нестандартной установки используются поля `mameBin`,
`mameRompath`, `mameDssImage`, `mameSystemHddImage`, `mameBios` профиля launch.
Расширение в режиме `auto` использует `~/.pyenv/shims/python` при наличии
local `.python-version`; для внешнего workspace ищет установленный
`~/.pyenv/versions/3.12*/bin/python`, затем `.venv/bin/python` и известные
@@ -98,8 +104,29 @@ service-точка `main` и вводится `a:\\HELLO.EXE`. После сов
наличие prompt всё равно обязательно. Перед вводом сохраняется диагностический
снимок DSS.
Дополнительные файлы на floppy задаются массивом `data`, путь к другому MAME —
полем `mame`.
Для перенесённого SprPoP его workspace содержит локальный профиль F5:
```json
{
"type": "sprinter-mame",
"request": "launch",
"name": "Sprinter: SprPoP (VS Code)",
"build": "${workspaceFolder}/build/.sprinter-cc-sprpop",
"buildTarget": "hdd",
"appHdd": "${workspaceFolder}/build/hdd/sprpop.chd",
"launchPath": "d:\\games\\sprpop\\sprpop.exe"
}
```
Расширение перед F5 запускает `make SRC_DEBUG=1 hdd` в каталоге игры,
затем загружает EXE с её локального диска. Для такого профиля нужен
`SPRINTER_ROOT` только на этапе сборки и `MAME_HOME` при запуске.
Дополнительные файлы на floppy задаются массивом `data`; для приложения с
собственным CHD задайте `appHdd`, `launchPath` и `buildTarget: "hdd"`.
Launcher монтирует временную копию CHD как `-hard2`, а DSS вводит путь EXE
из `launchPath`. Сам debug EXE остаётся также на временной A: для проверки
сигнатуры; несовпадение кода на диске с пакетом отладки останавливает launch.
## Ручная проверка VS Code
@@ -117,7 +144,7 @@ service-точка `main` и вводится `a:\\HELLO.EXE`. После сов
launcher дождётся prompt DSS, введёт
`A:\\HELLO.EXE` и VS Code остановится в `main`.
4. Проверьте Call Stack, scope Registers и Debug Console. После Continue
должна сработать подтверждённая точка строки 31 по адресу `0x824b`.
должна сработать подтверждённая точка строки 31.
5. На остановке проверьте F11 и F10. Курсор должен переходить только после
фактической остановки CPU, а не сразу после отправки команды. На строке 62
(`getchar`) нажмите F10, щёлкните окно Sprinter MAME и нажмите латинскую `x`:
@@ -205,16 +232,19 @@ reset в native console обходят модель состояния VS Code;
локального RPC и launcher; выбор `windows` решает только сторону MAME и не
обеспечивает работу VS Code-интеграции.
Backend `sdbg` входит как воспроизводимый patch к MAME 0.287. Для локального
checkout достаточно:
Backend `sdbg` входит как воспроизводимый patch к MAME 0.287. Исходники и
рецепты теперь принадлежат самостоятельному проекту MAME:
```sh
make mame-sdbg
cd /путь/к/MAME
scripts/sprinter/build-variants.sh stock
scripts/sprinter/build-variants.sh sdbg
```
Команда идемпотентно применяет
`toolchain/mame-patches/0001-sdbg-debugger-backend.patch`, инкрементально
собирает MAME и устанавливает `mame/v306/mame.arm`.
В fork patch уже зафиксирован в Git; для чистого baseline сохранён
`scripts/sprinter/apply-sdbg-patch.sh`. Каждый вариант копируется в
`MAME_HOME/bin/stock/mame.arm` или `MAME_HOME/bin/sdbg/mame.arm` без подмены
активного `MAME_HOME/mame.arm`.
## Logpoints