Compare commits

...

5 Commits

Author SHA1 Message Date
snark13 5323b168a7 docs: описать разделение тулкита, MAME и приложений 2026-09-15 17:59:13 +03:00
snark13 e4695b8281 Sprinter: добавить отладку C-исходников и интеграцию VS Code 2026-09-15 17:58:41 +03:00
snark13 50c6e56b7b Volkov: адаптировать тайминги MAME 0.287 и таймаут на macOS 2026-09-15 17:57:20 +03:00
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
snark13 05bcd8197e check_bank_calls: ловить адрес ПОЛЯ структуры в аргументах банкового вызова
Проверка 2 искала форму «адрес метки своего банка положен в аргументы вызова в
чужой банк», но регулярка принимала только `ld hl,#_метка` и `#_метка+6`. Адрес
поля структуры SDCC пишет в скобках:

	ld	bc, #(_mstream + 6)
	push	bc
	...
	call	___sdcc_bcall_ehl

Из-за этого целый класс ошибок собирался «чисто». Поймано вживую 2026-09-03 в
порту Loom: mask.c (банк 5, --bank-data 5) отдавал res_copy (банк 11) адрес поля
своей структуры — поток маски читался в чужую страницу, маска выходила «всё
заполнено», тайлов в комнате стало 30 вместо 17. Фон при этом оставался
побайтово верным, потому что его путь идёт из резидентного кода, так что
попиксельная сверка экрана молчала.

Класс проверки не меняется: адрес метки ДАННЫХ своего банка, положенный в стек
как аргумент вызова в ЧУЖОЙ банк, неверен всегда — это по-прежнему
доказательный случай, а не эвристика.

