Files
Sprinter-SDCC/applications/Volkov/docs/p1-platform-probes.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

18 KiB
Raw Blame History

Sprinter Commander: платформенные пробы P1

Статус: MAME 0.287 / BIOS 3.06 — PASS; проверка на реальном Sprinter ожидается

Связанные документы: требования, архитектура, клавиши, roadmap, экранный backend P2

1. Назначение

Программа p1probe.exe объединяет платформенные проверки, которые должны быть завершены до реализации UI Commander. Она не является ранней версией Commander и не определяет его пользовательский интерфейс.

Исходники находятся в tests/p1_platform/.

Вторая программа, p1child.exe, используется только для проверки ESTEX EXEC, возврата к родителю и кода завершения.

2. Ограничения безопасности

  • Пробы не создают, не изменяют и не удаляют файлы.
  • Каталожная проба выполняет только getcwd, chdir(".") и ffirst/fnext.
  • EMM-проба пишет только в выделенный ей блок из трёх страниц.
  • Screen-проба пишет только в отдельную выделенную EMM-страницу.
  • Дочерняя программа меняет видеорежим, но не пишет на диск.
  • Проба не открывает файловые дескрипторы приложения напрямую.
  • MAME не запускается целями make и make all.

Первый MAME-прогон выполнен 6 сентября 2026 года после отдельного согласования. Все запуски использовали автоматически пересоздаваемый mc.img; исходные дисковые образы не изменялись программами-пробами.

3. Состав

Файл Назначение
p1probe.c меню, общие сообщения, последовательность тестов
p1_sys.c app-local wrappers DSKINFO, EXEC, WAIT, WINREST
p1_emm.c выделение трёх страниц и проверка границ
p1_dir.c CURDIR/CHDIR/F_FIRST/F_NEXT и DSKINFO output
p1_screen.c полный и частичный WINREST с ненулевым offset
p1_keyboard.c вывод ascii/scan/live modifiers
p1_exec_test.c два режима EXEC и проверка состояния родителя
p1child.c дочерний EXE, меняющий режим на 40x32 и возвращающий 0x5A
mame_dump_keys.lua вывод карты полей AT-клавиатуры MAME
mame_p1_keyboard.lua воспроизводимый ввод стрелок, F1–F10 и сочетаний
Makefile сборка обоих EXE

4. Сборка

cd applications/Volkov/tests/p1_platform
make

Диагностическая программа собирается в режиме small --safe. Это сделано намеренно: P1 проверяет платформенные ABI и не должен одновременно отлаживать банковую topology Commander. Сборка big --safe является критерием P2.

Дочерняя программа собирается как tiny --safe.

Результат текущей сборки

p1probe.exe:

  • _CODE: 11 062 байта;
  • данные: 2 741 байт;
  • файл EXE: 11 835 байт;
  • heap после статики: 17 429 байт;
  • стек: 1 279 байт.

p1child.exe:

  • _CODE: 3 907 байт;
  • данные: 849 байт;
  • файл EXE: 4 453 байта;
  • heap после статики: 10 092 байта;
  • стек: 1 279 байт.

Компиляция выполнена без ошибок. Значения относятся к текущей диагностической сборке и не являются бюджетом Commander.

5. Статическая проверка ABI

5.1. DSKINFO

Сигнатура:

int p1_disk_info(uint8_t disk, P1DiskInfo *out);

Сгенерированный вызов передаёт disk в A, out в DE. Wrapper сохраняет IX, а после RST сохраняет:

  • A — sectors per cluster;
  • HL — total clusters;
  • DE — free clusters;
  • BC — bytes per sector.

Размер P1DiskInfo проверяется typedef-assert и равен семи байтам.

5.2. EXEC

Сигнатура намеренно имеет 8-битный аргумент первым:

int p1_exec(uint8_t path_mode, const char *path);

Для этого порядка SDCC передаёт path_mode в A и path в DE. Wrapper перекладывает их в B и HL соответственно. Вариант p1_exec(const char *path, uint8_t mode) был отвергнут после просмотра сгенерированного ASM: второй 8-битный аргумент SDCC помещал на стек, а не в DE.

На успехе A сохраняется как p1_exec_exit_code; на ошибке код из A проходит через __errno_set.

5.3. WINREST

