Завершить разделение SDK и внешних проектов
This commit is contained in:
@@ -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-сравнения без человека~~ —
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Статус: **не начато**, задача на будущее. Обвязка уже готова и обкатана —
|
||||
`testkit/` (см. `testkit/README.md`); первый потребитель —
|
||||
`applications/PoP/roomtest/tests-host/`. Этот документ — про то, как накрыть
|
||||
`../Applications/PoP-Archive/roomtest/tests-host/`. Этот документ — про то, как накрыть
|
||||
тем же способом основной продукт репозитория.
|
||||
|
||||
## Что это НЕ заменяет
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
| шаг | пауза ПОСЛЕ шага |
|
||||
|-----|------------------|
|
||||
|
||||
@@ -293,6 +293,9 @@ host-моста пока не готова: FileBridge использует `fcn
|
||||
живой bridge-тест не использует такой скрипт. Повторная загрузка autoboot
|
||||
на reset защищена от дублирования callback. Старый mamebridge параллельно
|
||||
с sdbgbridge не загружать: общая арбитрирующая сессия ещё не реализована.
|
||||
Два одновременно запущенных процесса MAME через MCP bridge не проверялись;
|
||||
корректная маршрутизация команд между ними не гарантируется. Это отдельная
|
||||
отложенная задача в [TODO.md](TODO.md).
|
||||
|
||||
## Размерный регресс и оставшаяся работа
|
||||
|
||||
|
||||
@@ -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, поэтому не могут
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
## Сборка и запуск
|
||||
```bash
|
||||
make -C examples/mdview
|
||||
make -C ../Examples/mdview
|
||||
```
|
||||
|
||||
Запуск на целевой системе:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 фикс был
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user