# 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.1–1.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`.