mdview2: percent на 16-битной арифметике (убрать __divulong)

calc_md_pct/calc_raw_pct тянули 32-битное деление __divulong (+__muluint2ulong)
ради показа процента в статусе. Оба дают операнды ≤16 бит (≤18432 / ≤1024),
переполняет только *100. Новый pct16() масштабирует оба вниз и считает долю
циклом-вычитанием — 66 Б, НОЛЬ подтянутых арифм-хелперов. Точность ±1%
(на границах точно), для индикатора прокрутки незаметно.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 23:00:14 +03:00
parent 977e2d3d4a
commit fabbc8129c
4 changed files with 23 additions and 6 deletions
+17
View File
@@ -284,6 +284,23 @@ void fill_row(uint8_t y, uint8_t attr)
bios_clearwin(y, 0, 1, SCREEN_W, attr);
}
/* Процент 0..100 = num*100/den на чистой 16-битной арифметике — чтобы НЕ
* тянуть 32-битное деление __divulong (~760 Б) ради показа процента в статусе.
* Оба вызова (MD/RAW) дают операнды, влезающие в 16 бит (≤18432 и ≤1024),
* переполняет только *100 — поэтому масштабируем оба вниз, пока num*100 не
* влезёт в uint16, затем считаем долю циклом-вычитанием (без div-хелпера).
* Инвариант вызовов: num ≤ den; результат всё равно ограничен 100. */
uint8_t pct16(uint16_t num, uint16_t den)
{
if (den == 0) return 0;
while (num > 655) { num >>= 1; den >>= 1; } /* num*100 ≤ 65500 < 65536 */
if (den == 0) return 100; /* страховка от num>den */
uint16_t n = (uint16_t)(num * 100u);
uint8_t p = 0;
while (n >= den && p < 100) { n = (uint16_t)(n - den); p++; }
return p;
}
/* Отображает указанную EMM-страницу файла в окно W3.
* Если эта страница уже активна, переключение не выполняется. */