Volkov: добавить Sprinter Commander

Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
This commit is contained in:
2026-09-10 10:45:30 +03:00
parent 05bcd8197e
commit 8e389c03f8
870 changed files with 21310 additions and 25 deletions
@@ -0,0 +1,73 @@
# Sprinter Commander: выбор записей 0.2/P7
Дата: 8 сентября 2026 года.
Статус: `PASS` в MAME 0.288 / BIOS 3.06 / DSS 1.71.57 на HDD `D:`.
## Контракт
- `Insert` меняет выбор текущей обычной записи и передвигает cursor вниз;
- `*` инвертирует выбор только файлов текущей панели;
- файлы и каталоги можно выбирать, синтетический `..` и виртуальный маркер
DSS нельзя;
- групповые `+`, `-` и `*` игнорируют каталоги и не снимают выбор,
ранее поставленный с каталога через `Insert`;
- выбранная запись отмечается `*` слева от имени;
- footer активной панели показывает `<bytes> bytes in <count> selected`, а
общая строка информации пока сохраняет компактное `sel размер/количество`;
- размер каталога в этой статистике равен нулю: рекурсивный подсчёт появится
вместе с групповой job;
- сортировка переносит `SC_ENTRY_SELECTED` вместе с записью и сохраняет
текущий файл под cursor;
- refresh текущего среза явно очищает выбор; режим сортировки сохраняется;
- панели имеют независимые EMM-страницы и независимую статистику.
Функции выбора находятся в BANK1 и работают только через
`sc_store_get/put`; указатель на W3 не сохраняется. Для toggle и invert
используется один банковый entry point, чтобы не плодить resident thunk’и.
## Проверка
Target-проба `SELRT.EXE` проверяет Insert двух файлов, точную сумму 30,
отказы для `..`/DSS-маркера, две инверсии, выбор каталога, сброс статистики
через `sc_store_clear()` и возврат EMM. Результат извлекается из CHD:
```text
PASS: Insert/invert/masks, virtual guards, totals, refresh и EMM.
```
UI-сценарий выбирает два каталога и `A.BIN`, меняет порядок на `N-`,
инвертирует выбор и перечитывает каталог. Контрольные состояния:
- [виртуальная запись не выбирается](../artifacts/mame-p7/select/virtual-entry-guard.png);
- [три записи, `sel 10/003`](../artifacts/mame-p7/select/insert-three.png);
- [сортировка сохранила flags и cursor](../artifacts/mame-p7/select/sort-keeps-selection.png);
- [инверсия файлов не изменила ранее выбранные каталоги, `sel 50/004`](../artifacts/mame-p7/select/inverted.png);
- [refresh очистил выбор и сохранил `N-`](../artifacts/mame-p7/select/refresh-clears.png);
- [штатный возврат в DSS](../artifacts/mame-p7/select/clean-dss-return.png).
## Размер
Конфигурация `--memory big --safe --max-allocs 3000`:
| Область | После P6 | После P7 | Изменение |
|---|---:|---:|---:|
| `_CODE` W2 | 9125 | 9434 | +309 |
| данные W2 | 3244 | 3256 | +12 |
| свободная куча W2 | 2479 | 2158 | -321 |
| BANK1 | 5137 | 6033 | +896 |
| BANK2 | 6053 | 6213 | +160 |
| `SPRCMD.EXE` | 42702 | 43011 | +309 |
Первый вариант имел два банковых entry point и оставлял 2069 байт heap.
После объединения и сокращения резидентных сообщений финальная сборка
возвращает 2158 байт. Межбанковый аудит чистый.
## Воспроизведение
```sh
make hdd-p7-select ALLOCS=3000
tests/run_mame_hdd.sh build/hdd/p7_select.chd \
tests/mame_p7_select.lua artifacts/mame-p7/local 65
tests/check_p7_select_hdd.sh build/hdd/p7_select.chd
```