Проверено в трёх режимах: с ошибкой срабатывает, на исправленном коде молчит, и
на всех банковых сборках самого тулчейна (banktest, w3probe, banked, bankedbg,
banklocl, w3bankgfx, roomtest, сборка SprPoP) ложных срабатываний нет.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qxu9rwsmyDyYPxG198nzSR
2026-09-03 11:04:27 +03:00
933 changed files with 28746 additions and 54 deletions
+27
View File
@@ -0,0 +1,27 @@
# Настройки Codex
`config.toml` и запускной скрипт `toolchain/run-mame-mcp.sh` хранятся в Git.
Запускайте Codex из корня репозитория или любой вложенной папки.
Корень определяется через `git rev-parse --show-toplevel`.
На каждом компьютере установите `uv` и добавьте его в PATH процесса Codex.
По умолчанию сервер расположен в `mame/sources/MAME/src/mame_mcp.py`.
Каталог `mame/` не хранится в Git и должен быть установлен отдельно.
Первый запуск uv может потребовать сеть для установки Python 3.12 и mcp<2.
Если расположение отличается, создайте `.codex/mame.local.env` (игнорируется Git):
```sh
MAME_UV="/opt/homebrew/bin/uv"
MAME_MCP_SCRIPT="mame/sources/MAME/src/mame_mcp.py"
```
Путь к серверу может быть абсолютным или относительно корня проекта.
Путь к uv может быть абсолютным, относительным к корню или именем из PATH.
Переменные можно также передать через окружение Codex; локальный файл имеет
приоритет. Файл читается как shell-код запускным скриптом, а не самим Codex.
Не храните в нём секреты и не добавляйте его в Git.
После изменения настроек перезапустите подключение MCP или Codex.
Инициализация MCP не требует запущенного эмулятора; для команд отладки нужен
MAME с `mame_bridge.lua` (см. `docs/mame-autotest.md`).
+7 -8
View File
@@ -1,14 +1,10 @@
[mcp_servers.mame-z80]
command = "/Users/alex/.local/bin/uv"
command = "sh"
args = [
"run",
"--python",
"3.12",
"--no-project",
"--with",
"mcp<2",
"/Volumes/SAM8/Projects/DIY/Z80/Sprinter/C-Compiler/mame/sources/MAME/src/mame_mcp.py",
"-c",
'root=$(git rev-parse --show-toplevel) || exit; exec sh "$root/toolchain/run-mame-mcp.sh"',
]
startup_timeout_sec = 60
[mcp_servers.mame-z80.tools.clear_breakpoint]
approval_mode = "approve"
@@ -27,3 +23,6 @@ approval_mode = "approve"
[mcp_servers.mame-z80.tools.pause]
approval_mode = "approve"
[mcp_servers.mame-z80.tools.status]
approval_mode = "approve"
+7
View File
@@ -78,6 +78,10 @@ toolchain/mkexe/tests/*.actual
*.obj
*.dSYM/
# Python host-tools: bytecode всегда воспроизводим и не входит в исходники.
__pycache__/
*.py[cod]
# ===========================================================================
# Vendored / downloaded
# ===========================================================================
@@ -138,3 +142,6 @@ applications/PoP/R1/
# здесь его содержимое НЕ дублируется (иначе разъедется). Коротко: в
# репозиторий не идут assets/orig/ (чужие данные — их выкачивает
# `make fetch`) и assets/packed/LEVELS/ (уровни из оригинала как есть).
# Локальные пути MCP; общая конфигурация .codex остаётся в Git.
/.codex/mame.local.env
+1
View File
@@ -0,0 +1 @@
3.12
+10
View File
@@ -56,6 +56,16 @@ make size-baseline # принять текущие размеры эталон
- Справочник API — docs/libc-reference.md (обновлять при добавлении
функций).
## Документация source debugger
При изменении `<sdbg.h>`, извлечения/форматирования logMessage,
поддержанных типов/регистров, чтения указателей или маршрутов MAME/DAP
одновременно обновлять `docs/sdbg-log-macros.md` и проверяемые примеры;
ссылки и краткий статус синхронизировать с `docs/mame-source-debug.md`,
`docs/vscode-sprinter-debug.md`, `docs/mame-source-debug-status.md` и
`docs/libc-reference.md`. Финальные задачи по hex и разыменованию
указателей пока только в плане, не считать их рабочим API.
## ABI и платформа (кратко; детали в memory/)
- SDCC `__sdcccall(1)`: arg1 → HL (8-бит → A), arg2 → DE, остальные
+16 -1
View File
@@ -43,7 +43,7 @@ DATA_FILES := \
examples/mdview/SAMPLE.MD
.PHONY: all tools lib tests examples check clean sdcc floppy \
size-check size-baseline host-tests $(TESTS) $(APPS)
size-check size-baseline host-tests sdbg-tests mame-sdbg-patch mame-sdbg $(TESTS) $(APPS)
all: tools lib tests
@@ -87,6 +87,21 @@ HOST_TEST_DIRS := testkit applications/SprPoP/tests/host
host-tests:
@for d in $(HOST_TEST_DIRS); do $(MAKE) -C $$d || exit 1; done
# Отладочная карта: реальные SDCC/linker и протокол транспорта без MAME.
# Для local pyenv: pyenv exec make sdbg-tests.
sdbg-tests: tools lib
python3 -m unittest discover -s tests/sdbg -v
# Backend удерживает MAME в stopped-loop без Cocoa debugger; Lua bridge при
# этом обслуживается из periodic_check ядра. Повторный вызов безопасен.
mame-sdbg-patch:
sh toolchain/apply-mame-sdbg-patch.sh
# Инкрементально собирает patched checkout и устанавливает бинарник в v306.
mame-sdbg: mame-sdbg-patch
$(MAKE) -C mame/sources/MAME
cp mame/sources/MAME/mame $(MAME_DIR)/mame.arm
# Размерный регресс: сверить _CODE всех программ с docs/size_baseline.tsv.
size-check:
python3 toolchain/size_check.py
+27 -6
View File
@@ -12,6 +12,8 @@
# # STACK_SIZE := 2048 # bytes reserved for the stack
# # EXTRA_SRCS := helper.c util.c # additional .c files in this dir
# # EXTRA_FLAGS := --crt0=minimal # passed through to sprinter-cc
# # SRC_DEBUG := 1 # карта C/asm и проверенный debug-пакет
# # SRC_DEBUG_FILES := helper.c # либо карта только выбранных TU
# # EXTRA_DATA := test.txt # extra files to add to `make floppy`
# # HDD_DEST_DIR := games/myapp # общий каталог файлов в `make hdd`
#
@@ -31,6 +33,7 @@
# (in the repo root) still packs all examples.
# run floppy + launch MAME
PYTHON ?= python3
SPRINTER_CC := $(PROJ_ROOT)/bin/sprinter-cc
MKEXE := $(PROJ_ROOT)/toolchain/mkexe/mkexe
LIB := $(PROJ_ROOT)/lib/sprinter.lib
@@ -77,6 +80,12 @@ ifneq ($(STACK_SIZE),)
CC_FLAGS += --stack-size $(STACK_SIZE)
endif
CC_FLAGS += $(EXTRA_FLAGS)
ifeq ($(SRC_DEBUG),1)
CC_FLAGS += --src-debug
endif
ifneq ($(strip $(SRC_DEBUG_FILES)),)
CC_FLAGS += $(foreach src,$(SRC_DEBUG_FILES),--src-debug-file $(src))
endif
all: $(EXE)
@@ -99,12 +108,24 @@ BANK_CHECK := $(PROJ_ROOT)/toolchain/check_bank_calls.py
# предупреждение: страницы в W0 кладут не все. Разбор — в шапке скрипта.
W0ISR_CHECK := $(PROJ_ROOT)/toolchain/check_w0_isr.py
$(EXE): $(SOURCES) $(MKEXE) $(LIB) $(RUNTIME_DEPS)
$(if $(strip $(BUILD_DIR)),@mkdir -p $(dir $@))
$(SPRINTER_CC) $(CC_FLAGS) -o $@ $(SOURCES)
@d=$(dir $@).sprinter-cc-$(EXAMPLE); \
if ls $$d/bank*_*.asm >/dev/null 2>&1; then python3 $(BANK_CHECK) $$d; fi; \
if ls $$d/*.map >/dev/null 2>&1; then python3 $(W0ISR_CHECK) $$d; fi
# Команда/зависимости карты участвуют в пересборке, включая смену режима.
SDBG_CONFIG := $(dir $(EXE)).resource-stamps/$(EXAMPLE)-config.json
SDBG_MANIFEST := $(dir $(EXE)).sprinter-cc-$(EXAMPLE)/manifest.json
.PHONY: sdbg-config-force
SDBG_CONFIG_ARGS = $(SDBG_CONFIG) $(SPRINTER_CC) $(CC_FLAGS) $(SOURCES) $(SDBG_MANIFEST)
# Проверка содержимого обязательна: mtime make может иметь точность в секунду.
# Сохранение fingerprint только после успешной сборки позволяет повторить сбой.
$(EXE): $(SOURCES) $(MKEXE) $(LIB) $(RUNTIME_DEPS) sdbg-config-force $(SPRINTER_CC) $(wildcard $(PROJ_ROOT)/toolchain/sdbg/*.py) $(wildcard $(PROJ_ROOT)/toolchain/sdbg_*.py)
@state=$$($(PYTHON) $(PROJ_ROOT)/toolchain/sdbg_config.py check $(SDBG_CONFIG_ARGS)) || exit $$?; \
if [ "$$state" = changed ] || [ -n "$(filter-out sdbg-config-force,$?)" ]; then \
mkdir -p $(dir $@); \
SPRINTER_PYTHON="$(PYTHON)" $(SPRINTER_CC) $(CC_FLAGS) -o $@ $(SOURCES) || exit $$?; \
d=$(dir $@).sprinter-cc-$(EXAMPLE); \
if ls $$d/bank*_*.asm >/dev/null 2>&1; then $(PYTHON) $(BANK_CHECK) $$d || exit $$?; fi; \
if ls $$d/*.map >/dev/null 2>&1; then $(PYTHON) $(W0ISR_CHECK) $$d || exit $$?; fi; \
$(PYTHON) $(PROJ_ROOT)/toolchain/sdbg_config.py save $(SDBG_CONFIG_ARGS); \
fi
$(MKEXE):
$(MAKE) -C $(PROJ_ROOT)/toolchain/mkexe
+8
View File
@@ -0,0 +1,8 @@
# Локальные исполняемые файлы платформенных проб собираются рядом с
# исходниками. Общий шаблон репозитория не покрывает этот дополнительный
# уровень вложенности applications/Volkov/tests/<probe>/.
/tests/*/*.exe
# Клон исторических исходников VC служит локальным справочным материалом и
# сохраняет собственный .git; во внешний репозиторий его как gitlink не кладём.
/VolkovCommander/
+222
View File
@@ -0,0 +1,222 @@
# Sprinter Commander — двухпанельный файловый менеджер.
PROJ_ROOT := $(abspath $(CURDIR)/../..)
EXAMPLE := sprcmd
SRC_DIR := src
BUILD_DIR := build
MEMORY := big
ALLOCS ?= 3000
HDD_IMG := $(CURDIR)/build/hdd/sprcmd.chd
MDVIEW2_DIR := $(PROJ_ROOT)/examples/mdview2
MDVIEW2_SRCS := $(wildcard $(MDVIEW2_DIR)/*.c)
MDVIEW2_HEADERS := $(wildcard $(MDVIEW2_DIR)/*.h)
MDVIEW2_TEST_EXE := $(CURDIR)/build/external/mdview2.exe
P5_COPY_FAULT_EXE := $(CURDIR)/build/tests/cperr.exe
P6_SORT_TEST_EXE := $(CURDIR)/build/tests/sortrt.exe
P7_SELECT_TEST_EXE := $(CURDIR)/build/tests/selrt.exe
P9_MKDIR_TEST_EXE := $(CURDIR)/build/tests/mkrt.exe
P10_RENAME_TEST_EXE := $(CURDIR)/build/tests/renrt.exe
P11_DELETE_TEST_EXE := $(CURDIR)/build/tests/delrt.exe
P19_OVERWRITE_TEST_EXE := $(CURDIR)/build/tests/p19/delrt.exe
BANK1_SRCS := src/sc_source_fs.c src/sc_sort.c src/sc_select.c \
src/sc_copy_job.c src/sc_metadata.c src/sc_disk.c src/sc_tree.c src/sc_exec_ui.c
BANK2_SRCS := src/sc_draw.c src/sc_dialog.c src/sc_copy_ui.c \
src/sc_file_ui.c src/sc_name.c src/sc_rename.c
EXTRA_FLAGS := --safe --max-allocs $(ALLOCS) -I include \
$(foreach f,$(BANK1_SRCS),--bank 1=$(f)) \
$(foreach f,$(BANK2_SRCS),--bank 2=$(f))
EXTRA_SRCS := \
src/sc_app.c \
src/sc_command.c \
src/sc_input.c \
src/sc_path.c \
src/sc_panel.c \
src/sc_platform_screen.c \
src/sc_platform_exec.c \
src/sc_screen.c \
src/sc_store.c \
src/sc_theme.c \
src/sc_video_system.c
include $(PROJ_ROOT)/app.mk
HEADERS := $(wildcard include/*.h)
$(EXE): Makefile $(HEADERS) $(BANK1_SRCS) $(BANK2_SRCS)
hdd-stress: $(EXE)
sh tests/make_p3_stress_hdd.sh $(CURDIR)/build/hdd/p3_stress.chd $(EXE)
hdd-copy: $(EXE)
sh tests/make_p4_copy_hdd.sh $(CURDIR)/build/hdd/p4_copy.chd $(EXE)
tests/p4_exec_child/p4child.exe: tests/p4_exec_child/p4child.c \
tests/p4_exec_child/Makefile
$(MAKE) -C tests/p4_exec_child ALLOCS=$(ALLOCS)
hdd-exec: $(EXE) tests/p4_exec_child/p4child.exe
sh tests/make_p4_exec_hdd.sh $(CURDIR)/build/hdd/p4_exec.chd \
$(EXE) tests/p4_exec_child/p4child.exe
hdd-p5: $(EXE)
sh tests/make_p5_hdd.sh $(CURDIR)/build/hdd/p5_stability.chd $(EXE)
hdd-p5-enospc: $(EXE)
sh tests/make_p5_enospc_hdd.sh \
$(CURDIR)/build/hdd/p5_enospc.chd $(EXE)
hdd-p5-panels: $(EXE)
sh tests/make_p5_panel_edges_hdd.sh \
$(CURDIR)/build/hdd/p5_panel_edges.chd $(EXE)
$(MDVIEW2_TEST_EXE): $(MDVIEW2_SRCS) $(MDVIEW2_HEADERS) $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory small --max-allocs $(ALLOCS) \
-o $@ $(MDVIEW2_SRCS)
hdd-p5-viewer: $(EXE) $(MDVIEW2_TEST_EXE)
sh tests/make_p5_viewer_hdd.sh \
$(CURDIR)/build/hdd/p5_viewer.chd $(EXE) \
$(MDVIEW2_TEST_EXE) $(MDVIEW2_DIR)/README.md
$(P5_COPY_FAULT_EXE): tests/p5_copy_faults.c src/sc_copy_job.c \
src/sc_metadata.c src/sc_disk.c \
src/sc_path.c src/sc_platform_exec.c include/sc_copy.h \
include/sc_metadata.h include/sc_disk.h include/sc_path.h \
include/sc_exec.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_copy_job.c --bank 1=src/sc_metadata.c \
--bank 1=src/sc_disk.c -o $@ \
tests/p5_copy_faults.c src/sc_path.c src/sc_platform_exec.c
hdd-p5-copy-faults: $(P5_COPY_FAULT_EXE)
sh tests/make_p5_copy_faults_hdd.sh \
$(CURDIR)/build/hdd/p5_copy_faults.chd $(P5_COPY_FAULT_EXE)
hdd-p5-media: $(EXE)
sh tests/make_p5_media_hdd.sh \
$(CURDIR)/build/hdd/p5_media.chd $(EXE)
$(P6_SORT_TEST_EXE): tests/p6_sort_probe.c src/sc_sort.c src/sc_store.c \
include/sc_entry.h include/sc_panel.h include/sc_sort.h \
include/sc_store.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_sort.c -o $@ \
tests/p6_sort_probe.c src/sc_store.c
hdd-p6-sort: $(EXE) $(P6_SORT_TEST_EXE)
sh tests/make_p6_sort_hdd.sh $(CURDIR)/build/hdd/p6_sort.chd \
$(EXE) $(P6_SORT_TEST_EXE)
$(P7_SELECT_TEST_EXE): tests/p7_select_probe.c src/sc_select.c \
src/sc_store.c include/sc_entry.h include/sc_panel.h \
include/sc_select.h include/sc_store.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_select.c -o $@ \
tests/p7_select_probe.c src/sc_store.c
hdd-p7-select: $(EXE) $(P7_SELECT_TEST_EXE)
sh tests/make_p7_select_hdd.sh $(CURDIR)/build/hdd/p7_select.chd \
$(EXE) $(P7_SELECT_TEST_EXE)
hdd-p8-masks: hdd-p7-select
$(P9_MKDIR_TEST_EXE): tests/p9_mkdir_probe.c src/sc_name.c src/sc_path.c \
include/sc_path.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_name.c -o $@ \
tests/p9_mkdir_probe.c src/sc_path.c
hdd-p9-mkdir: $(EXE) $(P9_MKDIR_TEST_EXE)
sh tests/make_p9_mkdir_hdd.sh $(CURDIR)/build/hdd/p9_mkdir.chd \
$(EXE) $(P9_MKDIR_TEST_EXE)
$(P10_RENAME_TEST_EXE): tests/p10_rename_probe.c src/sc_rename.c \
include/sc_file_ops.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_rename.c -o $@ \
tests/p10_rename_probe.c
hdd-p10-rename: $(EXE) $(P10_RENAME_TEST_EXE)
sh tests/make_p10_rename_hdd.sh $(CURDIR)/build/hdd/p10_rename.chd \
$(EXE) $(P10_RENAME_TEST_EXE)
$(P11_DELETE_TEST_EXE): tests/p11_delete_probe.c $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-o $@ tests/p11_delete_probe.c
hdd-p11-delete: $(EXE) $(P11_DELETE_TEST_EXE)
sh tests/make_p11_delete_hdd.sh $(CURDIR)/build/hdd/p11_delete.chd \
$(EXE) $(P11_DELETE_TEST_EXE)
hdd-p12-group-copy: $(EXE)
sh tests/make_p12_group_copy_hdd.sh \
$(CURDIR)/build/hdd/p12_group_copy.chd $(EXE)
hdd-p13-group-delete: $(EXE)
sh tests/make_p13_group_delete_hdd.sh \
$(CURDIR)/build/hdd/p13_group_delete.chd $(EXE)
hdd-p14-default-colors: $(EXE)
sh tests/make_p14_default_colors_hdd.sh \
$(CURDIR)/build/hdd/p14_default_colors.chd $(EXE)
hdd-p15-tree-copy: $(EXE)
sh tests/make_p15_tree_copy_hdd.sh \
$(CURDIR)/build/hdd/p15_tree_copy.chd $(EXE)
hdd-p15-tree-cancel: $(EXE)
sh tests/make_p15_tree_cancel_hdd.sh \
$(CURDIR)/build/hdd/p15_tree_cancel.chd $(EXE)
hdd-p15-tree-self: $(EXE)
sh tests/make_p15_tree_self_hdd.sh \
$(CURDIR)/build/hdd/p15_tree_self.chd $(EXE)
hdd-p16-group-tree-copy: $(EXE)
sh tests/make_p16_group_tree_copy_hdd.sh \
$(CURDIR)/build/hdd/p16_group_tree_copy.chd $(EXE)
hdd-p17-tree-delete: $(EXE)
sh tests/make_p17_tree_delete_hdd.sh \
$(CURDIR)/build/hdd/p17_tree_delete.chd $(EXE)
hdd-p17-tree-delete-cancel: $(EXE)
sh tests/make_p17_tree_delete_cancel_hdd.sh \
$(CURDIR)/build/hdd/p17_tree_delete_cancel.chd $(EXE)
hdd-p18-metadata: $(EXE)
sh tests/make_p18_metadata_hdd.sh \
$(CURDIR)/build/hdd/p18_metadata.chd $(EXE)
$(P19_OVERWRITE_TEST_EXE): tests/p19_overwrite_probe.c \
src/sc_copy_job.c src/sc_metadata.c src/sc_disk.c src/sc_path.c \
include/sc_copy.h include/sc_metadata.h include/sc_disk.h \
include/sc_path.h $(LIB)
mkdir -p $(dir $@)
$(PROJ_ROOT)/bin/sprinter-cc --memory big --safe --max-allocs $(ALLOCS) \
-I include --bank 1=src/sc_copy_job.c --bank 1=src/sc_metadata.c \
--bank 1=src/sc_disk.c \
-o $@ tests/p19_overwrite_probe.c src/sc_path.c
hdd-p19-overwrite: $(P19_OVERWRITE_TEST_EXE)
sh tests/make_p19_overwrite_hdd.sh \
$(CURDIR)/build/hdd/p19_overwrite.chd $(P19_OVERWRITE_TEST_EXE)
hdd-p19-policy: $(EXE)
sh tests/make_p19_policy_hdd.sh \
$(CURDIR)/build/hdd/p19_policy.chd $(EXE)
.PHONY: hdd-stress hdd-copy hdd-exec hdd-p5 hdd-p5-enospc hdd-p5-panels \
hdd-p5-viewer hdd-p5-copy-faults hdd-p5-media hdd-p6-sort hdd-p7-select \
hdd-p8-masks hdd-p9-mkdir hdd-p10-rename hdd-p11-delete \
hdd-p12-group-copy hdd-p13-group-delete hdd-p14-default-colors \
hdd-p15-tree-copy hdd-p15-tree-cancel hdd-p15-tree-self \
hdd-p16-group-tree-copy hdd-p17-tree-delete hdd-p17-tree-delete-cancel \
hdd-p18-metadata hdd-p19-overwrite hdd-p19-policy
+112
View File
@@ -0,0 +1,112 @@
# Sprinter Commander
Функциональный аналог классического двухпанельного Commander для Sprinter
Sp2000. Volkov Commander 4.05/4.99 и Dos Navigator используются как
поведенческие и архитектурные референсы; проект не является переносом их
DOS-кода.
Текущее состояние: PoC 0.1 (этапы P1P5) пройден в MAME / BIOS 3.06 /
DSS 1.71.57; аппаратный smoke-тест остаётся внешним контрольным пунктом.
Начат этап 0.2: готовы независимые для каждой панели сортировки по имени,
расширению, размеру и дате/времени в обоих направлениях, выбор записей через
`Insert`, `*` и маски `+`/`-`, создание каталога по `F7` и локальное
переименование файла/каталога по `F6` без overwrite, однообъектный F8 и
групповой рекурсивный F8 для выбранных файлов и каталогов, а также рекурсивный
F5 для выбранных файлов и каталогов. F5 сохраняет FAT date/time и атрибуты
`R/H/S/A` обычных файлов и поддерживает conflict-policy
`overwrite/skip/rename`, включая `overwrite all`/`skip all`, отдельную
защиту readonly и backup/rollback. Обход использует динамическую EMM-очередь.
Встроенный профиль имён уже различает белые каталоги, жёлтые `.EXE` и
светло-серые остальные файлы; загрузка пользовательских цветовых правил
остаётся задачей 1.0.
Командер
сканирует, хранит и сортирует каталоги, показывает явную виртуальную запись
предела DSS 1.71, безопасно копирует один файл через выделенную EMM-страницу
W3 и запускает `.EXE` с восстановлением режима, палитры, CWD и обеих панелей.
## Сборка
Из этого каталога:
```sh
make
```
Результат: `build/sprcmd.exe`, конфигурация
`--memory big --safe --max-allocs 3000`. Значение `ALLOCS=3000` принято как
исходное для Commander и всех его проб; при диагностике его можно переопределить
явно, например `make ALLOCS=4000`.
Основные тесты используют быстрый HDD `D:`:
```sh
make hdd # только Commander
make hdd-stress # большой каталог P3
make hdd-copy # набор успех/overwrite/cancel/zero для P4.1
make hdd-exec # запуск child/restore/error для P4.2
make hdd-p5 # 20 copy, граничные размеры, 100 refresh, lifecycle
make hdd-p5-enospc # реальный disk-full и cleanup temp
make hdd-p5-panels # точные границы панели 27/28 записей
make hdd-p5-copy-faults # детерминированная матрица ошибок copy/EXEC
make hdd-p5-viewer # запуск реального mdview2 и восстановление Commander
make hdd-p5-media # снятие/возврат hard2 во время F5
make hdd-p6-sort # target-матрица и UI-сценарий сортировок 0.2
make hdd-p7-select # выбор Insert/*, статистика и EMM cleanup
make hdd-p8-masks # тот же расширенный образ: редактор и маски +/−
make hdd-p9-mkdir # validator DOS 8.3, mkdir/error/CWD и UI F7
make hdd-p10-rename # file/dir rename, no-overwrite, CWD и UI F6
make hdd-p11-delete # confirm/cancel, file/empty-dir, guards и UI F8
make hdd-p12-group-copy # legacy group fixture; current F5 also copies selected dirs
make hdd-p13-group-delete # legacy file-only group F8 regression
make hdd-p14-default-colors # built-in dir/EXE/file colours и restore палитры
make hdd-p15-tree-copy # recursive current directory, depth=16 и repeat guard
make hdd-p15-tree-cancel # Esc в 4-МБ файле и cleanup temp/traversal page
make hdd-p15-tree-self # target-inside-source guard до mutation
make hdd-p16-group-tree-copy # selected files + multiple directory roots
make hdd-p17-tree-delete # recursive group F8, depth=12, cancel confirmation
make hdd-p17-tree-delete-cancel # Esc после начала recursive group F8
make hdd-p18-metadata # exact FAT date/time + R/H/S/A после F5
make hdd-p19-overwrite # target backup/commit/rollback matrix
make hdd-p19-policy # UI overwrite/skip/rename/all/readonly/cancel
```
`make floppy` сохранён для smoke-проверки совместимости с FDD и не запускает
эмулятор. Подробнее: [политика тестовых носителей](docs/test-media.md).
## Документы
- [требования PoC](docs/commander-requirements.md);
- [архитектура](docs/commander-architecture.md);
- [roadmap](docs/commander-roadmap.md);
- [клавиши и команды](docs/commander-keymap.md);
- [результаты платформенных проб P1](docs/p1-platform-probes.md);
- [экранный backend и границы BIOS API](docs/p2-screen-backend.md);
- [результаты coordinate-screen probe P2.1](docs/p2-screen-probe-results.md);
- [результаты системной палитры P2.2](docs/p2-palette-results.md);
- [результаты двухпанельного skeleton P2](docs/p2-skeleton-results.md);
- [результаты файловых панелей P3](docs/p3-panel-results.md);
- [результаты копирования P4.1](docs/p4-copy-results.md);
- [результаты запуска EXE P4.2](docs/p4-exec-results.md);
- [результаты стабилизации P5](docs/p5-stability-results.md);
- [результаты сортировок 0.2/P6](docs/p6-sort-results.md);
- [результаты выбора записей 0.2/P7](docs/p7-selection-results.md);
- [результаты выбора по маске 0.2/P8](docs/p8-mask-results.md);
- [результаты создания каталога 0.2/P9](docs/p9-mkdir-results.md);
- [результаты локального rename 0.2/P10](docs/p10-rename-results.md);
- [результаты однообъектного delete 0.2/P11](docs/p11-delete-results.md);
- [результаты группового F5 0.2/P12](docs/p12-group-copy-results.md);
- [результаты группового F8 0.2/P13](docs/p13-group-delete-results.md);
- [результаты стандартных цветов P14](docs/p14-default-colors-results.md);
- [результаты рекурсивного F5/P15](docs/p15-tree-copy-results.md);
- [результаты рекурсивного group F5/P16](docs/p16-group-tree-copy-results.md);
- [результаты рекурсивного group F8/P17](docs/p17-tree-delete-results.md);
- [результаты сохранения метаданных F5/P18](docs/p18-metadata-results.md);
- [результаты conflict-policy F5/P19](docs/p19-copy-policy-results.md);
- [направление развития UI по образцу VC](docs/ui-reference.md);
- [инструкция и ограничения PoC 0.1](docs/poc-0.1-release.md);
- [носители интеграционных тестов](docs/test-media.md);
- [предел больших каталогов DSS и стратегия Commander](docs/dss-large-directories.md).
Экран выводится системными координатными функциями ESTEX/BIOS без оконных
дескрипторов и без прямой адресации VRAM. Системные вызовы палитры разрешены;
их save/set/readback/restore и многоцветная сцена подтверждены пробой P2.2.
@@ -0,0 +1,36 @@
# Артефакты MAME-прогона P1
Дата: 6 сентября 2026 года.
Окружение: MAME 0.287 (`b0c4527c`), машина `sprinter`, BIOS `v3.06`, текущие системные
образы проекта. `p1probe.exe` и `p1child.exe` запускались с дискеты A:.
Каталоги:
- `directory/` — CWD, `*.*`, `*`, завершение F_NEXT с `ENOENT=3`;
`strict-enoent.png` снят после удаления временного допуска `EISDIR`;
- `emm/` — три страницы, граничные patterns и возврат free pages;
- `dskinfo/` — геометрия и свободное место текущего диска;
- `winrest/` — полный экран 80x32 и частичный вывод из offset `0x2000`;
`partial-phase-hidden.png`/`partial-stable.png` показывают неудачные raw-
атрибуты, а `partial-flash-phase.png`/`partial-contrast-stable.png`
именованный цветной pattern. Повторная проверка декодированных RGB показала,
что два последних кадра пиксельно идентичны; P2.2 отдельно подтвердил
стабильность четырёх палитровых планов;
- `exec/` — оба вызова child и итоговые значения EXEC/WAIT;
- `exec-then-emm/` — повторный EMM-тест после двух EXEC в том же процессе;
- `keyboard-commander/` — навигация, F1F10, Ctrl+R, Ctrl+PgUp, Alt+F1;
- `keyboard/` — дополнительная проба Ctrl+A, Alt+X и Shift+Tab.
Нумерованные клавиатурные кадры соответствуют времени сценария:
- `0000.png` — первые навигационные события;
- `0001.png` — продолжение навигации и начало F-клавиш;
- `0002.png` — полная базовая таблица до сочетаний;
- `0003.png` — сочетания, Esc и общий `RESULT: PASS`;
- `0004.png` — возврат в главное меню.
Интерпретация результатов и ссылки на основные кадры находятся в
`docs/p1-platform-probes.md` и `docs/commander-keymap.md`.
Актуальная интерпретация палитры находится в
`docs/p2-palette-results.md`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Some files were not shown because too many files have changed in this diff Show More