Wrapper повторяет уже подтверждённую раскладку tests/winrest и mdview2:

A       row
L       column
SP+2    height
SP+3    width
SP+4    physical page
SP+5..6 offset in 16-KB page

IX сохраняется, перед RST устанавливается в 0xC000 + offset. Сгенерированный вызов проверен для полного экрана 32x80 и окна 2x20 с offset 0x2000.

6. Меню p1probe.exe

Клавиша Проба Автоматическая оценка
1 Каталог и F_FIRST/F_NEXT да, плюс наблюдаемые коды
2 EMM: три страницы да
3 WINREST full/partial только завершение; изображение оценивается визуально
4 Клавиатурные коды сбор наблюдений
5 EXEC и возврат да для режима B=1
6 DSKINFO текущего диска да
A Пробы 1, 2 и 6 да
0/Esc Выход

7. Ожидаемые проверки

7.1. Каталог

Проба дважды перечисляет каталог по маскам *.* и *, печатает первые 20 записей и итоговые значения:

  • число записей;
  • наличие .;
  • наличие ..;
  • errno последнего fnext();
  • совпадение результатов двух масок;
  • сохранение CWD после chdir(".").

Фактический результат DSS различается: *.* вернул обе записи с расширением, а * завершился как пустой список с ENOENT. Поэтому *.* принят как обязательный шаблон полного scan; совпадение масок не предполагается.

MAME-прогон установил фактическое завершение перечисления: fnext() возвращает ошибку с errno=3 (ENOENT). Код 0x0F из старого описания DSS для этой операции не подтверждён. Проба после измерения принимает только ENOENT, чтобы возможная смена поведения не осталась незамеченной.

7.2. EMM

Проверяются:

  • mem_alloc_pages(3);
  • три различных физических номера;
  • первые 64 байта каждой страницы;
  • последние 64 байта каждой страницы;
  • независимые patterns страниц;
  • восстановление mem_info.free_pages после освобождения блока.

7.3. Screen/WINREST

Первый вызов должен показать полный экран 80x32 с рамкой и цветными строками. После клавиши второй вызов должен наложить окно 20x2 в позиции row 14, column 30. Данные второго окна лежат по offset 0x2000, поэтому тест одновременно проверяет корректность IX.

Тест не открывает окно через BIOS: ESTEX WINREST здесь только копирует прямоугольник в текущий текстовый экран. Повтор со снимками в t=20 и t=24 без промежуточных вызовов подтвердил, что фон вне прямоугольника сохранён.

Первая версия pattern использовала арифметически полученные атрибуты 0x11..0x17. Верхняя граница 0x11 была обычным blue-on-blue, а часть остальных сочетаний выглядела неоднозначно в разных моментах палитрового цикла. Замечание о синих символах на синем фоне подтвердилось; raw-арифметика атрибутов в UI запрещается.

После замены на именованные COLOR(LIGHTBLUE..WHITE, BLUE) полный экран и частичное окно были видимы на кадрах t=20 и t=24. Повторная проверка исходных PNG установила, что их декодированные RGB-пиксели полностью идентичны. Прежнее сообщение о чередовании P2 было ошибкой встроенного предпросмотра, а не поведением MAME.

Отдельная проба P2.2 сохранила, установила, прочитала обратно и восстановила шесть атрибутов во всех четырёх планах; многоцветная сцена осталась стабильной. Строка P1-SCR-03 ниже подтверждена как PASS. Детали — в результатах P2.2.

7.4. Keyboard

Для 24 событий печатаются:

ascii, scan, полное kbd_mod_state, compact Shift/Ctrl/Alt

Esc печатается последним и завершает сбор. В автоматическом MAME-сценарии использован следующий набор из 24 событий:

  • стрелки, Home/End, PgUp/PgDn;
  • F1F10;
  • Insert/Delete;
  • Ctrl+R;
  • Ctrl+PgUp;
  • Alt+F1;
  • Esc.

7.5. EXEC

Выполняются два случая:

  1. B=0, P1CHILD.EXE — наблюдение short-name/PATH semantics.
  2. B=1, .\\P1CHILD.EXE — обязательный случай PoC.

Дочерняя программа:

  • переключается в 40x32;
  • показывает свои W1/W2/W3 и CWD;
  • ждёт клавишу;
  • возвращает 0x5A.

