scr_x: байтовая таблица x/7 вместо словарной — 1 такт быстрее, -1152 Б
Гипотеза «двухбайтная индексация съест выигрыш от сложения» не
подтвердилась. Собраны ОБА варианта, такты посчитаны по сгенерированному
asm (хвост после проверки границ):
int16_t готовое: add hl,hl / add hl,de / ld e,(hl) / inc hl / ld d,(hl)
= 132 такта, 2 304 байта
int8_t x/7: add hl,bc / ld a,(hl) / ld l,a / rlca / sbc a,a /
ld h,a / add hl,de = 131 такт, 1 152 байта
Расширение знака плюс 16-битное сложение стоят ровно столько же, сколько
лишний add hl,hl при двухбайтном индексе, а обращений к памяти на одно
меньше — под wait-state'ами Sprinter (2,4x номинала именно на обращениях
к ОЗУ) байтовый вариант ещё чуть выгоднее номинала.
Банк 4: 9 394 -> 8 243 из 16 384 (свободно 8 141 вместо 6 990) — запас под
рост pop_cdraw, о котором и был вопрос.
Тест переименован в geom_mul8div7_table_rules и проверяет ОБА правила
генерации таблицы: тождество 8x/7 == x + x/7 и усечение к нулю.
tests-host: [geom] 1992 -> 3144, все 5 наборов прошли.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,20 +72,23 @@ TC_TEST(geom_y_to_row_matches_formula)
|
||||
}
|
||||
}
|
||||
|
||||
/* calc_screen_x_coord (seg008:2602) считается в pop_cdraw.c ГОТОВОЙ таблицей
|
||||
* SCRX (банк 4, сюда не линкуется). Таблица сгенерирована питоном по правилу
|
||||
* «усечение К НУЛЮ»: значение = знак(x) * (|x|*8 / 7). Проверяем ИМЕННО это
|
||||
* правило на целевом компиляторе: если бы __divsint у SDCC округлял иначе
|
||||
* (к минус бесконечности), вся отрицательная половина таблицы уехала бы на
|
||||
* пиксель, а поймалось бы это только глазами на левой кромке комнаты. */
|
||||
TC_TEST(geom_mul8div7_trunc_to_zero)
|
||||
/* calc_screen_x_coord (seg008:2602) считается в pop_cdraw.c таблицей SCRX7
|
||||
* (банк 4, сюда не линкуется): хранится x/7 байтом, результат = x + SCRX7[..].
|
||||
* Таблица сгенерирована питоном, поэтому проверяем два правила, на которых
|
||||
* держится генерация — ИМЕННО на целевом компиляторе:
|
||||
* 1) тождество 8x/7 == x + x/7 (7x делится нацело);
|
||||
* 2) усечение К НУЛЮ, а не к минус бесконечности.
|
||||
* Округляй SDCC иначе — вся отрицательная половина уехала бы на пиксель, и
|
||||
* поймалось бы это только глазами на левой кромке комнаты. */
|
||||
TC_TEST(geom_mul8div7_table_rules)
|
||||
{
|
||||
int16_t x;
|
||||
/* Полный диапазон obj_x по данным кадров: −416..695 (см. шапку scr_x). */
|
||||
for (x = -448; x <= 703; x++) {
|
||||
int16_t want = (int16_t)(((x < 0) ? -x : x) * 8 / 7);
|
||||
if (x < 0) want = (int16_t)-want;
|
||||
TC_EQ((int16_t)(x * 8 / 7), want);
|
||||
TC_EQ((int16_t)(x * 8 / 7), want); /* усечение к нулю */
|
||||
TC_EQ((int16_t)(x * 8 / 7), (int16_t)(x + x / 7)); /* тождество */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +174,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_trunc_to_zero);
|
||||
TC_RUN(geom_mul8div7_table_rules);
|
||||
#if POP_PRANDOM_EXACT
|
||||
TC_RUN(geom_lcg_matches_reference);
|
||||
TC_RUN(geom_lcg_seed_zero);
|
||||
|
||||
Reference in New Issue
Block a user