mdview2: полировка статус-бара/справки/детекции + libc min/max

- status-bar: dirty-tracking (числа/процент/кодировка перерисовываются
  только при изменении), поле кодировки сдвинуто к DIV1_X-10 (8 симв.)
- md_key: HOME/END не перерисовывают экран, если позиция не меняется
- help: версия v1.0(a3), добавлены F2/F3 (RAW/Wrap), компактные секции
- enc: детекция по 5 частотным буквам и сэмплу 1КБ; ENC_UNSUPPORTED (UTF16/32)
- libc: добавлены min()/max() (naked, <stdlib.h>) + сборка в lib/Makefile

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 20:43:04 +03:00
parent 1b78dda125
commit 733746572c
9 changed files with 260 additions and 104 deletions
+32 -12
View File
@@ -70,12 +70,22 @@ void set_encoding(uint8_t enc)
/* Самые ходовые строчные русские буквы (о е а и н т с р в л) — их байты
* различают 8-битные кодировки по частоте. */
static const uint8_t common866 [10] = {0xAE,0xA5,0xA0,0xA8,0xAD,0xE2,0xE1,0xE0,0xA2,0xAB};
static const uint8_t common1251[10] = {0xEE,0xE5,0xE0,0xE8,0xED,0xF2,0xF1,0xF0,0xE2,0xEB};
static const uint8_t commonkoi [10] = {0xCF,0xC5,0xC1,0xC9,0xCE,0xD4,0xD3,0xD2,0xD7,0xCC};
// static const uint8_t common866 [10] = {0xAE,0xA5,0xA0,0xA8,0xAD,0xE2,0xE1,0xE0,0xA2,0xAB};
// static const uint8_t common1251[10] = {0xEE,0xE5,0xE0,0xE8,0xED,0xF2,0xF1,0xF0,0xE2,0xEB};
// static const uint8_t commonkoi [10] = {0xCF,0xC5,0xC1,0xC9,0xCE,0xD4,0xD3,0xD2,0xD7,0xCC};
// static uint8_t in_set10(const uint8_t *s, uint8_t b)
// {
// for (uint8_t i = 0; i < 10; i++) if (s[i] == b) return 1;
// return 0;
// }
/* Проверяем только пять самых популярных символов (о е а и н) */
static const uint8_t common866 [5] = {0xAE,0xA5,0xA0,0xA8,0xAD};
static const uint8_t common1251[5] = {0xEE,0xE5,0xE0,0xE8,0xED};
static const uint8_t commonkoi [5] = {0xCF,0xC5,0xC1,0xC9,0xCE};
static uint8_t in_set10(const uint8_t *s, uint8_t b)
{
for (uint8_t i = 0; i < 10; i++) if (s[i] == b) return 1;
for (uint8_t i = 0; i < 5; i++) if (s[i] == b) return 1;
return 0;
}
@@ -88,7 +98,7 @@ uint8_t detect_encoding(void)
return ENC_UTF8;
uint32_t n = file_size;
if (n > 4096u) n = 4096u; /* сэмпл: первые 4 КБ — детекции хватает */
if (n > 1024u) n = 1024u; /* сэмпл: первый 1 КБ — детекции хватает */
uint8_t utf_ok = 1, has_mb = 0, has_high = 0, cont = 0;
uint16_t s866 = 0, s1251 = 0, skoi = 0;
@@ -102,10 +112,11 @@ uint8_t detect_encoding(void)
if (cont) {
if ((b & 0xC0) == 0x80) cont--;
else { utf_ok = 0; cont = 0; }
} else if (b >= 0xC2 && b <= 0xDF) { cont = 1; has_mb = 1; }
else if (b >= 0xE0 && b <= 0xEF) { cont = 2; has_mb = 1; }
else if (b >= 0xF0 && b <= 0xF4) { cont = 3; has_mb = 1; }
else utf_ok = 0; /* битый лид/одиночный континюэйшн */
}
else if (b >= 0xC2 && b <= 0xDF) { cont = 1; has_mb = 1; }
else if (b >= 0xE0 && b <= 0xEF) { cont = 2; has_mb = 1; }
else if (b >= 0xF0 && b <= 0xF4) { cont = 3; has_mb = 1; }
else utf_ok = 0; /* битый лид/одиночный континюэйшн */
}
/* Незавершённая multibyte-последовательность на КОНЦЕ — нарушение только
* если это настоящий EOF; на границе сэмпла (n<file_size) это просто
@@ -138,7 +149,10 @@ static uint8_t attr_is_content(uint8_t a)
* g_remap (CP1251/KOI8). Без активной таблицы — прямой win_rest. */
void win_rest_remap(uint8_t row, uint8_t w, uint8_t page, uint16_t off)
{
if (!g_remap || w == 0) { win_rest(row, 0, 1, w, page, off); return; }
if (!g_remap || w == 0) {
win_rest(row, 0, 1, w, page, off);
return;
}
uint8_t buf[SCREEN_W * 2];
bank_read(page, off, buf, (uint16_t)w * 2u);
for (uint8_t i = 0; i < w; i++) {
@@ -225,7 +239,10 @@ static void conv_emit_cp(uint32_t cp)
if (cp == 0x2026) { conv_put('.'); conv_put('.'); conv_put('.'); return; } /* … → "..." */
if (cp == 0xFEFF) return; /* BOM/ZWNBSP — выкинуть */
for (uint8_t i = 0; i < UTF_SYM_N; i++)
if (utf_sym[i].utf8 == (uint16_t)cp) { conv_put(utf_sym[i].cp866); return; }
if (utf_sym[i].utf8 == (uint16_t)cp) {
conv_put(utf_sym[i].cp866);
return;
}
conv_put('?');
}
@@ -251,7 +268,10 @@ void utf_convert_more(uint32_t target)
while (utf_src < n &&
(uint32_t)((uint32_t)conv_page * PAGE_SIZE + conv_off) < target) {
uint8_t b = (uint8_t)cv_read(utf_src++);
if (b < 0x80) { conv_emit_cp(b); continue; }
if (b < 0x80) {
conv_emit_cp(b);
continue;
}
uint32_t cp;
uint8_t need;