После возврата родитель проверяет:

  • результат непосредственного EXEC;
  • результат WAIT;
  • восстановление W1/W2/W3;
  • восстановление CWD;
  • возможность вернуть 80x32 и продолжить работу.

Ошибка случая B=0 записывается как наблюдение и не проваливает PoC. Ошибка B=1 проваливает тест.

8. Выполненный порядок первого прогона

  1. 2 — EMM.
  2. 6 — DSKINFO.
  3. 1 — каталог.
  4. 3 — WINREST.
  5. 4 — клавиатура.
  6. 5 — EXEC последним.
  7. Повторно 2 в том же процессе после EXEC, чтобы проверить EMM.
  8. Возврат в меню; независимые запуски дополнительно подтвердили повторный старт программы.

Такой порядок сначала проверяет неразрушительные примитивы и оставляет наиболее сложное переключение контекста на конец.

9. Таблица runtime-результатов

Окружение MAME: mame.arm 0.287 (b0c4527c), машина sprinter, BIOS v3.06, запуск p1probe.exe с дискеты A:. PENDING в аппаратной колонке означает только отсутствие прогона на реальном Sprinter и не отменяет результата MAME.

ID Проверка MAME 0.287 / BIOS 3.06 Реальный Sprinter Артефакт
P1-DIR-01 CWD и chdir(".") PASS PENDING результат
P1-DIR-02 *.* против * PASS: 2 против 0; полный scan использует только *.* PENDING результат
P1-DIR-03 Код конца F_NEXT PASS, ENOENT=3 PENDING строгая проверка
P1-EMM-01 Блок 3 страницы PASS, страницы EF/F0/F1 PENDING результат
P1-EMM-02 Границы страниц PASS PENDING результат
P1-EMM-03 Счётчик после free PASS, 221 → 221 PENDING результат
P1-SCR-01 Полный WINREST 80x32 PASS, визуально PENDING контрастный экран
P1-SCR-02 Offset WINREST PASS, row 14 / col 30 / 0x2000 PENDING фон и окно вместе
P1-SCR-03 Цветные атрибуты в двух моментах цикла PASS, RGB кадров идентичен; P2.2 подтвердил 6 атрибутов × 4 плана PENDING кадр 1, кадр 2, P2.2
P1-SCR-04 Raw-атрибуты 0x11..0x17 OBSERVED, raw-арифметика запрещена PENDING неудачный исходный pattern
P1-KBD-01 Базовые scan-коды PASS PENDING таблица
P1-KBD-02 Ctrl/Alt modifiers PASS PENDING сочетания
P1-EXE-01 EXEC B=0 PASS PENDING результат
P1-EXE-02 EXEC B=1 PASS PENDING результат
P1-EXE-03 Exit/WAIT 0x5A PASS / PASS PENDING результат
P1-EXE-04 Восстановление W1/W2/W3 PASS, F3/F2/FF PENDING результат
P1-EXE-05 EMM после двух EXEC PASS PENDING контроль
P1-DSK-01 DSKINFO PASS PENDING результат

9.1. Зафиксированные значения

  • DSKINFO: 1 сектор на кластер, 512 байт на сектор, 2847 кластеров всего, 2814 свободно.
  • EMM до выделения: 256 страниц всего, 221 свободна; после освобождения снова 221.
  • Оба режима EXEC: rc=0, errno=0, непосредственный exit=5A, WAIT=5A.
  • CWD до и после child: \; страницы W1/W2/W3 до и после: F3/F2/FF.
  • Модифицированная клавиша приходит с установленным битом 7 scan-кода: Ctrl+R=93, Ctrl+PgUp=D9, Alt+F1=BB. После scan & 0x7F получаются базовые коды 13, 59, 3B; compact modifiers равны 02, 02, 04.
  • Esc: ascii=1B, scan=01.

10. Условия завершения P1

MAME-часть P1 завершена: все обязательные строки имеют PASS, фактические клавиатурные коды перенесены в keymap, завершение fnext() уточнено, EXEC B=1/WAIT и EMM после child подтверждены, артефакты сохранены.

Проверка на реальном Sprinter остаётся желательной аппаратной валидацией, но не блокирует переход к P2 и реализацию platform API PoC. Если реальное железо даст расхождение, оно оформляется отдельным репро и не маскируется адаптацией UI.