Files
Sprinter-SDCC/testkit/host-tests.mk
T
Александр Петров 3fe083331f tests-host: покадровый харнесс сценариев Кида (физика + зацеп)
Проверять физику Кида глазами в MAME дорого и ненадёжно: ошибка почти
всегда не в одной функции, а в РАСХОЖДЕНИИ ТРАЕКТОРИИ через несколько
кадров.  Харнесс гоняет тот же кадр, что и главный цикл
(pop_ctrl_tick -> kid_tick -> pop_phys_tick -> pop_loose_tick), и
сравнивает трассу состояния с эталоном.

- scene.c/.h — раннер: комната + стартовая поза + скрипт ввода -> трасса;
  sc_kid_at_x задаёт точный X (исход часто зависит от фазы внутри тайла).
- stubs.c/.h — libc/libbgi/соседние модули; read() реально отдаёт
  kid_data.bin (иначе kdat_ok=0 и play_seq молчит — трасса замирает).
- t_phys.c — 9 характеризующих сценариев, 1723 сверки (golden/).
- t_grab.c — окно зацепа: существует, достижимо коротким шагом, не
  зависит от рисунка нажатий.
- record_golden.py — снятие эталона по одному сценарию за прогон.
- testkit/host-tests.mk — CODE_LOC настраиваемый, EXTRA_INC/EXTRA_CFLAGS.

Именно харнесс дал доказательство, что физика зацепа у нас верна, и тем
самым перевёл поиск BUG-GRAB-1 на клавиатуру.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 12:32:55 +03:00

92 lines
4.5 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ----------------------------------------------------------------------
# host-tests.mk — общие правила модульных тестов, исполняемых под ucsim_z80.
#
# Сама обвязка (crt0_ucsim.s, tcheck.*, run_ucsim.py) лежит в testkit/ и ни
# к какому подпроекту не привязана: тестировать так можно и libc, и логику
# приложений — всё, что на plain C и не трогает железо.
#
# Подключается из каталога с наборами t_*.c:
#
# TESTKIT := $(abspath ../../../../testkit)
# ENGINE_DIR := $(abspath ..) # где лежат модули под тестом
# OBJS_geom := build/eng_pop_geom.rel # что доложить в этот набор
# include $(TESTKIT)/host-tests.mk
#
# Набор t_<имя>.c подхватывается wildcard'ом, регистрировать не надо.
# ----------------------------------------------------------------------
ifndef TESTKIT
$(error перед include надо задать TESTKIT — путь к каталогу testkit/)
endif
PROJ_ROOT ?= $(abspath $(TESTKIT)/..)
SDCC := $(PROJ_ROOT)/third_party/sdcc/bin/sdcc
SDASZ80 := $(PROJ_ROOT)/third_party/sdcc/bin/sdasz80
UCSIM := $(PROJ_ROOT)/third_party/sdcc/bin/ucsim_z80
RUNNER := $(TESTKIT)/run_ucsim.py
BUILD := build
# --code-loc: стартовый код занимает 13 байт по 0x0000, код с 0x0200.
# --data-loc 0x8000: данные заведомо выше кода.
#
# CODE_LOC переопределяется набором, если ему нужна нижняя память под
# данные: так делает t_phys в roomtest — он кладёт по 0x100 страницу
# таблиц анимации, которую на устройстве туда приводит маппинг W0.
# EXTRA_INC — заголовки, которых нет ни в testkit, ни в ENGINE_DIR
# (например libc/libbgi, когда модуль под тестом их включает).
CODE_LOC ?= 0x0200
EXTRA_INC ?=
CFLAGS := -mz80 --no-std-crt0 --std-c99 --opt-code-size -I$(TESTKIT) \
$(if $(ENGINE_DIR),-I$(ENGINE_DIR)) $(EXTRA_INC) $(EXTRA_CFLAGS)
LDFLAGS := -mz80 --no-std-crt0 --code-loc $(CODE_LOC) --data-loc 0x8000
SUITES := $(patsubst t_%.c,%,$(notdir $(wildcard t_*.c)))
COMMON := $(BUILD)/crt0_ucsim.rel $(BUILD)/tcheck.rel
.PHONY: all clean $(addprefix t_,$(SUITES))
# Иначе make считает .rel/.ihx промежуточными и удаляет их после прогона —
# следующий `make` пересобирал бы всё заново.
.SECONDARY:
# OBJS_<набор> подставляется в правило по имени цели — нужен второй проход
# раскрытия, иначе модуль не попадёт в зависимости и не соберётся.
.SECONDEXPANSION:
# Ярлык каталога в отчёте — с родителем: «tests-host» само по себе
# неоднозначно, когда таких каталогов несколько.
LABEL := $(notdir $(patsubst %/,%,$(dir $(CURDIR))))/$(notdir $(CURDIR))
all: $(addprefix run-,$(SUITES))
@echo "$(LABEL): все наборы прошли ($(words $(SUITES)))"
# Прогон одного набора. Раннер сам разбирает tc_result и возвращает код.
run-%: $(BUILD)/%.ihx
@python3 $(RUNNER) $(UCSIM) $(BUILD)/$*.ihx $(BUILD)/$*.noi
# Удобный псевдоним: `make t_geom` вместо `make run-geom`.
t_%: run-% ;
$(BUILD)/%.ihx: $(BUILD)/%.rel $(COMMON) $$(OBJS_$$*)
@$(SDCC) $(LDFLAGS) -o $@ $(COMMON) $(BUILD)/$*.rel $(OBJS_$*)
$(BUILD)/%.rel: t_%.c $(TESTKIT)/tcheck.h | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
# Модули под тестом собираются ТЕМ ЖЕ компилятором и с той же семантикой,
# что и продукт, — включая модули с inline-asm, которые хостовой сборкой
# не проверить в принципе.
$(BUILD)/eng_%.rel: $(ENGINE_DIR)/%.c | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
$(BUILD)/tcheck.rel: $(TESTKIT)/tcheck.c $(TESTKIT)/tcheck.h | $(BUILD)
@$(SDCC) $(CFLAGS) -c -o $@ $<
$(BUILD)/crt0_ucsim.rel: $(TESTKIT)/crt0_ucsim.s | $(BUILD)
@$(SDASZ80) -plosgff $@ $<
$(BUILD):
@mkdir -p $(BUILD)
clean:
@rm -rf $(BUILD)