/* * pop_state.c — данные, которые читают ОБЕ стороны банковой границы. * * Зачем отдельный модуль: sprinter-cc собирает банковый модуль с * --dataseg BANKn, поэтому ВСЯ его писучая память (глобалы, file-static, * статики внутри функций) линкуется В СТРАНИЦУ БАНКА и снаружи не читается * — проверено на .map (2026-07-30: глобал банкового модуля лёг по * 0x0001C000, а не в _DATA). Значит любую переменную, к которой нужен * доступ и из банка, и снаружи, надо держать в НЕбанковом модуле — здесь. * * Модуль обязан оставаться в W1/W2: его читают и главный цикл, и банки. */ #include "pop_state.h" #include "pop_ctrl.h" /* объявления шины control_* (живёт здесь) */ uint8_t pop_loose_landed; /* ---- Шина управления (seg006 globals) ------------------------------ * * Объявлены в pop_ctrl.h, а ЛЕЖАТ здесь: к ним обращаются ТРИ банка — * pop_ctrl (банк 5) пишет с клавиатуры, guards.c (банк 1) подаёт * синтетический ввод ИИ (autocontrol_*, seg002), pop_map (банк 3) читает * через pop_ctrl_shift_held. Сегодня оно уцелело бы и в pop_ctrl.c * (собираем без --bank-data, данные банков остаются в _DATA), но это * флаг сборки: включат его — и шина уедет в страницу банка 5. * * control_x/y/shift — «сырое» состояние осей ЭТОГО кадра (абсолютно: * X LEFT/-1..RIGHT/+1); *_forward/backward/up/down/shift2 — конечный * автомат held/released/ignore (авто-повтор). */ int8_t control_x, control_y, control_shift; int8_t control_forward, control_backward, control_up, control_down, control_shift2; /* Чит «бессмертие» (клавиша I). Отладочный: Кид получает анимацию удара, * но HP не теряет — иначе проверять боёвку приходится с трёх попаданий. */ uint8_t pop_immortal; /* Габариты последней нарисованной двери уровня (порт leveldoor_right / * leveldoor_ybottom): пишет draw_leveldoor из банка pop_bg, читает * clip_char из pop_map. См. pop_state.h. */ int pop_leveldoor_right; int pop_leveldoor_ybottom; /* ---- Отладочная «пустышка» для брейкпоинтов из БАНКОВ ---------------- * * Зачем. PC-брейкпоинт видит только логический адрес, а 0xC000+ — это * окно, куда мапятся ВСЕ банки: точка на адресе банковой функции ловит * заодно чужой код, случайно легший по тому же смещению (проверено: * точка на start_fall из банка 3 срабатывала на каждом кадре — попадала * в pop_bg из банка 2). Условные брейкпоинты этот отладчик MAME не * поддерживает («error in assignment expression» на `==`). * * Приём (идея пользователя, 2026-08-04): позвать ЭТУ функцию ровно из * того места банкового кода, которое отлаживаем, и поставить брейкпоинт * на неё — она резидентна в W1, её адрес однозначен. По возврату из неё * читаем что нужно. Условие «когда именно ловить» пишется обычным `if` * в C — это гибче любых выражений отладчика. * * Счётчик нужен, чтобы вызов не выкинул оптимизатор; заодно видно, сколько * раз точка прошла, если ловим не останавливаясь. */ uint8_t pop_dbg_hits; void pop_dbg_trap(void) { pop_dbg_hits++; }