mdview2: статус-бар в отдельный модуль, упростить alloc_set_storage
- mdview2_status.c: вынести статус-бар/меню/спиннер из ядра - mdview2.c: убрать retry-цикл в alloc_set_storage (fail-fast вместо ложной устойчивости — при нехватке EMM под индекс контент тоже не влезет) - mdview2.h: дополнить экспортами статус-модуля - mdview2_md.c / mdview2_raw.c: зачистка после расщепления - mdview/mdview.c: переименовать scroll_* → md_scroll_* (симметрия) - docs/fast_ram.md, docs/turboc.txt: добавить справочные доки - examples/mdview2/README.MD, READMEBG.MD: обновить описание Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -112,10 +112,51 @@ int main(void) {
|
||||
- **Кодировки:** CP866 / CP1251 / KOI8-R / UTF-8 (автоопределение, `F8`)
|
||||
- **Максимальный размер файла:** 128 КБ
|
||||
- **Максимальное число строк в индексе:** 16 384
|
||||
- **Максимальная длина строки в рендер-кэше:** 255 ячеек (см. ограничение ниже)
|
||||
- **Режим памяти:** small
|
||||
- Код программы, cтек, данные, куча — окнa W1-W2 (32 КБ, адреса 0x4000–0xBFFF).
|
||||
- Буфер файла — страницы EMM, отображаемые в W3 (0xC000–0xFFFF)
|
||||
|
||||
## Известные ограничения
|
||||
|
||||
### Длина строки в MD-режиме — 255 ячеек
|
||||
|
||||
Рендер-кэш хранит каждую логическую строку как **не более 255 пар (символ, атрибут)**
|
||||
— константа `MAX_CACHE_LINE_LEN`. Лимит задан типами: `g_ncells` и
|
||||
`cache_rec_t.len` — `uint8_t`. Касается всех строк, но заметнее всего на
|
||||
**горизонтально скроллируемых** строках (блоки кода и строки таблиц, флаг
|
||||
`IF_HSCROLL`), которые в MD-режиме можно листать вправо.
|
||||
|
||||
**Что происходит с более длинной строкой:** при индексации `gc_put()` молча
|
||||
отбрасывает каждую ячейку после 255-й (`if (g_ncells < MAX_CACHE_LINE_LEN)`).
|
||||
В кэш попадают только первые 255 ячеек, остаток **теряется** — до него нельзя
|
||||
доскроллить и **нет маркера обрезки** на 255-й позиции (маркер `>` означает лишь
|
||||
«есть ещё в пределах кэша»). Переполнения буфера нет — `gc_put` проверяет границу.
|
||||
|
||||
Важно: «255 ячеек» — это **отрендеренная ширина**, не байты исходника. Табы в
|
||||
коде разворачиваются в пробелы (до `TAB_STOP`), а ячейки таблицы добиваются
|
||||
пробелами до ширины колонки + рамки `│` — поэтому кап достигается раньше, чем
|
||||
255 «полезных» символов.
|
||||
|
||||
> **RAW-режим (`F2`) этого лимита не имеет** — он рисует прямо из файла
|
||||
> побайтово, длинные строки видны целиком (через wrap `F3` или гориз. скролл).
|
||||
|
||||
**Идея снятия лимита** (оценка, не реализовано) — расширить длину до `uint16_t`:
|
||||
- `cache_rec_t.len` `uint8_t→uint16_t` — структура остаётся **ровно 8 байт**
|
||||
(len съедает один pad-байт), адресация `idx<<3` не меняется. Бесплатно.
|
||||
- `g_ncells` / `g_ncells_at_space` → `uint16_t` — главная цена по **коду/скорости**:
|
||||
16-битная арифметика на Z80 в горячем `gc_put` (вызов на каждую ячейку) и в
|
||||
scan-циклах. Ориентир: **+0.2…0.4 КБ кода** + замедление индексации.
|
||||
- Буфер `g_cells[MAX_CACHE_LINE_LEN*2]` в near-RAM (W2) — главная цена по
|
||||
**памяти**: `2 × кап` байт. Сейчас 510 Б; кап 512 → +0.5 КБ, 1024 → +1.5 КБ.
|
||||
EMM-кэш контента (1 МБ) длинные строки тянет легко — узкое место именно near.
|
||||
- `viewport_x` (и копия в `docset_t`) + потолок `max_vx` (сейчас 248) → `uint16_t`,
|
||||
иначе хранить >255 можно, а доскроллить нельзя. Плюс `widths[]`/`ccx` в таблицах/коде.
|
||||
|
||||
Реалистичный компромисс — кап 512–1023: хватит почти всем листингам/таблицам,
|
||||
цена ~+0.3 КБ кода и +0.5…1.5 КБ near-RAM. **Дешёвая полумера без `uint16_t`** —
|
||||
ставить честный маркер обрезки на 255-й позиции, чтобы потеря была видна.
|
||||
|
||||
## TODO
|
||||
|
||||
1. **Увеличение размера документов.** Снять лимит 128 КБ: Достаточно
|
||||
|
||||
Reference in New Issue
Block a user