Files
Sprinter-SDCC/applications/Volkov/docs/dss-large-directories.md
T
snark13 8e389c03f8 Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
2026-09-10 10:45:30 +03:00

6.5 KiB
Raw Blame History

DSS: большие каталоги и F_FIRST/F_NEXT

Вывод

Стабильный DSS 1.71 не может перечислить каталог за пределами первых 512 физических FAT-записей. Это ограничение внутреннего 16-КБ кэша DSS, а не размера ffblk_t, адреса DTA, W2, W3 или EMM-хранилища Commander.

Commander хранит до 640 элементов в EMM, но на стабильном DSS источник может закончиться раньше. Код ошибки 35 принимается как частичный успех: полученные элементы сохраняются, а последней добавляется красная виртуальная строка >>> MORE....

Подтверждение исходниками DSS

Исходники находятся в ../../docs/sources/Estex-DSS и закодированы в CP866. Для чтения комментариев они просматривались через iconv, без изменения оригинальных файлов.

Стабильная ветка master, релизный срез 6078563:

  • DSS/defines.inc: DIRPAGE.buffer = 0xC000;
  • DSS/FS/FAT.asm:LOADDIR: за один раз читается ровно 0x4000 байт;
  • размер FAT_DIRECTORY_RECORD равен 32 байтам;
  • SEARCH.Custom начинает с IX=0xC000 и прибавляет 32;
  • после 512 записей IX переходит через 0xFFFF, а SEARCH.error_too_many_files возвращает DSS_Error.sys.TOO_MANY_FILES_IN_DIR;
  • DSS/API/Find.asm:F_NEXT отдельно проверяет IX==0 и направляет выполнение на ту же ошибку;
  • комментарии TODO прямо требуют record index и загрузку другой части каталога размером более 0x4000 байт.

В системном SYSTEM.DOS, реально используемом MAME, найдены обе характерные последовательности стабильной реализации: проверка LD IX,0 и цикл ADD IX,32 до переноса. Бинарник на HDD и dss171u.img совпадают по SHA-256.

Почему старый тест показывал 682

Один ранний экран P3DIR показывал count=682, errno=0, но поле last содержало B0000599.DAT. Проверка физического порядка тестового FAT-образа показала:

  • записи 0 и 1 — . и ..;
  • B0000599.DAT — запись 511, то есть 512-я физическая запись;
  • запись 512 уже имеет другое имя.

Следовательно, DSS завершил реальный перебор точно на системной границе, а старый диагностический .EXE исказил локальный счётчик и errno. Этот экран не является доказательством чтения 682 записей. Исправленная проба хранит счётчик и контрольные имена 511/512/513 в статической памяти.

Матрица tests/p3_enum_matrix независимо получила для всех проверенных вариантов count=512, end_errno=35: обычный wrapper, wrapper и цикл в W1, чтение W3 и запись в EMM.

Семантика Commander 0.11.0

При fnext() == -1 && errno == 35:

  1. Ошибка не откатывает уже прочитанный каталог.
  2. panel.truncated устанавливается в 1.
  3. В конец добавляется ScDirEntry с флагом SC_ENTRY_DSS_LIMIT и именем >>> MORE....
  4. Маркер всегда сортируется после файлов, рисуется красным и занимает один из 640 слотов панели.
  5. Enter и файловые команды не трактуют маркер как файл или каталог.

Число видимых файлов может быть меньше 510: в 512 физических записей входят ./.., удалённые записи и служебные записи длинных имён, которые DSS или Commander отфильтровывают.

Расширенная ветка DSS

В origin/beta_cdfs существует незавершённая реализация больших каталогов:

  • B=0x80 — короткое имя и обход без старого предела;
  • B=0x81 — DOS-имя и обход без старого предела;
  • хранится record index;
  • при окончании страницы вызывается LOAD_NEXT_DIR_PART_TO_DIR_CACHE;
  • старые режимы B=0/1 намеренно ограничиваются 512 результатами для совместимости.

Это хороший upstream-прототип для версии 2.0, но не контракт стабильного DSS 1.71. До отдельной сборки и тестирования Commander не должен зависеть от него.

Следствие для логических страниц Commander

Предложенные <<< PAGE n/>>> PAGE n реализуемы без дополнительной памяти, если DSS способен продолжить физический перебор после первой 16-КБ части. На стабильном DSS повторный F_FIRST/F_NEXT снова остановится на тех же 512 записях, поэтому настоящее переключение на PAGE2 требует одного из вариантов:

  1. стабилизировать расширенный режим B=0x80/0x81;
  2. добавить эквивалентный API DSS с record index/offset;
  3. как нежелательный запасной путь — реализовать raw FAT source вне DSS.

Выбор делается после релиза 1.0; текущий красный маркер уже имеет отдельный тип и сможет позднее стать переходом без изменения формата ScDirEntry.