Инвентаризация делений по .asm: убраны три, остальные разобраны

Обход всех сгенерированных .asm (awk по `call __div/__mod/__mul` с
привязкой к строке исходника) нашёл 31 вызов в 9 модулях.  Три из них
были в горячем пути:

- pop_cdraw.c calc_screen_x_coord: `x * 8 / 7` -> __divsint, 2 400 тактов
  на ПЕРСОНАЖА КАЖДЫЙ КАДР (два вызова при живом сопернике).  Заменено
  тождеством 8x/7 == x + x/7 плюс таблица DIV7[256] в банке 4 — резидент
  не тронут, обычный диапазон (obj_x 0..252 при x_bump 58..184) покрыт
  целиком, деление осталось только хвостом для шва (render_dx = ∓140).
- pop_guard.c guard_col_from_x: /14 и %14 звались БЕЗУСЛОВНО, мимо
  POP_TILE_DIV — единственное 16-битное деление без подключённой таблицы.
- pop_trob.c animate_chomper: `tp / 10` на чомпера каждый кадр, при том
  что TP_ROW/TP_COL лежали в этом же файле, но ниже по тексту.  Таблицы
  подняты выше чомперов.

Остальные 25 оставлены осознанно и расписаны в TASKS_OPEN.md: хвосты за
таблицей (x вне 0..255 = персонаж в соседней комнате), намеренный
медленный хвост pop_y_to_row, недостижимая ветка pop_rnd_fit и холодные
места (вход стража, старт уровня, читы, имя файла, отладочный HUD).

В банках 4, 6, 7 теперь ноль __div*.  Тождество 8x/7 закреплено тестом
geom_mul8div7_identity (перебор −420..700), таблица DIV7 сверена с x//7.
tests-host: [geom] 840 -> 1961, все 5 наборов прошли.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 20:23:43 +03:00
parent 8cac51d592
commit 72797e1be8
5 changed files with 129 additions and 17 deletions
@@ -72,6 +72,18 @@ TC_TEST(geom_y_to_row_matches_formula)
}
}
/* calc_screen_x_coord (seg008:2602) считается в pop_cdraw.c таблицей DIV7 по
* тождеству 8x/7 == x + x/7 (7x делится нацело, поэтому усечение обеих частей
* совпадает). Само тождество и проверяем — оно и есть неочевидная часть;
* таблица DIV7 сгенерирована как x/7 и живёт в банке 4, сюда не линкуется. */
TC_TEST(geom_mul8div7_identity)
{
int16_t x;
/* obj_x = 2*fwd 116; со сдвигом шва (∓140) уходит в 406..684. */
for (x = -420; x <= 700; x++)
TC_EQ((int16_t)(x * 8 / 7), (int16_t)(x + x / 7));
}
/* ---- PRNG: сверка asm-LCG с эталонной формулой ---------------------- */
#if POP_PRANDOM_EXACT
@@ -154,6 +166,7 @@ int main(void)
TC_RUN(geom_yland_rows);
TC_RUN(geom_y_to_row);
TC_RUN(geom_y_to_row_matches_formula);
TC_RUN(geom_mul8div7_identity);
#if POP_PRANDOM_EXACT
TC_RUN(geom_lcg_matches_reference);
TC_RUN(geom_lcg_seed_zero);