Обвязка для быстрых тестов plain-C логики: секунды вместо прогона в MAME,
без образа диска. ucsim_z80 идёт в комплекте нашего SDCC — новых
зависимостей нет.
ПОЧЕМУ ПОД Z80, А НЕ ХОСТОВЫМ GCC. У SDCC z80 int 16 бит, у хоста 32, и
расходится это НЕ в объявлениях, а в выражениях: integer promotion
повышает операнды до int независимо от того, объявлены они как uint8_t
или uint16_t. Перевод кода на фиксированные типы разницу не убирает —
убирает только исполнение с z80-семантикой. Побочно проверяется
кодогенерация SDCC и модули с inline-asm, которых хостовая сборка не
видит в принципе.
Устройство: crt0_ucsim.s (SP, зануление, main, halt), tcheck.* (итог в
структуру в ОЗУ), run_ucsim.py (гоняет ucsim, дампит tc_result, печатает
отчёт), host-tests.mk (общие правила). Вывода через printf нет: тестовый
бинарь линкуется без Sprinter-libc. Через ucsim-simif не идём — номера
его команд плавают между версиями, halt + dump работают везде.
Наборы лежат РЯДОМ с проверяемым кодом, обвязка общая:
testkit/t_selftest.c — самопроверка (sizeof(int)==2)
applications/PoP/roomtest/tests-host/ — движок PoP
Первый содержательный набор — t_geom: сверяет рукописный asm-LCG из
pop_geom.c с наивной 32-битной формулой на 128 шагах. Заявка «бит-в-бит
как в SDLPoP» до сих пор держалась на комментарии. Тест проверен
мутацией: порча эталонной константы даёт красный.
Планы дальнейшего покрытия:
docs/host-tests-plan.md — libc и libbgi (не начато)
applications/PoP/docs/host_tests_plan.md — движок PoP
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Три Critical'а (BUG-1 провал на row 1 при боковом переходе, BUG-2 ping-pong
при возврате, BUG-3 окклюзия climb-up на кнопке) висели непроверенными с
2026-07-21. Прогнал в MAME:
- BUG-1 не воспроизводится: room6 → кнопка (0,2) → открытая решётка →
переход влево даёт room8, y=55, curr_row=0. Заодно снят и сам диагноз
записи — репроекция Y при БОКОВОМ переходе не нужна: goto_other_room
(seg002.c:390) меняет только x, наш check_leave делает то же.
- BUG-2 не воспроизводится: шов room2↔room3, четыре пересечения с
разворотом сразу после входа — комната меняется ровно раз на пересечение.
- BUG-3 закрыт фиксом tile_code_drawn от 2026-07-28 (это дубль уже
записанного «спуск с кнопки»); оговорка про непереснятый подъём — в
bug_closed.md.
bug_list.md теперь только открытое (BUG-CEIL-1/2/3, BUG-OCCL-1, T-1, T-2,
таблица обхода 24 комнат) + индекс с якорями. bug_closed.md — закрытое
вместе с разбором корней (odd-pixel char_x, подстановка тайла кнопки, баг
кодогенератора SDCC), он и есть главная ценность архива.
TASKS.md: кросслинки на открытые баги в шапке, в L1-TRIAGE, L1-PASS и
«Отложено». Указатели в CLAUDE.md/README/room_model_plan/layout_plan_v2
переведены на нужный из двух файлов.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Документы отстали от кода: PORT_PLAN писал «PoC не начат», хотя играется
весь уровень 1, а четыре плана были исполнены целиком.
- PORT_PLAN: таблица статусов по разделам; фазы 0-3 сделаны, 4-6 нет;
риски §8 п.1/п.3 закрыты, п.2 переформулирован под реальный движок
(спрайтовый движок для персонажей не используется, лимит «21 спрайт»
неприменим), п.4 — найдено расхождение таймингов: оригинал считает
логический кадр за 5 тиков при BASE_FPS=60 (83.3 мс, в бою 100 мс), а мы
ждём три vsync (60 мс) — игра идёт примерно на 39 % быстрее эталона.
- levels_plan.md — новый: машинерия перехода между уровнями, второй
тайлсет (palace), потабличные различия и читы SDLPoP, которые окупаются
сразу. Инвентарь тайлов снят прямо с res200N.bin: уровень 2 не требует
ни одного нового ассета и ни одной новой механики.
- roomtest/TASKS.md — новый: доска текущих задач с критериями готовности.
- Удалены как исполненные и перекрытые кодом: clip_char_plan,
double_buffer_plan, loose_floors_plan, size_optimization_plan. Его §8
(замеры скорости отрисовки) не был перекрыт — перенесён в
layout_plan_v2 §9, чтобы не потерять цифры.
- KID_PLAN / gates_spikes_plan — шапки «реализовано, оставлено
справочником»; room_model_plan — «S1 сделан, остальное не срочно».
- docs/README.md стал индексом с отметками актуальности.
- ideas_backlog: зелье переворота экрана — оригинал переворачивает готовый
буфер построчно, спрайты не трогает; по данным уровней тип 4 встречается
только на уровне 9, до него механика не нужна.
- examples/scroll: ссылка на удалённый план вела к неверному факту
«теневая копия одна — общая»; заменено на подтверждённое «у каждой
страницы своя».
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Проваливающиеся полы в roomtest (порт SDLPoP seg007/seg008), проверено в MAME:
- Падающий кусок (mob): правый край env-42 (w=26, доходит до mob_x+57)
теперь полностью покрыт heal-коридором (MOB_W 56->64) — убран тёмный
хвост-тень на полу 2,7 ПОСЛЕ падения.
- Окклюзия правого куска во ВРЕМЯ падения: после отрисовки плиты
перерисовывается сосед-пол draw_tile(row,col+1) в том же кадре — край
прячется за полом 2,7 (порт redraw_at_cur_mob: set_redraw_full+1).
- Тряска от сотрясения (knock): seqtbl-команды KNOCK_DOWN/UP в play_seq ->
флаг knock -> do_knock(ряд) трясёт loose ряда из покоя (modif=0x80).
KNOCK_DOWN в land-seq (приземление) и runcyc (footstep).
- Фикс «бесконечной тряски» (дабл-буфер): при завершении тряски (0x84->0)
перерисовать покойный кадр плиты на ОБЕИХ страницах (loose_rest, 2 кадра) —
иначе на одной странице застревает дрожащий кадр правой грани (живёт в
тайлах col и col+1) -> мерцание через флип.
Инфраструктура/документация:
- app.mk: цель `make hdd` (упаковка в D: для MCP-моста MAME).
- docs: POP-DAT-FormatSpecifications.pdf/.txt как каноническая спецификация
форматов ресурсов; ссылки в README/MSDOS_RESOURCE_FORMAT.
- README.md/CLAUDE.md для applications/PoP и roomtest (правило «SDLPoP —
источник истины», порядок слоёв, режим отладки freeze 1/2).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>