8e389c03f8
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
90 lines
4.7 KiB
Markdown
90 lines
4.7 KiB
Markdown
# Sprinter Commander: сохранение метаданных F5 0.2/P18
|
||
|
||
Дата: 10 сентября 2026 года.
|
||
|
||
Статус: `PASS` в MAME 0.288 / BIOS 3.06 / DSS 1.71.57 на HDD `D:`.
|
||
|
||
## Контракт
|
||
|
||
Одиночный, групповой и рекурсивный F5 сохраняют у каждого обычного файла:
|
||
|
||
- FAT date/time, включая двухсекундную точность;
|
||
- атрибуты readonly, hidden, system и archive.
|
||
|
||
Date/time задаются вызовом DSS `PUT_D_T` на открытом temp-файле после
|
||
последней записи и до `close()`. Атрибуты задаются через `ATTRIB` только
|
||
после атомарного rename temp в конечное имя. Такой порядок не делает temp
|
||
readonly до commit и сохраняет прежнюю защиту существующего target.
|
||
|
||
Если ошибка происходит до rename, общий cleanup закрывает дескрипторы и
|
||
удаляет temp. Если `ATTRIB` или восстановление CWD завершаются ошибкой уже
|
||
после rename, `ScCopyJob.committed` не позволяет выдавать результат за
|
||
отсутствующий файл: UI сообщает `File committed; finalization failed`.
|
||
|
||
Метаданные каталогов на этом этапе не переносятся.
|
||
|
||
## Проверка
|
||
|
||
Fixture создаёт `MSRC/META.BIN` размером 4097 байт с контролируемым payload,
|
||
датой `2001-02-03`, временем `04:05:06` и набором атрибутов `R/H/S/A`.
|
||
Подготовленный raw FAT проверяется до MAME, чтобы текущая дата сборки не могла
|
||
дать ложный положительный результат.
|
||
|
||
После F5 извлекается конечный CHD и собственным FAT16-reader проверяются обе
|
||
32-байтовые directory entries и цепочка кластеров:
|
||
|
||
```text
|
||
PASS: F5 preserved exact FAT date/time and R/H/S/A attributes.
|
||
```
|
||
|
||
На экране обе панели показывают одинаковые размер, `RHSA` и
|
||
`2001-02-03 04:05`; секунды и payload подтверждает raw-проверка.
|
||
|
||
Контрольные кадры:
|
||
|
||
- [исходные метаданные](../artifacts/mame-p18/metadata/source-metadata.png);
|
||
- [файл скопирован с теми же полями](../artifacts/mame-p18/metadata/copied-metadata.png);
|
||
- [пассивная панель после переключения](../artifacts/mame-p18/metadata/passive-metadata.png);
|
||
- [чистый возврат в DSS](../artifacts/mame-p18/metadata/clean-dss-return.png).
|
||
|
||
После P18 повторно пройдены:
|
||
|
||
- P5 copy-fault matrix: `ALL PASS`, CHD-check `PASS`;
|
||
- P16 recursive group F5: UI корректен, все выбранные деревья и файлы
|
||
совпали побайтно.
|
||
|
||
## ABI DSS
|
||
|
||
`sc_metadata_set_datetime()` раскрывает packed FAT date/time в поля
|
||
`PUT_D_T $18`. Низкоуровневый leaf получает handle в `A`, near-указатель на
|
||
семибайтовую структуру в `DE`, загружает год в `IX` и сохраняет caller IX.
|
||
|
||
Для `ATTRIB $16` сгенерированный `.asm` подтвердил важную особенность
|
||
`__sdcccall(1)`: второй однобайтовый аргумент banked-wrapper лежит на стеке,
|
||
а `E` занят номером банка. Поэтому публичная banked-функция вызывает
|
||
локальный raw-leaf с обычным ABI; leaf снимает однобайтовый аргумент и адрес
|
||
возврата явно. Оба пути переводят `CF/A` в `errno`.
|
||
|
||
## Компоновка
|
||
|
||
Сборка `--memory big --safe --max-allocs 3000` остаётся двухбанковой и не
|
||
увеличивает EXE за счёт пустого третьего банка:
|
||
|
||
```text
|
||
_CODE 9503; DATA 3531; heap 1814
|
||
BANK1 11011/16384; BANK2 16145/16384
|
||
SPRCMD.EXE 43080
|
||
```
|
||
|
||
В BANK2 остаётся 239 байт. Следующий заметный UI/policy-модуль следует
|
||
размещать с осмысленной перекладкой в BANK3. Межбанковый аудит чист.
|
||
|
||
## Воспроизведение
|
||
|
||
```sh
|
||
make hdd-p18-metadata ALLOCS=3000
|
||
tests/run_mame_hdd.sh build/hdd/p18_metadata.chd \
|
||
tests/mame_p18_metadata.lua artifacts/mame-p18/local 48
|
||
tests/check_p18_metadata_hdd.sh build/hdd/p18_metadata.chd
|
||
```
|