Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места. Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
4.7 KiB
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 и цепочка кластеров:
PASS: F5 preserved exact FAT date/time and R/H/S/A attributes.
На экране обе панели показывают одинаковые размер, RHSA и
2001-02-03 04:05; секунды и payload подтверждает raw-проверка.
Контрольные кадры:
- исходные метаданные;
- файл скопирован с теми же полями;
- пассивная панель после переключения;
- чистый возврат в DSS.
После P18 повторно пройдены:
- P5 copy-fault matrix:
ALL PASS, CHD-checkPASS; - 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 за счёт пустого третьего банка:
_CODE 9503; DATA 3531; heap 1814
BANK1 11011/16384; BANK2 16145/16384
SPRCMD.EXE 43080
В BANK2 остаётся 239 байт. Следующий заметный UI/policy-модуль следует размещать с осмысленной перекладкой в BANK3. Межбанковый аудит чист.
Воспроизведение
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