Download dev/HANDOFF.md from HelloSun/c_dos: direct link, hf CLI and curl.
- Browser
- Download file 6.93 kB
-
https://huggingface.co/spaces/HelloSun/c_dos/resolve/main/dev/HANDOFF.md
- Command line
-
hf download hf://spaces/HelloSun/c_dos/dev/HANDOFF.md
-
curl -L -o HANDOFF.md https://huggingface.co/spaces/HelloSun/c_dos/resolve/main/dev/HANDOFF.md
小貓中文 — 接手說明 (HANDOFF)
目標:DOS 常駐 (TSR) Big5 中文顯示 + 注音輸入,跑在 js-dos 6.22(瀏覽器/手機),部署為 HF static Space。 傳統記憶體越少越好(現況常駐約 16 KB,不強制 600K)。授權 GPL-3.0-only + GPLv3 §7(b) 附加條款(保留作者 HelloSun,見 LICENSE)。全部元件開源,不含專有軟體。
作者聲明規則(修改時務必遵守)
- 作者 HelloSun、首版 v1.0 / 2026-10-25、版權 Copyright (C) 2026 HelloSun 出現在:每個原始檔檔頭、
LICENSE、NOTICE.md、README.md、index.html頁尾、 以及src/xiaomao.c的report()(M6,程式每次載入都會顯示)。不得移除(GPLv3 §7(b));加入自己的修改請另加自己的名字並註明為修改版。 - 作者資訊由
apply_notice.py的三個常數產生過;改版本或日期時,請連同上述所有位置一起更新。
一鍵流程
HF_TOKEN=... HF_SPACE=user/space ./build.sh(兩者是腳本開頭變數,token 不入檔)。空目錄也能跑:自動建 Python venv、下載並以雜湊驗證
Open Watcom 1.9、JWasm+HimemX 原始碼(現場編成 HIMEMX.EXE)、GNU Unifont、FreeDOS 1.4 Floppy、js-dos 6.22.60(npm),再產生字型/詞庫、編譯、組開機片、產生 dist/、上傳。
主機需求:bash gcc make nasm mtools unzip curl gzip python3(venv)。快取在 .cache/,工具在 .build/(皆 .gitignore)。
現況(已驗證)
- FreeDOS 開機 →
FDCONFIG.SYS載 HIMEMX →FDAUTO.BAT載 XIAOMAO.EXE → 回到A:\>;顯示 MEM;Ctrl+Space注音;候選列在最底列;Backspace 刪整個中文字。 - 手機尺寸(390x844)+觸控虛擬鍵盤驗證過;DOSBox 核心與開機片都自架,不依賴外部 CDN。
架構(傳統「中文系統」作法:文字影子 + 繪圖顯示)
src/xiaomao.c:TSR。video_service(INT10 文字模式 BIOS 模擬)、refresh(渲染器)、key_service(INT16 + 注音)、載入器main。src/xms.asm(NASM OMF):XMS 包裝、INT10/16/2F 掛勾(私有 2 KB 堆疊在 _TEXT,SS=CS;INT10 掛勾把暫存器框架以遠指標交給 C)、bios10_call、get_rom_font(INT10 AX=1130h)、cpu_idle。 helper 只能改 AX;Watcom 暫存器呼叫 AX,DX,BX,CX(第二參數在 DX);large model 用retf;符號後綴_。- 顯示:BIOS 模式 12h(640x480x16),CRTC 垂直顯示結束改 399(只顯示 400 線=25 列x16)。程式眼中仍是模式 3:BDA(0040:xx)被改寫成模式 3/80 欄/25 列。
影子文字在
B800:0000;畫面像素在平面偏移 0000-7CFF,經 A000 視窗寫入。渲染器每 tick(INT16 輪詢、阻塞前強制)逐列比對影子與「已繪副本」(B800:6000字元/屬性、B800:7000種類),只重畫變動的格子。 Big5 偵測:前導 A1-F9 + 後隨 40-7E/A1-FE(Ctrl+\可關);漢字 16x16 由 XMS 取(64 項快取),ASCII 用 ROM 字型。游標以底線疊畫,BDA/CRTC 游標暫存器皆會同步。 - DOSBox 的 VGA 陷阱(都已實測,別再踩):
- 模式 12h 下
B800不是 RAM;GC 雜項暫存器(GC6) map=3(B8000) 會讓 DOSBox 變成 CGA 模式。 - 解法:GC6=0x01(A0000 起 128KB 視窗)。此時
B800:0000對應平面偏移 0x8000(寫入 map mask=0Fh、讀 plane 0,行為如 RAM),與 A000 低 32 KB 的畫面互不重疊,且完全不需切換視窗。 - 寫模式 2 的背景填色在 DOSBox 無效;改用寫模式 0 + Set/Reset(GC0=色、GC1=0F、GC8=位元遮罩)。
- 部分遮罩寫入前必須「真的讀一次」同位址以載入 latch(用 volatile sink 變數,否則編譯器會丟掉讀取,未遮罩位元會帶入垃圾)。
- 畫完一列必須還原 GC1=0、GC8=FF、GC0=0,否則程式之後寫 B800 會被 Set/Reset 污染。
- 模式 12h 下
- 輸入:INT16 AH=0/1/0x10/0x11 掛勾 → IME 狀態機 → Big5 兩位元組入 16 字佇列。BS 加倍(一次退兩格)只在 DOS 內部讀鍵時(InDOS≠0)啟用,直接呼叫 INT16 的程式(PE2/XEDIT)收到單一 BS。
- 資料:
FONT.DAT("ETNF" 18 byte 頭, ASCII 256x16, CJK 32 byte/字, 索引 (lead-0xA1)157+trail索引) 與IME.DAT("ETNI", 12 byte 頭, 5 byte 記錄 key/offset/count),載入 XMS。 key=(((ini4+med)*14+fin)*5+tone);XMS 搬移長度必須為偶數;XMS 只在安全點(INT16/INT10 內)呼叫,不在計時器 ISR。 - 常駐大小:build.sh 兩階段編譯,由連結 map 的 STACK 段位址 +0x10 得
TSR_PARAS;init 用大緩衝(含 4000 B 舊畫面)放堆疊(-k10240,不常駐)。 - 防重複載入 INT2F AX=D7A0h→584Dh;再次執行 XIAOMAO 只顯示 MEM。
- 附加軟體:
src/addons/xedit.c(PE2 風格直接寫 B800 的編輯器,用來驗證直接寫顯示記憶體相容性)。 - 網頁:
index.html(含「示範 Demo」:runDemo()以controller.simulateKeyEvent送鍵,step(字幕, 閱讀停留ms, 動作);SPEED=4倍速:按鍵間隔約 160 ms(下限 50 ms,DOS 需要)、字幕停留約 0.6–1.6 s,全程約 40 秒)。HF 對二進位檔回 302 無 CORS,所以emu.b64.js(wdosbox.js+wasm 的 base64) 與dos.b64.js(開機片 zip 的 base64) 以 Blob URL 供 js-dos; monkeypatchXMLHttpRequest.prototype.open把wdosbox.js/wdosbox.wasm.js對應到 Blob URL(js-dos 以.js→.wasm.js推導 wasm 檔名)。 - FreeDOS 開機片:取 FD14
144m/x86BOOT.img,刪除安裝用檔,換dos/FDCONFIG.SYS、dos/FDAUTO.BAT(CRLF 由 build.sh 轉)。FreeDOS 主控台輸出經 INT 10h TTY(已驗證)。
編譯注意
Open Watcom 1.9:wcl -bt=dos -ml -0 -os -s -zu -k6144(-s 必要:私有堆疊上不可堆疊檢查)。無 _AX 偽暫存器;_psp 需自行 extern unsigned _psp;。
測試方式
無本機 DOS 模擬器:python3 tests/smoke.py --dist dist --chromium <chrome>(Playwright,截圖到 /tmp/xm-shots,只做粗略像素斷言;請人工看截圖)。
自己寫測試 EXE 時:用 build 裡的 Open Watcom 編譯,放進映像(參考 build.sh 的組映像段),改 dos/FDAUTO.BAT 即可。
Chromium 旗標:--no-sandbox --disable-gpu --disable-dev-shm-usage。截圖檔寫入有延遲,讀檔前稍等。
已知限制 / 待辦
- 不支援程式直接改 CRTC/VGA 暫存器做文字特效(游標暫存器除外)、載入文字模式字型、閃爍屬性。
- 渲染為 tick 驅動(約 18 fps);可考慮在 INT10 寫入後立即小範圍重畫,或重新程式化 PIT 提高更新率。
- 輸入法只有注音(候選字已可分頁,每音最多 63 個);無詞組/聯想;可加倚天/倉頡/大易。
- Big5 與 CP437 畫框字元衝突只能用
Ctrl+\手動切換;可加自動偵測。 - 可加 JEMM386/UMB 讓 TSR 載入高記憶體(現約 15 KB 傳統記憶體)。
- 自動化測試只有 smoke test;可加截圖比對基準。