Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# Sprinter Commander: результаты файловых панелей P3
|
||||
|
||||
Дата: 7 сентября 2026 года.
|
||||
|
||||
Статус: `PASS` в MAME для навигации, независимых панелей, EMM-store на
|
||||
границе 640/641, сортировки и явной обработки предела каталога DSS 1.71.
|
||||
|
||||
Связанные документы:
|
||||
[требования](commander-requirements.md),
|
||||
[архитектура](commander-architecture.md),
|
||||
[roadmap](commander-roadmap.md),
|
||||
[большие каталоги DSS](dss-large-directories.md)
|
||||
|
||||
## 1. Проверенная граница
|
||||
|
||||
В P3 синтетические записи заменены настоящим источником `F_FIRST/F_NEXT`.
|
||||
Каждая панель имеет собственные путь, cursor/top и физическую EMM-страницу.
|
||||
Запись панели занимает 24 байта, поэтому одна 16-КБ страница вмещает
|
||||
жёсткий продуктовый предел 640 записей и оставляет 1024 байта запаса.
|
||||
|
||||
Реализованы и проверены:
|
||||
|
||||
- шаблон перечисления `*.*` и имена DOS 8.3;
|
||||
- синтетическая `..` в некорневом каталоге без дублей `.`/`..` от DSS;
|
||||
- каталоги перед файлами и сортировка имён без учёта регистра ASCII;
|
||||
- вход в каталог, возврат через `..`/`Ctrl+PgUp`, refresh и независимость
|
||||
пассивной панели;
|
||||
- навигация `Up/Down/PgUp/PgDn/Home/End` без повторного scan;
|
||||
- частичный результат при ошибке DSS 35 и отдельная виртуальная запись
|
||||
`>>> MORE...`.
|
||||
|
||||
## 2. Сборка
|
||||
|
||||
Основная команда: `make`.
|
||||
|
||||
Конфигурация: `--memory big --safe --max-allocs 3000`.
|
||||
|
||||
| Область | Значение |
|
||||
|---|---:|
|
||||
| `_CODE` | 7728 байт (`0x8100..0x9F30`) |
|
||||
| данные | 2281 байт (конец `0xA819`) |
|
||||
| свободная куча W2 | 4839 байт |
|
||||
| стек | 1279 байт |
|
||||
| `_BANK1` — scan/sort | 2299 / 16384 байт (14,0%) |
|
||||
| `_BANK2` — renderer | 2902 / 16384 байт (17,7%) |
|
||||
| EXE | 41305 байт |
|
||||
|
||||
`check_bank_calls.py` не нашёл прямых вызовов в чужой банк или публикации
|
||||
указателей на данные банка.
|
||||
|
||||
## 3. Прямая диагностика DSS
|
||||
|
||||
Образ содержит `BIGDIR` из 680 обычных файлов. Исправленная проба `P3DIR`
|
||||
получила:
|
||||
|
||||
```text
|
||||
count=512
|
||||
errno=35
|
||||
511=B0000598.DAT
|
||||
512=B0000599.DAT
|
||||
513=
|
||||
```
|
||||
|
||||
Это подтверждает границу стабильного DSS и отсутствие продолжения за ней.
|
||||
Конкретные последние имена отражают физический порядок записей, созданный
|
||||
`mcopy`, и сами по себе не являются контрактом теста.
|
||||
|
||||
Артефакт: [экран P3DIR](../artifacts/mame-p3/panels/dss-enum-limit.png).
|
||||
|
||||
## 4. Диагностика общего пути Commander
|
||||
|
||||
Проба `P3SCAN` использует те же `sc_source_fs`, `sc_store` и `sc_sort`, что
|
||||
основная программа. Получен результат:
|
||||
|
||||
```text
|
||||
scan: rc=0 errno=35 count=512 trunc=1
|
||||
first: .. attr=10 flags=01
|
||||
last : >>> MORE... attr=00 flags=04
|
||||
```
|
||||
|
||||
Ошибка 35 сознательно остаётся в `errno` как причина усечения, но scan
|
||||
возвращает успешный частичный снимок. Красный маркер занимает последний
|
||||
элемент снимка и сортируется после файлов.
|
||||
|
||||
Артефакт: [экран P3SCAN](../artifacts/mame-p3/panels/scan-marker.png).
|
||||
|
||||
## 5. Интеграционный сценарий Commander
|
||||
|
||||
Исторические артефакты ниже сняты в MAME 0.287 с FDD `A:`. Текущий
|
||||
регрессионный сценарий предельного каталога переведён на HDD `D:`:
|
||||
`make hdd-stress` создаёт `build/hdd/p3_stress.chd`, а
|
||||
`tests/mame_p3_stress.lua` сначала переключает DSS на `D:`. FDD-сборщик
|
||||
`tests/make_p3_stress_floppy.sh` оставлен только для smoke-совместимости.
|
||||
|
||||
| Действие | Подтверждённое наблюдение | Результат |
|
||||
|---|---|---|
|
||||
| Корень | обе панели независимо открыли один реальный каталог | [PASS](../artifacts/mame-p3/panels/root-both-panels.png) |
|
||||
| Вход и `..` | левая панель вошла в `TESTDIR` и вернулась в корень | [PASS](../artifacts/mame-p3/panels/left-testdir-parent.png), [возврат](../artifacts/mame-p3/panels/enter-parent-return.png) |
|
||||
| `Ctrl+R` | после refresh сохранён выбор `INNER.TXT` | [PASS](../artifacts/mame-p3/panels/refresh-preserves-inner.png) |
|
||||
| `Tab` и навигация справа | пути и cursor/top панелей не смешиваются | [PASS](../artifacts/mame-p3/panels/independent-panel-state.png) |
|
||||
| `Ctrl+PgUp` слева | изменена только активная левая панель | [PASS](../artifacts/mame-p3/panels/ctrl-pgup-left-only.png) |
|
||||
| Вход в `EMPTY` | единственная запись — синтетическая `..`, count=1 | [PASS](../artifacts/mame-p3/panels/empty-parent.png) |
|
||||
| Вход в `MANY`, `PgDn`, `Down` | cursor/top меняются до 28/2 без rescan, рамки и соседняя панель сохраняются | [PASS](../artifacts/mame-p3/panels/navigation-scroll.png) |
|
||||
| Вход в `BIGDIR` | показан частичный снимок, count=512 и признак `entries+` | [PASS](../artifacts/mame-p3/panels/bigdir-partial.png) |
|
||||
| `End` | выбран последний красный `>>> MORE...`, info показывает `<DSS LIMIT>` | [PASS](../artifacts/mame-p3/panels/dss-marker-selected.png) |
|
||||
| `Enter` на маркере | выведено сообщение о недоступном остатке DSS; переход или EXEC не выполнен | [PASS](../artifacts/mame-p3/panels/dss-marker-message.png) |
|
||||
| `F10` | открыт диалог выхода поверх текущего состояния | [PASS](../artifacts/mame-p3/panels/dss-limit-quit-dialog.png) |
|
||||
| `Enter` в диалоге | выполнен cleanup и возврат в `A:\>` | [PASS](../artifacts/mame-p3/panels/dss-limit-clean-exit.png) |
|
||||
|
||||
Скриншот фиксирует только состояние изображения в конкретный момент и не
|
||||
используется в одиночку для вывода о причине возможного дефекта. Подозрение
|
||||
на ошибку должно дополнительно подтверждаться соседними кадрами, ожидаемым
|
||||
состоянием сценария и, при необходимости, отдельной диагностической пробой.
|
||||
|
||||
## 6. Синтетическая граница EMM-store
|
||||
|
||||
Проба `tests/p3_store_probe/p3store.c` не вызывает DSS и поэтому достигает
|
||||
продуктового предела, который нельзя получить из реального каталога DSS
|
||||
1.71. Сборка выполнена с `--max-allocs 3000`.
|
||||
|
||||
```text
|
||||
entry=24 capacity=640 bytes=15360 reserve=1024
|
||||
write: count=640 first=1 middle=1 last=1
|
||||
guard: put640=1 get640=1 tail=1
|
||||
cleanup: free_after=222 restored=1
|
||||
PASS: store boundary is intact.
|
||||
```
|
||||
|
||||
Проверены записи 0, 319 и 639. Запись и чтение индекса 640 отклонены,
|
||||
байты в начале и конце 1024-байтового резерва не изменились, EMM-страница
|
||||
освобождена без утечки.
|
||||
|
||||
Артефакт:
|
||||
[граница 640/641](../artifacts/mame-p3/panels/store-boundary-640-641.png).
|
||||
|
||||
## 7. Итог и следующая граница
|
||||
|
||||
Функциональный gate файловых панелей P3 закрыт в MAME. Аппаратный прогон на
|
||||
реальном Sprinter ещё нужен, но не блокирует начало P4.
|
||||
|
||||
Следующая работа PoC:
|
||||
|
||||
1. копирование одного файла через отдельную EMM-страницу в W3;
|
||||
2. безопасный временный файл, обработка ошибок и cleanup;
|
||||
3. запуск `.EXE` через ESTEX с восстановлением экрана после child;
|
||||
4. регрессионный MAME-сценарий для копирования, файлов больше 64 КБ и EXEC.
|
||||
Reference in New Issue
Block a user