Files
Sprinter-SDCC/examples/mdview/PLAN_866.md
T
snark13 0dedc4dac8 ChangeLog:
- prebuild.
2026-06-05 23:33:23 +03:00

571 lines
25 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# « ­: ⥪áâ®¢ë© Markdown viewer ¤«ï Sprinter (`examples/mdview`)
## Context
’¥á⮢ ï ªà㯭 ï § ¤ ç  - ¯à®¢¥à¨âì ­ èã libc ­  ­¥âਢ¨ «ì­®¬ interactive-¯à¨«®¦¥­¨¨ (¯®«­®íªà ­­ë© UI, ä ©«®¢ë© I/O, ¯ àá¥à).  à ««¥«ì­® ¤ áâ å®à®è¨© showcase ¯« âä®à¬ë ¨ ¯®¬®¦¥â ¢ëâ é¨âì ­¥¤®¤¥«ª¨ ¢ conio/io. Š®­¥ç­ ï 楫ì: viewer ¤«ï `.md` ä ©«®¢ á ¯®¤á¢¥âª®© ᨭ⠪á¨á , ­ ¢¨£ æ¨¥© ¯® ⥪áâã ¨ ¯®áâà ­¨ç­ë¬ áªà®««¨­£®¬.
**Ž£à ­¨ç¥­¨ï v1 (§ ä¨ªá¨à®¢ ­ë ¯®«ì§®¢ â¥«¥¬):**
- POSIX file API (open/read/lseek/close); FILE pointer / fread / fgets - ­¥ ¨á¯®«ì§®¢ âì
- ®¤á¢¥âª  ç¥à¥§ 梥â: **à §¬¥à § £®«®¢ª ** -> 梥â èà¨äâ ; **bold/italic** -> 梥â ä®­  (¬®­®è¨à¨­­ë© ä®­â ¡¥§ ¦¨à­®£®/ªãàᨢ­®£® ­ ç¥àâ ­¨ï)
** áè¨à¥­¨ï, ॠ«¨§®¢ ­­ë¥ ¯®á«¥ ¯« ­ :**
- ” ©«ë ¤® 128 KB (1-8 EMM-áâà ­¨æ, lazy map ¢ W3 ç¥à¥§ `fb()/map_page()`) - ¨§­ ç «ì­® ¡ë«® ¢ v2
- €­¨¬¨à®¢ ­­ë© spinner ¨ ¯à¥¤¢ à¨â¥«ì­ ï ®âà¨á®¢ª  UI ¯à¨ áâ à⥠- UX
- Inline emphasis: `_`/`*`/`**` ¯®¤ç¨­ïîâáï XOR flanking-¯à ¢¨«ã (whitespace ஢­® á ®¤­®© áâ®à®­ë), `COLOR_YELLOW` ¨ `2 * 3` ®áâ îâáï «¨â¥à « ¬¨
---
## ’¥ªã騩 áâ âãá (2026-06-05)
| Phase | ‘â âãá | Š®¬¬¥­â à¨© |
|---|---|---|
| 1 Plain text + nav | | § £à㧪 , ¨­¤¥ªá æ¨ï, status/menu, ^V/PgUp/PgDn/Home/End/F1/F10/Esc |
| 2 Headers + HR | | H1..H4, `---`/`***`/`___` (á >=3 marker'®¢) |
| 3 Inline emphasis | | `**` / `*` / `_` / `` ` ``; XOR flanking (á¬. ¢ëè¥) |
| 4 Lists / quote / fenced code | | `- / * / +`, `N. / N)`, `> `, ``` ``` ```; light nested lists |
| 4-tables | | â ¡«¨æë ®â«®¦¥­ë ¢¬¥á⥠á Phase 6 |
| 5 Wrap / Unwrap (F2) | | wrap-by-default; soft wrap; F2 ¯¥à¥ª«îç ¥â; hpan <-/-> ¢ truncate-०¨¬¥ |
| 6 ®«­ë© layout â ¡«¨æ | | deferred |
| 7 Links + search | | deferred |
| 8 F8 Raw toggle | | deferred |
| Cache ७¤¥à¥­­ëå áâப | | ­¥ ­ã¦­® ¯® ᪮à®á⨠|
**UX-¯®¯à ¢ª¨ (®â¤¥«ì­® ®â phase-¯« ­ , 2026-06-05):**
- UI (menu + title bar) ®âà¨á®¢ë¢ ¥âáï „Ž `load_file`/`index_lines` - ¯®«ì§®¢ â¥«ì áà §ã ¢¨¤¨â ¨­â¥à䥩á,   ­¥ çñà­ë© íªà ­
- Title bar: `MDVIEW <spinner> <filename>` (3 ¯à®¡¥«  ¬¥¦¤ã MDVIEW ¨ filename, slot ᯨ­­¥à  - col 8)
- Spinner ªàãâ¨âáï ¢® ¢à¥¬ï `load_file` (¯® áâà ­¨æ¥) ¨ `index_lines` (à § ¢ 32 «®£¨ç¥áª¨å áâப¨), ¢ª«îç ï `toggle_wrap`
---
## €àå¨â¥ªâãà 
###  áª« ¤ª  íªà ­  (80x32, ⥪áâ mode 0x03)
```
Row 0: MDVIEW ³ mdview.md ³ L 1-30 / 142 ³ 21% <- status bar (BG=blue, FG=white)
³ ÀÄÄ filename @ col 10
ÀÄÄÄÄÄÄÄÄÄÄ spinner slot @ col 8 (anim. while busy)
Row 1:
... document viewport (30 rows)
Row 30:
Row 31: F1 Help F2 Wrap F10 Exit <- menu bar (BG=blue, FG=cyan)
```
- Viewport = 30 áâப x 80 á⮫¡æ®¢.
- Status / menu ७¤¥àïâáï ç¥à¥§ `wrchar()` (¡¥§  ¢â®-áªà®«« ), viewport - ç¥à¥§ `LOCATE` + ¯®á¨¬¢®«ì­ë© `wrchar()` (⮦¥ ¡¥§  ¢â®-áªà®«« , áâ ¢¨â ¨ char ¨ attr §  ®¤¨­ call).
###  ¬ïâì
Memory mode: **`small`** - DSS ®â¢®¤¨â ¯®¤ ­ è ®¡à § **¤¢  ¡ ­ª  (W1 + W2)** = 32 KB á㬬 à­® (CODE ¢ W1, DATA + STACK + HEAP ¢ W2). ⮣® ¤®«¦­® 墠â¨âì çâ®¡ë … § ¢®¤¨âì `__banked` ä㭪樨. W3 ®áâ ñâáï ¯®«­®áâìî ᢮¡®¤­ë¬ ¤«ï ¬ ¯¯¨­£  ¡®«ìè¨å ¡ãä¥à®¢:
```
W0 (0x0000-0x3FFF): ESTEX (system, untouchable)
W1 (0x4000-0x7FFF): CODE (small mode page 1)
W2 (0x8000-0xBFFF): DATA + STACK + HEAP (small mode page 2)
W3 (0xC000-0xFFFF): paged window - «¥­¨¢® ¯¥à¥ª«îç ¥âáï ¬¥¦¤ã EMM-áâà ­¨æ ¬¨
ä ©«  (¤® 8 áâà ­¨æ = 128 KB). `cur_page` ªíè¨àã¥â
⥪ãéãî mapping, `fb(p)` ¬ ¯¯¨â ­ã¦­ãî áâà ­¨æã ¯à¨
¯¥à¢®¬ ®¡à é¥­¨¨.
```
®ç¥¬ã small + W3:
- 32 KB ­  ª®¤+¤ ­­ë¥ á ¡®«ì訬 § ¯ á®¬ -> ­¥â ¡ ­ª¨­£ 
- W3 - áâ ­¤ àâ­ë© paged window, ¯®¤ ­¥£® ã ­ á 㦥 ¥áâì `bank_io_w3` API
- ” ©«ë ¤® 128 KB ¯®¤¤¥à¦¨¢ îâáï ­ â¨¢­®: `mem_alloc_pages(pages_needed)` ¯®¤ ¢¥áì ä ©«; `map_page()` ç¥à¥§ `sprinter_page_w3()`; `fb(p)` - ¥¤¨­ ï â®çª  ¤®áâ㯠 ¨§ ¨­¤¥ªá â®à  ¨ ७¤¥à .
‘â â¨ª¨ (¢ W2):
- `line_offset[MAX_LINES]` - uint16_t ᬥ饭¨¥ ª ¦¤®© áâப¨ ¢ ä ©«®¢®© áâà ­¨æ¥ (4 KB ­  2048 áâப)
- `cache_tag[CACHE_N]` - uint16_t ⥣ á«®â  (200 ¡ ©â ­  100 ᫮⮢, ¯®ï¢«ï¥âáï ¢ Phase 3)
- `filename[64]`, `top_line`, `total_lines`, `file_size`, `file_blk`, `cache_blk` - ¥¤¨­¨æë ¡ ©â
**FILE_BUF**: `((char*)0xC000)` - 䨪á¨à®¢ ­­ ï  ¤à¥á æ¨ï ¢ W3 ¯®á«¥ ¬ ¯¯¨­£  ­ã¦­®© áâà ­¨æë.
### ®â®ª ¤ ­­ëå
```
main -> open() -> read() chunks 1KB -> write to W1 (mapped EMM page) -> close()
-> index_lines() (®¤­® ᪠­¨à®¢ ­¨¥, § ¯®«­ï¥â line_offset[])
-> render_viewport() + main loop { getkey(); handle(); render_status(); render_viewport() }
```
**’®­ª®áâì á `read()`**: ESTEX READ § ¯¨á뢠¥â ¯® dst-㪠§ â¥«î ¢  ¤à¥á­®¬ ¯à®áâà ­á⢥ ¢ë§ë¢ î饣®. ®áª®«ìªã ¬ë ¬ ¯¯¨¬ EMM-áâà ­¨æã ¢ W3 (0xC000) „Ž ¢ë§®¢  read(), 㪠§ â¥«ì 0xC000+offset ¢ «¨¤¥­. …᫨ ¢ëïá­¨âáï çâ® BIOS âண ¥â W3 ¢® ¢à¥¬ï read (£à ä¨ç¥áª¨© ¢¨¤¥®¡ãä¥à ¯® 㬮«ç ­¨î ¢ W3 ¯à¨ £à ä¨ç¥áª¨å ०¨¬ å, ­® ¢ ⥪á⮢®¬ - ¤®«¦¥­ ¡ëâì ᢮¡®¤¥­) - fallback: ç¨â âì ¢ 1 KB ¡ãä¥à ¢ W2 ¨ ª®¯¨à®¢ âì ¢ W3 ç¥à¥§ `bank_write_w3()`.
---
## ¥ «¨§ æ¨ï - ¯®íâ ¯­ ï
### Phase 1 - Plain text viewer (MVP)
**—â® à ¡®â ¥â:**
- ‡ £à㧪  ä ©«  (`open/read/close`) ¢ W1-áâà ­¨æã
- ˆ­¤¥ªá æ¨ï áâப (LF / CRLF à §¤¥«¨â¥«¨)
- Status bar: ¨¬ï ä ©« , L N-M / Total, ¯à®æ¥­â áªà®««¨­£ 
- Menu bar: `F1 Help F10 Exit`
-  ¢¨£ æ¨ï: ^/V (1 áâப ), PgUp/PgDn (30 áâப), Home/End (­ ç «®/ª®­¥æ), Esc/F10 (¢ë室), F1 (help screen)
- Ž¡à¥§ª  áâப ¤«¨­­¥¥ 80 ᨬ¢®«®¢ (¡¥§ word-wrap)
- –¢¥â : ⥪áâ ¡¥«ë© ­  çñà­®¬; status/menu - ¡¥«ë© ­  ᨭ¥¬
**Šà¨â¨ç­ë¥ ä ©«ë:**
- `examples/mdview/mdview.c` - main, key loop, rendering, indexing (one-file MVP)
- `examples/mdview/Makefile`
- `examples/mdview/SAMPLE.MD` - â¥áâ®¢ë© markdown ä ©«
### Phase 2 - Headers ¨ £®à¨§®­â «ì­ ï «¨­¨ï
**MD ä¨ç¨:**
- `# H1` -> ïમ-¦ñ«âë© (COLOR_YELLOW = 14) ­  çñà­®¬
- `## H2` -> ïમ-£®«ã¡®© (COLOR_LBLUE = 11)
- `### H3` -> ïમ-§¥«ñ­ë© (COLOR_LGREEN = 10)
- `#### H4+` -> á¥àë© (COLOR_GREY = 8)
- `---` / `***` ­  ®â¤¥«ì­®© áâப¥ -> «¨­¨ï 0xC4 (£®à¨§®­â «ì­ ï à ¬ª  ASCII) ¢® ¢áî è¨à¨­ã
### Phase 3 - Inline emphasis
** àá¥à inline (per-line, runs ¢ ®¤­ã áâபã):**
- `**bold**` -> ATTR_TEXT_BOLD
- `*italic*` -> ATTR_TEXT_ITALIC
- `_underscore_` -> ATTR_TEXT_UNDERSORE
- `` `code` `` -> ATTR_TEXT_CODE
- Œ àª¥àë `**`/`*`/`_`/`` ` `` … ७¤¥àïâáï (áꥤ îâáï)
State machine: ®¤¨­  ªâ¨¢­ë© áâ¨«ì ®¤­®¢à¥¬¥­­® (¡¥§ ¢«®¦¥­­®áâ¨); ª®­ä«¨ªâãî騩 ¬ àª¥à ¯à¨ ç㦮¬  ªâ¨¢­®¬ á⨫¥ ¢áñ à ¢­® ª®­áìâáï (zero-width) ¤«ï ᨭåà®­¨§ æ¨¨ è¨à¨­ë á index_lines. ‘®áâ®ï­¨¥ á¡à á뢠¥âáï ­  ª ¦¤®© áâப¥.
**Flanking-¯à ¢¨«® (CommonMark intraword, ॠ«¨§®¢ ­® ¯®á«¥ ¨§­ ç «ì­®£® ¯« ­ ):**
- `*` / `**` / `_` áç¨â îâáï markdown-¬ àª¥à®¬ ⮫쪮 ¥á«¨ whitespace/EOL
஢­® á Ž„މ áâ®à®­ë (XOR).
- ‘«ãç ¨ "®¡  whitespace" (`2 * 3`, `2 ** 3`) -> «¨â¥à «ë ( à¨ä¬¥â¨ª ).
- ‘«ãç ¨ "­¨ ®¤­®£® whitespace" (`COLOR_YELLOW`, `FILE*/fread`, `foo*bar*baz`)
-> «¨â¥à «ë (intraword).
- Backtick (`` ` ``) flanking … âॡã¥â - `` `code` `` à ¡®â ¥â ¡¥§ ¯à®¡¥«®¢.
- à ¢¨«® ¯à¨¬¥­¥­® ᨬ¬¥âà¨ç­® ¢ 4 ¬¥áâ å (`index_lines`, cont-render,
®á­®¢­®© inline-¯ àá¥à, truncation peek), ¨­ ç¥ wrap-¨­¤¥ªá â®à ¨
७¤¥à ࠧꥤãâáï ¯® è¨à¨­¥.
> **Šíè ®âä®à¬ â¨à®¢ ­­ëå áâப** - ®â«®¦¥­ ¢ á ¬ë© ª®­¥æ, á¬. "Phase : ®¯â¨¬¨§ æ¨¨".
> ‘ª®à®á⨠⥪ã饣® ­ ¨¢­®£® ७¤¥à  墠⠥⠭  80x30 = 2400 wrchar / ª ¤à; PgUp/PgDn ¢¨§ã «ì­® ¬£­®¢¥­¥­.
### Phase 4 - Block elements (¡¥§ â ¡«¨æ)
- Œ àª¨à®¢ ­­ë¥ ᯨ᪨: `- foo`, `* foo`, `+ foo` -> ¯à¥ä¨ªá `o` (0x07) + ¯à®¡¥«; 梥⠬ àª¥à  ïàç¥ ®á­®¢­®£®
- 㬥஢ ­­ë¥ ᯨ᪨: `1. foo`, `2. foo` -> ª ª ¥áâì (ç¨á«® ®áâ ¢«ï¥¬)
- Blockquote: áâப¨ á `> ` -> ¯à¥ä¨ªá `³` (0xB3) á¥à®£® 梥â , ®áâ «ì­®© ⥪áâ á«¥£ª  ¯à¨£«ãèñ­­ë©
- Fenced code blocks: `` ``` `` ®âªà뢠¥â/§ ªà뢠¥â ¡«®ª; ¢á¥ áâப¨ ¬¥¦¤ã - bg=á¥àë©, ¬®­®è¨à¨­­® (¡¥§ inline-¯ àᨭ£ )
- Indented code blocks (4+ ¯à®¡¥«®¢):  ­ «®£¨ç­® fenced, ­® ¡¥§ ®£® ¬ àª¥à 
**Light nested lists (v1 - ॠ«¨§®¢ ­®):**
- `classify_line()` ¯à®¯ã᪠¥â leading spaces ¯¥à¥¤ ulist/olist/quote ¬ àª¥à®¬,
¢®§¢à é ¥â `content_off` ¯®á«¥ ¬ àª¥à  -> `content_off - p_start` = indent + marker
¡¨â ¢ visible col.
- `render_line()` à¨áã¥â leading-spaces ¢ `ATTR_TEXT`, ¯®â®¬ ¬ àª¥à ­  ᤢ¨­ã⮩
¯®§¨æ¨¨ (col = indent). Marker ¢áñ ¥éñ 䨪á¨à®¢ ­ ¯à¨ £®à¨§®­â «ì­®¬ pan'¥.
- HR / header / fence delim ®áâ îâáï áâண® col-0 (CommonMark à §à¥è ¥â ¤® 3
¢¥¤ãé¨å ¯à®¡¥«®¢ ¤«ï ­¨å - ã¯à®á⨫¨).
- Tab-indent -> ­¥ à á¯®§­ ñâáï ª ª nesting (⮫쪮 spaces).
**Phase 4-full - ¯®«­ ï ¯®¤¤¥à¦ª  ¢«®¦¥­­®á⨠(deferred):**
- **Tab-indent**: áç¨â âì tab = 4 ¯à®¡¥«  ¤«ï ®¯à¥¤¥«¥­¨ï ã஢­ï.
- **Quote nesting** (`> > foo`): ª ¦¤ë© `>` ¯®¤àï¤ = +1 ã஢¥­ì, ª ¦¤ë© à¨áã¥âáï
®â¤¥«ì­ë¬ `³` ¢ `ATTR_QUOTE_MARKER` (¢¨§ã «ì­ ï "«¥áâ­¨æ " á«¥¢ ).
- **Hanging indent ¢ wrap-continuation**: ª®£¤  `- some very long bullet text
that wraps...` - continuation seg ¤®«¦¥­ ­ ç¨­ âìáï ®â content-col (¯®á«¥
¬ àª¥à ),   ­¥ ®â col 0. ‘¥©ç á continuation ¨¤ñâ ®â col 0 (v1 simplification).
’ॡã¥â åà ­¨âì `marker_width` per «®£¨ç¥áª ï áâப  (8 ¡¨â) ¨«¨ re-classify
first seg ¯à¨ ७¤¥à¥ continuation.
- **Lazy continuation**: áâப¨ ¡¥§ ¬ àª¥à , ­® á ¯à ¢¨«ì­ë¬ indent ¯®¤
¯à¥¤ë¤ã騬 bullet'®¬, ¤®«¦­ë áç¨â âìáï ¯à®¤®«¦¥­¨¥¬ ⮣® bullet' 
(¢¨§ã «ì­® - ®¡é¨© attr).
- **Strict CommonMark indent rules**: ¢«®¦¥­­ë© ¯ã­ªâ ¤®«¦¥­ ¡ëâì ­  indent
>= content_col த¨â¥«ï, ¨­ ç¥ áç¨â ¥âáï breakout. 㦥­ ¬¨­¨-stack
 ªâ¨¢­ëå ᯨ᪮¢ ¯à¨ ¨­¤¥ªá æ¨¨.
### Phase 5 - Wrap / Unwrap ¤«¨­­ëå áâப
„¥ä®«â: **wrap on**. F2 ¯¥à¥ª«îç ¥â; ¢ ¬¥­î-¡ à¥ ¯®¤¯¨áì ®âà ¦ ¥â ¤¥©á⢨¥
("Unwrap" ª®£¤  wrap ¢ª«îçñ­, "Wrap" ª®£¤  ¢ëª«î祭). ‚® ¢à¥¬ï २­¤¥ªá æ¨¨
ªàãâ¨âáï ᯨ­­¥à ­  title bar.
**v1 - ॠ«¨§®¢ ­®:**
- ޤ¨­ ¬ áᨢ `line_offset[2048]` åà ­¨â ‚ˆ„ˆŒ›… ᥣ¬¥­âë (  ­¥ «®£¨ç¥áª¨¥
áâப¨); ¡¨âë 0..13 - ¡ ©â®¢®¥ ᬥ饭¨¥, ¡¨â 15 - CONT-ä« £ continuation.
- Wrap-०¨¬: soft wrap ­  ¯®á«¥¤­¥¬ ¯à®¡¥«¥ <= 80; hard fallback ¥á«¨
¯à®¡¥«  ­¥â.
- Œ àª¥àë í¬ä §¨á  (`**`/`*`/`_`/`` ` ``) ¨ header-¯à¥ä¨ªáë (`#`/`##`/...) ­¥
ãç¨â뢠îâáï ¢ visible-col ¯à¨ ¯®¨áª¥ â®çª¨ ¯¥à¥­®á .
- "‘¯¥æ¨ «ì­ë¥" «®£¨ç¥áª¨¥ áâப¨ ­¥ wrap' îâáï ¢®®¡é¥ (®¤­  seg-§ ¯¨áì ­ 
«®£¨ç¥áªãî áâபã): fence delim, table row (header/separator/body), HR.
- F2 toggle á®åà ­ï¥â ¢¨§ã «ì­ãî ¯®§¨æ¨î ç¥à¥§ `top_offset` ¢ FILE_BUF.
- Bitmaps (`in_code`/`in_table`/`is_tab_hdr`) ¯¥à¥áâà ¨¢ îâáï ¢¬¥á⥠á
ᥣ¬¥­â ¬¨, ¨­¤¥ªá¨àãîâáï seg-¨­¤¥ªá®¬, ¡¨âë áâ ¢ïâáï ⮫쪮 ­  ¯¥à¢®¬
seg'¥ «®£¨ç¥áª®© áâப¨.
- Continuation-ᥣ¬¥­âë ७¤¥àïâáï ¢ á⨫¥ "v1: ¯«®áª®" - plain text,
­¨ª ª¨å markdown-ª« áá¨ä¨ª æ¨©; padding ¤® ª®­æ  áâப¨ `ATTR_TEXT`.
**v1.5 - ®â«®¦¥­® ¤«ï ¯®«­®© ª à⨭ë wrap:**
- **Hanging indent**: continuation ®â ulist/olist/quote ¤®«¦¥­ ¢ëà ¢­¨¢ âìáï
¯®¤ content,   ­¥ ®â col 0. ’ॡã¥â åà ­¨âì marker_width per «®£¨ç¥áª ï
áâப  ˆ‹ˆ re-classify ¯¥à¢®£® seg'  ¯à¨ ७¤¥à¥ continuation.
- ** á«¥¤®¢ ­¨¥ base_attr**: continuation ®â header'  ¤®«¦¥­ á®åà ­ïâì
梥â; continuation ®â code body - ä®­ ATTR_TEXT_CODE. ’ॡã¥â åà ­¨âì
1 ¡ ©â `base_attr` per seg ˆ‹ˆ lookup ¯¥à¢®£® seg' .
- **Inline emphasis ç¥à¥§ £à ­¨æã**: í¬ä §¨á, ®âªàëâë© ¢ ¯¥à¢®¬ seg'¥ ¨ ­¥
§ ªàëâë©, ¤®«¦¥­ ¯à®¤®«¦ âìáï ¢® ¢â®à®¬. ’ॡã¥â åà ­¨âì emph state per
seg (3 ¡¨â ).
- Compact way: ¤®¡ ¢¨âì ¯ à ««¥«ì­ë© ¬ áᨢ `seg_meta[MAX_SEGS]` ¯® 1 ¡ ©âã
- ¯ ªã¥â marker_width (4 ¡¨â ) + emph_state (3 ¡¨â ) + base_attr_idx
(4 ¡¨â  ¨§ â ¡«¨æë -> ­ã¦¥­ 2-¡ ©â®¢ë© seg_meta).
- **Hpan ¤«ï ¤«¨­­ëå áâப**: ¥á«¨ wrap ¢ëª«î祭, ¤®¡ ¢¨âì <-/-> ¤«ï
£®à¨§®­â «ì­®£® áªà®««  >80 cols. ޡ鍩 ¬¥å ­¨§¬ á tables (Phase 6).
**…€‹ˆ‡Ž‚€Ž** (light) - `viewport_x` + ¯®«­ë© re-render ­  ª ¦¤®¥ <-/->.
- **“᪮७¨¥ hpan ç¥à¥§ ESTEX WINCOPY/WINREST** (deferred): ᥩç á pan
¤¥« ¥â ¯®«­ë© `render_viewport()` = 30 áâப x 80 wrchar. Œ®¦­®
᪮¯¨à®¢ âì áãé¥áâ¢ãî饥 ᮤ¥à¦¨¬®¥ viewport'  ­  N cols ¢«¥¢®/¢¯à ¢®
ç¥à¥§ win-copy, ¯®â®¬ ७¤¥à¨âì ⮫쪮 㧪ãî ¯®«®áã á¯à ¢ /á«¥¢ 
(HPAN_STEP cols x 30 rows 240 wrchar ¢¬¥áâ® 2400). ESTEX SCROLL
£®à¨§®­â «ì ­¥ ¯®¤¤¥à¦¨¢ ¥â - ­ã¦­  ¨¬¥­­® WINCOPY-®¯¥à æ¨ï ¨«¨
rdchar/wrchar loop. €ªâ¨¢¨à®¢ âì ª®£¤  ®éãâ¨âáï â®à¬®§; ᥩç á ­ 
⨯®¢®¬ markdown'¥ ­¥ § ¬¥â­®.
**v2 - ®â¤¥«ì­ ï ä¨ç , ¬¨¬® wrap:**
- Toggle ¯®¤á¢¥âª¨ 楫¨ª®¬ (F3?)
- Search ¯® ⥪áâã (Ctrl+F / F4)
- Links `[text](url)` -> ᨭ¨© ¯®¤çñભãâë© text, url ¯àïç¥âáï
- Images `![alt](path)` -> `[IMG: alt]`
### Phase 7 - Links ¨ ¯®¨áª (post-v1)
- `[text](url)` -> ®âà¨á®¢ âì ⮫쪮 `text` á ïમ-ᨭ¨¬ FG (¢¨§ã «ì­® ¯®¤çñભã⮥)
- `![alt](path)` -> `[IMG: alt]` ¢ ᪮¡ª å
- Search ¯® ⥪áâã (F3 / Ctrl+F): ¨­ªà¥¬¥­â «ì­ë©, ¯®¤á¢¥âª  ᮢ¯ ¤¥­¨©
### Phase 8 - F8 Raw / Render toggle
¥à¥ª«îç â¥«ì ०¨¬  ®â®¡à ¦¥­¨ï: ¯à¨ ¢ª«îçñ­­®¬ Raw ¯®ª §ë¢ ¥âáï ¨á室­ë©
⥪áâ ä ©«  ª ª ¥áâì - ¢á¥ markdown-¬ àª¥àë (`#`, `**`, `_`, `` ` ``, `|`,
`>`, `-`, etc.) ७¤¥àïâáï «¨â¥à « ¬¨ á `ATTR_TEXT`, ¡¥§ ª« áá¨ä¨ª æ¨¨.
®«¥§­® ª®£¤ :
- ­ã¦­® 㢨¤¥âì â®ç­ãî à §¬¥âªã (®â« ¦¨¢ ­¨¥ .md, áªà¨­è®âë, ª®¯¨à®¢ ­¨¥)
- markdown-ª« áá¨ä¨ª â®à ®è¨¡áï ¨ å®ç¥âáï 㢨¤¥âì ®à¨£¨­ «
- å®ç¥âáï ¡ëáâà® áà ¢­¨âì "¤®/¯®á«¥" ७¤¥à 
**®¢¥¤¥­¨¥:**
- F8 ¯¥à¥ª«îç ¥â `render_mode` (1=render, 0=raw); ¬¥­î ¯®ª §ë¢ ¥â ®¡à â­®¥
¤¥©á⢨¥ ("Raw" ª®£¤  ᥩç á render, "Render" ª®£¤  ᥩç á raw) - ⮩ ¦¥
«®£¨ª®© çâ® F2/Wrap/Unwrap.
- Raw ०¨¬¥: `render_line()` ¨¤ñâ ¯® ª®à®âª®¬ã ¯ã⨠- ­¨ª ª®£®
`classify_line`, `is_fence_delim`, `is_code_body`, inline-í¬ä §¨á ; ¯à®áâ®
¡ ©â®¢ë© ¤ ¬¯ FILE_BUF ®â seg-offset ¤® next-seg/EOL á tab-expansion ¨
ATTR_TEXT.
-  §¤¥«ì­® ®â F2: ®¡  ०¨¬  ­¥§ ¢¨á¨¬ë (¬®¦­® Raw+Wrap, Raw+Truncate,
Render+Wrap, Render+Truncate). Wrap-«®£¨ª  ¢ `index_lines` à ¡®â ¥â ¢
®¡®¨å á«ãç ïå ®¤¨­ ª®¢® (®¯¨à ¥âáï ­  ¢¨§ã «ì­ë¥ ª®«®­ª¨ ­¥§ ¢¨á¨¬® ®â
à áªà áª¨).
- ‘â âãá-¡ à: ¤®¡ ¢¨âì ¨­¤¨ª â®à `[R]` / `[V]` (Raw / View) ¨«¨ ⥪á⮬
`RAW` à冷¬ á ¨¬¥­¥¬ ä ©« .
**Œ¨­¨¬ «ì­ ï ॠ«¨§ æ¨ï:**
- ޤ¨­ ­®¢ë© static `uint8_t render_mode = 1;`
- `render_line()`: ­  á ¬®¬ ¢¥àåã `if (!render_mode) { ... raw render ... return; }`
- `render_menu()`: ¤®¡ ¢¨âì ïà«ëª F8 à冷¬ á F2.
- ‚ £« ¢­®¬ 横«¥: `case KEY_F8: toggle_render(); break;`
- `toggle_render()` ®â«¨ç ¥âáï ®â `toggle_wrap()` ⥬, çâ® … ¯¥à¥áâà ¨¢ ¥â
`line_offset[]` (wrap-ᥣ¬¥­â æ¨ï ­¥ ¬¥­ï¥âáï), ⮫쪮 ¯¥à¥à¥­¤¥à¨â íªà ­.
---
## API-­®¢¨­ª¨ ¢ libc (¬¨­¨¬ «ì­ë¥)
### `getkey()` - extended key reader (¢ libc)
’¥ªã騩 `getch()` â¥àï¥â scan code à áè¨à¥­­ëå ª« ¢¨è (¢®§¢à é ¥â ⮫쪮 E=ASCII). „®¡ ¢«ï¥¬ **áà §ã ¢ `libc/conio/conio.c`** ­®¢ãî äã­ªæ¨î à冷¬ á `getch()`:
```c
// Returns scan in high byte, ASCII in low byte.
// Extended keys (arrows, F-keys, PgUp/PgDn, Home/End): ASCII=0, scan code ¢ high byte.
// Plain keys: ASCII ¢ low byte; high byte ᮤ¥à¦¨â positional scan (¡¨â 7 = Ctrl/Alt/Shift modifier).
uint16_t getkey(void) __naked {
__asm
ld c, #0x30 ; ESTEX WAITKEY
rst #0x10 ; A=ASCII, D=scan, E=ASCII
ld e, a ; ensure E=ASCII even if E clobbered
ret ; SDCC __sdcccall(1): ¢®§¢à â uint16_t ¢ DE (D=scan, E=ASCII)
__endasm;
}
```
„®¯®«­¨â¥«ì­® - **¢ `libc/include/conio.h`** ¯à®¯¨á âì ¯à®â®â¨¯ ¨ ª®­áâ ­âë scan-ª®¤®¢:
```c
uint16_t getkey(void);
/* Scan codes for getkey() high byte when ASCII=0 (extended keys). */
#define KEY_F1 0x0E
#define KEY_F2 0x0F
#define KEY_F3 0x10
#define KEY_F4 0x11
#define KEY_F5 0x12
#define KEY_F6 0x13
#define KEY_F7 0x14
#define KEY_F8 0x15
#define KEY_F9 0x16
#define KEY_F10 0x17
#define KEY_F11 0x18
#define KEY_F12 0x19
#define KEY_END 0x24
#define KEY_DOWN 0x25
#define KEY_PGDN 0x26
#define KEY_LEFT 0x27
#define KEY_RIGHT 0x29
#define KEY_HOME 0x2A
#define KEY_UP 0x2B
#define KEY_PGUP 0x2C
#define KEY_INS 0x23
#define KEY_DEL 0x22
```
**‘ª ­-ª®¤ë (¨§ docs/converted/ProgrammerManual.txt:2143-2323):**
| Š« ¢¨è  | scan | Š« ¢¨è  | scan |
|---|---|---|---|
| F1 | 0x0E | Up | 0x2B |
| F10 | 0x17 | Down | 0x25 |
| F11 | 0x18 | Left | 0x27 |
| F12 | 0x19 | Right | 0x29 |
| | | PgUp | 0x2C |
| | | PgDn | 0x26 |
| | | Home | 0x2A |
| | | End | 0x24 |
### —â® **¯¥à¥¨á¯®«ì§ã¥¬** ¨§ áãé¥áâ¢ãî饩 libc
- `open/read/lseek/close` - `libc/io/{open,read,lseek}.c` (POSIX wrappers)
- `mem_alloc_pages/mem_free_block/mem_get_page` - `libc/mem/mem_alloc.c`
- `sprinter_page_w3()` - inline `__sfr` write ¢ `libc/include/sprinter.h:113`
- `bank_read_w3/bank_write_w3` - `libc/mem/bank_io_w3.c` (¤«ï fallback ¨«¨ v2 multi-page)
- `wrchar(x, y, ch, attr)` - `libc/conio/conio.c:476` (¡¥§ auto-scroll, ¨¤¥ «ì­® ¤«ï viewport)
- `clrscr_attr(attr)` - `libc/conio/conio.c:395`
- `gotoxy/wherex/wherey` - `libc/conio/conio.c:412-462` (¥á«¨ ­ã¦­®)
- `kbhit()` - `libc/conio/conio.c:22` (¤«ï non-blocking ®¯à®á , ®¯æ¨®­ «ì­®)
- `dec16/dec8` - `libc/stdio/dec_print.c` (¤«ï status bar: ⥪ãé ï áâப  / total / %)
- `COLOR(fg, bg)` ¬ ªà®á - `libc/include/conio.h:152`
- –¢¥â®¢ë¥ ª®­áâ ­âë `COLOR_*` - `libc/include/conio.h:145`
- `strlen/memcpy/memset` - z80.lib (… ¯¥à¥¯¨á뢠âì)
---
## ‘âàãªâãà  ¨á室­¨ª®¢
```
examples/mdview/
ÃÄÄ Makefile # áâ ­¤ àâ­ë© pattern (á¬. examples/cat/Makefile)
ÃÄÄ mdview.c # Phase 1: ¢áñ ¢ ®¤­®¬ ä ©«¥ (main, keys, indexing, render)
ÃÄÄ SAMPLE.MD # â¥áâ®¢ë© markdown
ÀÄÄ README.md # ®¯¨á ­¨¥ ¨ controls
```
®á«¥ Phase 3 à áª¨¤ âì ¯® ¬®¤ã«ï¬ (¥á«¨ á㬬 à­ë© à §¬¥à > ~6KB):
```
mdview.c - main loop, status/menu bars, key dispatch
mdrender.c - line rendering with MD inline parser
mdindex.c - file load + line indexing
```
### ‘¡®àª 
```makefile
PROJ ?= ../..
SPRINTER_CC := $(PROJ)/bin/sprinter-cc
mdview.exe: mdview.c
$(SPRINTER_CC) --memory small -o $@ mdview.c
```
`--memory small`: ª®¤+¤ ­­ë¥ ¢ W2 (DSS ¤ ñ⠭㦭®¥ ç¨á«® áâà ­¨æ); ä ©« - ®â¤¥«ì­ ï EMM-áâà ­¨æ  ¢ W3.
---
## ‘âàãªâãà  mdview.c (Phase 1, í᪨§)
```c
#include <stdint.h>
#include <stdio.h>
#include <conio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sprinter.h>
#include <sprinter_mem.h>
#define VIEW_TOP 1
#define VIEW_BOT 30 // inclusive
#define VIEW_H 30
#define SCREEN_W 80
#define MAX_LINES 2048
#define FILE_BUF ((char*)0xC000) /* W3 - EMM page mapped here */
#define TAB_STOP 4
#define ATTR_TEXT COLOR(COLOR_WHITE, COLOR_BLACK)
#define ATTR_BAR COLOR(COLOR_WHITE, COLOR_BLUE)
#define ATTR_MENU_K COLOR(COLOR_YELLOW, COLOR_BLUE)
#define ATTR_MENU_T COLOR(COLOR_WHITE, COLOR_BLUE)
static uint16_t line_off[MAX_LINES];
static uint16_t n_lines;
static uint16_t top_line;
static uint16_t file_size;
static uint8_t file_blk;
static char filename[64];
static int load_file(const char *path); // open, alloc EMM page, map W3, read, close
static void index_lines(void); // scan FILE_BUF, fill line_off[]
static void render_status(void); // row 0
static void render_menu(void); // row 31
static void render_line(uint16_t idx, uint8_t row); // one line @ row
static void render_viewport(void); // VIEW_H lines starting from top_line
static void scroll_up(uint16_t n);
static void scroll_down(uint16_t n);
static void help_screen(void); // F1
int main(int argc, char **argv) {
if (argc < 2) { puts("Usage: mdview <file.md>"); return 1; }
if (load_file(argv[1]) < 0) { puts("load error"); return 1; }
index_lines();
clrscr_attr(ATTR_TEXT);
render_menu();
render_status();
render_viewport();
for (;;) {
uint16_t k = getkey();
uint8_t ascii = k & 0xFF;
uint8_t scan = (k >> 8) & 0x7F; // strip mod bit
if (ascii) {
if (ascii == 0x1B) break; // Esc -> exit
continue;
}
switch (scan) {
case KEY_F10: goto exit;
case KEY_F1: help_screen(); break;
case KEY_UP: scroll_up(1); break;
case KEY_DOWN: scroll_down(1); break;
case KEY_PGUP: scroll_up(VIEW_H); break;
case KEY_PGDN: scroll_down(VIEW_H); break;
case KEY_HOME: top_line = 0;
render_viewport(); break;
case KEY_END: /* clamp to last viewport */ break;
}
render_status();
}
exit:
mem_free_block(file_blk);
clrscr_attr(ATTR_TEXT);
return 0;
}
```
---
## Verification
### Phase 1
1. ®¤£®â®¢¨âì `SAMPLE.MD` ~5 KB (§ £®«®¢ª¨,  ¡§ æë, ᯨ᪨) - ७¤¥à¨âìáï ¡ã¤¥â plain.
2. `cd examples/mdview && make`
3. `python make_disk.py mdview.exe SAMPLE.MD -> mc.img && ./run_mame.sh`
4. ஢¥à¨âì:
- Status bar ¯®ª §ë¢ ¥â `SAMPLE.MD L 1-30 / N X%`
- Menu bar ¢­¨§ã
- ^/V: 1 áâப 
- PgUp/PgDn: 30 áâப, ª®à४⭮¥ clamp ­  £à ­¨æ å
- Home: top_line=0
- End: top_line = total_lines - VIEW_H
- F1: ¯®ª §ë¢ ¥â help, «î¡ ï ª« ¢¨è  ¢®§¢à é ¥â
- F10 / Esc: ¢ë室, íªà ­ ®ç¨é¥­
5. Edge cases: ¯ãá⮩ ä ©«, ä ©« ¨§ ®¤­®© áâப¨, ä ©« á ®ç¥­ì ¤«¨­­®© áâப®© (>80), CRLF ¨ LF mixed.
### Phase 2-4
 áè¨àïâì `SAMPLE.MD` á ä¨ç ¬¨ ¯® ¬¥à¥ ¤®¡ ¢«¥­¨ï, ¢¨§ã «ì­® ¢¥à¨ä¨æ¨à®¢ âì ¢ MAME. ‘ªà¨­è®â-áà ¢­¥­¨¥ ®¯æ¨®­ «ì­®.
### ¥£à¥áᨨ
- ¨ª ª¨å ¨§¬¥­¥­¨© ¢ libc ­  Phase 1 ªà®¬¥ (¯®â¥­æ¨ «ì­®) ¤®¡ ¢«¥­¨ï `getkey()` ¢ `libc/conio/conio.c` - ¥á«¨ â ª, ¯à®£­ âì `examples/conio2` ¨ `examples/filetest` ç⮡ë ã¡¥¤¨âìáï çâ® ­¨ç¥£® ­¥ á«®¬ «®áì.
---
## ¥è¥­¨ï ¯® ­¥®¤­®§­ ç­®áâï¬
1. **Word-wrap vs truncate**: v1 = truncate (¯à®áâ®). v2 - F2 toggle wrap.
2. **ƒ®à¨§®­â «ì­ë© áªà®««¨­£**: v1 - ­¥â; v2 - `<-/->` ᤢ¨£ viewport ¯® á⮫¡æ ¬.
3. **Tab handling**: ¯à¥®¡à §®¢ ­¨¥ ¯à¨ ७¤¥à¥, **tabstop = 4** (áâ ­¤ àâ MD). Žà¨£¨­ « ¢ W3 ­¥ âண ¥¬.
4. **UTF-8**: ७¤¥à¨¬ ¡ ©âë ª ª ¥áâì. …᫨ ä ©« ¢ CP866 - ®âà¨áã¥âáï ª¨à¨««¨æ¥© ç¥à¥§ á¨á⥬­ë© ä®­â. UTF-8 - ¯®ª  ­¥ ¯®¤¤¥à¦¨¢ ¥¬ (¢¨§ã «ì­® ¡ã¤¥â ª è  ­  ­¥-ASCII ᨬ¢®« å; ¤¥â¥ªâ ¨ ¯à¥¤ã¯à¥¦¤¥­¨¥ - ¢ v2).
---
### Phase 6 - ®«­ë© layout â ¡«¨æ (deferred)
‘¥©ç á (Phase 4-tables) â ¡«¨æë à¨áãîâáï "¤¥ª®à â¨¢­®" - ¯ ©¯ë ¨ â¨à¥
§ ¬¥­ïîâáï ­  box-drawing chars, ­® è¨à¨­ë ª®«®­®ª ¡¥àãâáï ª ª ¥áâì ¨§
¨á室­¨ª . –¥«ì Phase 6 - ¯¥à¥áç¨â âì â ¡«¨æã ¢ ­®à¬ «¨§®¢ ­­ë© ¢¨¤:
- **Pre-scan â ¡«¨æë**: ¯à®©â¨ ¢á¥ áâப¨ ®¤­®£® table-¡«®ª , ­ ©â¨
¬ ªá¨¬ «ì­ãî è¨à¨­ã ª ¦¤®© ª®«®­ª¨ (á ãçñ⮬ áꥤ¥­­ëå inline-¬ àª¥à®¢ -
¢¨§ã «ì­ë© à §¬¥à, ­¥ ¡ ©â®¢ë©).
- **Re-emit ¢ ¡ãä¥à¥**: ¯à¨ § £à㧪¥ ä ©«  (¨«¨ ¯à¨ ¯¥à¢®© ¢áâà¥ç¥ â ¡«¨æë)
¯¥à¥¯¨á âì áâப¨ ¢ FILE_BUF â ª, çâ®¡ë ¢á¥ ï祩ª¨ ®¤­®© ª®«®­ª¨ ¨¬¥«¨
®¤¨­ ª®¢ãî è¨à¨­ã; ¤®¡ ¢¨âì top/bottom à ¬ª¨ (`ÚÄÂÄ¿` / `ÀÄÁÄÙ`) ª ª
ᨭâ¥â¨ç¥áª¨¥ áâப¨. â® ¯®§¢®«¨â á®åà ­¨âì 1:1 ᮮ⢥âá⢨¥ "«®£¨ç¥áª ï
áâப  -> ®¤­  viewport row" ¡¥§ ᯥ樠«ì­®© «®£¨ª¨ ¯à¨ ७¤¥à¥.
- ** ¬ïâì**: re-emit ¬®¦¥â “‚…‹ˆ—ˆ’œ ä ©« §  áçñâ padding ¨ ¤®¯.à ¬®ª.
…᫨ ¡ãä¥à ¡«¨§®ª ª 16KB - ®â१ âì â ¡«¨æã ¨ ¯®¬¥â¨âì ¥ñ overflow'®¬.
- **ƒ®à¨§®­â «ì­ë© áªà®««¨­£**: ¥á«¨ ¨â®£®¢ ï è¨à¨­  â ¡«¨æë (¨«¨ «î¡®©
áâப¨) > SCREEN_W = 80 - ¤®¡ ¢¨âì <-/-> ¤«ï horizontal pan. â® ¡ã¤¥â
®¡é¨© ¬¥å ­¨§¬ ¤«ï ¤«¨­­ëå áâப (á¬. â ª¦¥ wrap mode), ­¥ ⮫쪮 â ¡«¨æ.
- **‚ëà ¢­¨¢ ­¨¥ ¨§ separator-row**: `:-` -> left, `-:` -> right, `:-:` ->
center; ãç¨â뢠âì ¯à¨ padding'¥ ᮤ¥à¦¨¬®£® ï祩ª¨.
- **˜ £¨ ॠ«¨§ æ¨¨**:
1. Walking pass ¯® 䥭ᠬ/â ¡«¨æ ¬ ¯àאַ ¢ `index_lines()` - ᮡà âì
extents ¢á¥å â ¡«¨æ.
2. „«ï ª ¦¤®© â ¡«¨æë - ®¯à¥¤¥«¨âì è¨à¨­ë ª®«®­®ª.
3. ¥è¥­¨¥: rewrite-in-buffer (¯à®é¥ ¤«ï ७¤¥à , ­® ¬ãâ¨àã¥â ¨á室­¨ª)
vs render-time layout (cleaner, ­® âॡã¥â ®â¤¥«ì­®© áâàãªâãàë
®¯¨á ­¨ï layout'  ­  ª ¦¤ãî â ¡«¨æã).
4. Hpan: ®¡é¨© `viewport_x_offset` ¤«ï ¢á¥£® íªà ­ , ¨«¨ ®â¤¥«ì­ë©
"è¨à®ª¨© ०¨¬" ⮫쪮 ¢­ãâਠ⠡«¨æ.
> ¥ ¡«®ª¨àãîé ï ä¨ç . ‡ ¯ã᪠âì ª®£¤  áâ ­¥â ¯®­ï⥭ ⨯®¢®© ¨áâ®ç­¨ª
> markdown-ä ©«®¢ (㧪¨¥ ç¨â «ª¨ -> ¤®áâ â®ç­® ⥪ã饣® ¤¥ª®à â®à ;
> è¨à®ª¨¥ README á ¡®«ì訬¨ â ¡«¨æ ¬¨ -> ­ã¦¥­ ¯®«­ë© layout).
---
### Phase - Šíè ७¤¥à¥­­ëå áâப (low priority)
Žâ«®¦¥­®: ⥪ãé ï ᪮à®áâì ¡®«¥¥ 祬 ¤®áâ â®ç­ . €ªâ¨¢¨à®¢ âì ¥á«¨ ¯®ï¢¨âáï
áæ¥­ à¨©, £¤¥ ¢¨¤­  § ¤¥à¦ª  PgUp/PgDn (­ ¯à¨¬¥à, ¯à¨ âï¦ñ«®¬ inline-¯ àá¥à¥
v2 á UTF-8 / linkifier / â ¡«¨æ ¬¨).
**Šíè ®âä®à¬ â¨à®¢ ­­ëå áâப** (W3, ®â¤¥«ì­ ï EMM-áâà ­¨æ ):
```
Cache layout (16 KB EMM page, ¢á¥£® 16000 ¡ ©â ¨á¯®«ì§ã¥âáï):
slot 0: 80 chars + 80 attrs = 160 bytes @ offset 0
...
slot 99: 80 chars + 80 attrs = 160 bytes @ offset 15840
Cache tags (W2 static): uint16_t cache_tag[100] = 200 bytes
cache_tag[i] = line_id, ¨«¨ 0xFFFF = invalid
```
‘âà â¥£¨ï - **direct map (no LRU)**: `slot = line_id % 100`. Š®««¨§¨ï -> ¢ëâ¥á­¥­¨¥.
**Batched viewport render**: 2 page-swap'  ­  ‚…‘œ viewport (cache -> file -> cache),
­¥ 60 ª ª ¯à¨ ­ ¨¢­®© ॠ«¨§ æ¨¨.
ਠᡮથ: `cache_blk = mem_alloc_pages(1)` ¯®á«¥ `file_blk`; `mem_free_block` ­  exit.
---
## —â® ®â«®¦¥­® ¢ v2
- ~~” ©«ë >16 KB~~ - **ᤥ« ­® ¢ v1.5** (¤® 128 KB ç¥à¥§ 1-8 EMM-áâà ­¨æ + lazy map ¢ W3).
- ~~Word wrap~~ - **ᤥ« ­®** (Phase 5, F2 toggle).
- Search (Find / Find next) - F3 / F4.
- F8 Raw / Render toggle - ᯥæ¨ä¨ª æ¨ï ¢ Phase 8.
- Links `[text](url)` + image alt - Phase 7.
- Tables - Phase 6 (¯®«­ë© layout).
- Toggle highlight on/off - ç áâ­ë© á«ãç © F8 Raw.