HelloSun commited on
Commit
b1ed896
·
verified ·
1 Parent(s): 09ade96

Build and deploy 小貓中文 DOS demo

Browse files
Files changed (7) hide show
  1. README.md +14 -8
  2. XIAOMAO.img +0 -3
  3. dos.b64.js +0 -0
  4. dos.zip +0 -0
  5. index.html +17 -6
  6. wdosbox.js +0 -0
  7. wdosbox.wasm.js +0 -0
README.md CHANGED
@@ -8,16 +8,22 @@ sdk: static
8
 
9
  # 小貓中文 DOS 6.22
10
 
11
- 「小貓中文」是在瀏覽器執行的 DOS 6.22 注音中文系統示範。DOSBox 由 js-dos 6.22 提供;字型使用 GNU Unifont,詞庫由開放資料產生。
12
 
13
- ## 操作方式
 
 
 
 
 
 
14
 
15
- - 點選 DOS 畫面後使用實體鍵盤,或用畫面下方的虛擬鍵盤。
16
- - `Ctrl+Space` 切換注音/英文輸入。
17
- - 注音採相容倚天鍵位;輸入音節後按空白鍵選字,按 `1`–`9` 選候選字。
18
- - `F1` 查看系統資訊;`Alt+X` 離開。
19
 
20
- 啟動時會顯示 DOS 狀態列中的傳統記憶體用量,目標為保留 600KB 以上。
 
 
 
21
 
22
  ## 本機建置
23
 
@@ -29,7 +35,7 @@ HF_TOKEN=hf_... ./build.sh
29
 
30
  若未設定 `HF_TOKEN`,腳本會產生本機發佈檔但略過 Hugging Face 上傳。可用 `DOS_BASE_IMAGE=/path/to/boot.img` 指定其他基底映像。上傳目標為 `HelloSun/c_dos`,token 僅從環境讀取,不寫入專案。
31
 
32
- `dist/dos.zip` 內含 `XIAOMAO.img`,供頁面中的 js-dos 啟動;`dist/XIAOMAO.img` 可直接用於本機測試。
33
 
34
  ## 授權與來源
35
 
 
8
 
9
  # 小貓中文 DOS 6.22
10
 
11
+ 「小貓中文」是 DOS 常駐(TSR)的 Big5 中文顯示與注音輸入外掛,在瀏覽器的 js-dos 6.22 上執行;字型使用 GNU Unifont,詞庫由開放資料產生。載入後回到一般 DOS 提示字元,DOS 指令照常使用,並可直接輸入、顯示中文。
12
 
13
+ ## 運作方式
14
+
15
+ - `XIAOMAO.EXE` 常駐約 10 KB 傳統記憶體(可用 `LH` 載入高記憶體);字型與詞庫放在 XMS(需要 `HIMEM.SYS`)。
16
+ - 載入時(及再次執行 `XIAOMAO`)才顯示常駐大小、可用傳統記憶體與 XMS(即時 MEM),沒有狀態列。
17
+ - 顯示:攔截 INT 29h,遇到 Big5 雙位元組時,把 16×16 字形拆成兩個 8×16 字塊寫入 VGA 字型,再用原本的 INT 29h 輸出,游標、換行與捲動由 DOS 處理。80×25 文字模式,切為 8 點寬字元。
18
+ - 輸入:攔截 INT 16h。`Ctrl+Space` 切換注音/英數;注音選字列顯示於畫面最底列,用完即還原。`Backspace` 一次刪一個中文字。
19
+ - INT 2Fh `AX=D7A0h` 防止重複載入。
20
 
21
+ ## 操作方式
 
 
 
22
 
23
+ - 點選 DOS 畫面後使用實體鍵盤,或用畫面下方的虛擬鍵盤(含 Shift、`\`、`:`、Tab)。
24
+ - `Ctrl+Space` 切換注音/英數(網頁上有按鈕)。
25
+ - 注音採倚天鍵位;輸入音節後按聲調鍵(`6 3 4 7`)或空白鍵出候選字,按 `1`–`9` 或空白鍵選字。
26
+ - 試用:`TYPE DEMO.TXT`。限制:直接寫入顯示記憶體的程式不會顯示中文。
27
 
28
  ## 本機建置
29
 
 
35
 
36
  若未設定 `HF_TOKEN`,腳本會產生本機發佈檔但略過 Hugging Face 上傳。可用 `DOS_BASE_IMAGE=/path/to/boot.img` 指定其他基底映像。上傳目標為 `HelloSun/c_dos`,token 僅從環境讀取,不寫入專案。
37
 
38
+ HF 靜態 Space 以無 CORS 的重新導向提供二進位檔,因此開機映像以 base64 文字放在 `dist/dos.b64.js`,頁面載入後轉為 Blob 交給 js-dos;DOSBox 核心(`wdosbox.js`)取自 js-dos.com。
39
 
40
  ## 授權與來源
41
 
XIAOMAO.img DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:4ad1f23262b00f3d36bd27dca929d207f5fee3500c294d9413a5e5d684411b89
3
- size 1474560
 
 
 
 
dos.b64.js ADDED
The diff for this file is too large to render. See raw diff
 
dos.zip DELETED
Binary file (131 Bytes)
 
index.html CHANGED
@@ -39,7 +39,7 @@
39
  <body>
40
  <header>
41
  <strong>小貓中文 DOS 6.22</strong>
42
- <span id="memory">DOS 啟動後顯示可用傳統記憶體</span>
43
  </header>
44
  <main>
45
  <div id="screen-wrap"><canvas id="dosbox" width="640" height="480" aria-label="DOS emulator screen"></canvas></div>
@@ -59,11 +59,13 @@
59
  <button type="button" data-key="76">L ㄠ</button><button type="button" data-key="190">. ㄡ</button><button type="button" data-key="48">0 ㄢ</button><button type="button" data-key="80">P ㄣ</button><button type="button" data-key="186">; ㄤ</button><button type="button" data-key="191">/ ㄥ</button>
60
  <button type="button" data-key="189">- ㄦ</button><button type="button" data-key="54">6 ˊ</button><button type="button" data-key="51">3 ˇ</button><button type="button" data-key="52">4 ˋ</button><button type="button" data-key="55">7 ˙</button><button type="button" data-key="8">⌫</button>
61
  <button type="button" data-key="27">Esc</button><button type="button" data-key="13">Enter</button><button type="button" data-key="32" class="wide">Space</button><button type="button" data-key="37">←</button><button type="button" data-key="38">↑</button><button type="button" data-key="39">→</button><button type="button" data-key="40">↓</button>
 
62
  <button type="button" data-key="112">F1</button><button id="alt-x" type="button" class="wide">Alt+X</button>
63
  </section>
64
  </main>
65
- <footer>小貓中文 GPL-3.0 · OpenWatcom · GNU Unifont · Big5 注音 · 保留 600KB 以上傳統記憶體 · <a href="LICENSE">License</a></footer>
66
  <script src="js-dos.js"></script>
 
67
  <script>
68
  (() => {
69
  const status = document.getElementById('message');
@@ -79,6 +81,9 @@
79
  send(code, true);
80
  window.setTimeout(() => send(code, false), 90);
81
  };
 
 
 
82
  const toggleIme = () => {
83
  send(17, true);
84
  tap(32);
@@ -94,7 +99,11 @@
94
  button.addEventListener('pointerdown', (event) => {
95
  event.preventDefault();
96
  const code = Number(button.dataset.key);
97
- tap(code);
 
 
 
 
98
  button.classList.add('active');
99
  });
100
  button.addEventListener('pointerup', () => button.classList.remove('active'));
@@ -138,14 +147,16 @@
138
  if (typeof Dos !== 'function') { status.textContent = 'js-dos 核心載入失敗'; return; }
139
  Dos(host, { wdosboxUrl: 'https://js-dos.com/6.22/current/wdosbox.js' }).ready((fs, main) => {
140
  status.textContent = '正在載入 DOS 開機磁碟…';
141
- fs.extract('dos.zip', '/').then(() => main(['-c', 'boot XIAOMAO.img']))
 
 
 
142
  .then((ci) => {
143
  controller = ci;
144
  window.etController = ci;
145
  canvas.tabIndex = 0;
146
  status.textContent = 'DOS 6.22 已啟動;點選畫面輸入';
147
- memory.textContent = '小貓中文 · js-dos 6.22';
148
- })
149
  .catch((error) => { status.textContent = '啟動失敗:' + (error.message || error); });
150
  });
151
  })();
 
39
  <body>
40
  <header>
41
  <strong>小貓中文 DOS 6.22</strong>
42
+ <span id="memory">載入時於 DOS 畫面顯示即時 MEM</span>
43
  </header>
44
  <main>
45
  <div id="screen-wrap"><canvas id="dosbox" width="640" height="480" aria-label="DOS emulator screen"></canvas></div>
 
59
  <button type="button" data-key="76">L ㄠ</button><button type="button" data-key="190">. ㄡ</button><button type="button" data-key="48">0 ㄢ</button><button type="button" data-key="80">P ㄣ</button><button type="button" data-key="186">; ㄤ</button><button type="button" data-key="191">/ ㄥ</button>
60
  <button type="button" data-key="189">- ㄦ</button><button type="button" data-key="54">6 ˊ</button><button type="button" data-key="51">3 ˇ</button><button type="button" data-key="52">4 ˋ</button><button type="button" data-key="55">7 ˙</button><button type="button" data-key="8">⌫</button>
61
  <button type="button" data-key="27">Esc</button><button type="button" data-key="13">Enter</button><button type="button" data-key="32" class="wide">Space</button><button type="button" data-key="37">←</button><button type="button" data-key="38">↑</button><button type="button" data-key="39">→</button><button type="button" data-key="40">↓</button>
62
+ <button type="button" data-key="220">\</button><button type="button" data-key="186" data-shift="1">:</button><button type="button" data-key="9">Tab</button><button id="shift" type="button">Shift</button>
63
  <button type="button" data-key="112">F1</button><button id="alt-x" type="button" class="wide">Alt+X</button>
64
  </section>
65
  </main>
66
+ <footer>小貓中文 GPL-3.0 · OpenWatcom · GNU Unifont · Big5 注音 · 載入時顯示即時 MEM · <a href="LICENSE">License</a></footer>
67
  <script src="js-dos.js"></script>
68
+ <script src="dos.b64.js"></script>
69
  <script>
70
  (() => {
71
  const status = document.getElementById('message');
 
81
  send(code, true);
82
  window.setTimeout(() => send(code, false), 90);
83
  };
84
+ let shiftOn = false;
85
+ const setShift = (on) => { shiftOn = on; document.getElementById('shift').classList.toggle('active', on); };
86
+ document.getElementById('shift').addEventListener('click', () => setShift(!shiftOn));
87
  const toggleIme = () => {
88
  send(17, true);
89
  tap(32);
 
99
  button.addEventListener('pointerdown', (event) => {
100
  event.preventDefault();
101
  const code = Number(button.dataset.key);
102
+ if (button.dataset.shift || shiftOn) {
103
+ send(16, true);
104
+ window.setTimeout(() => { tap(code); window.setTimeout(() => send(16, false), 130); }, 40);
105
+ setShift(false);
106
+ } else tap(code);
107
  button.classList.add('active');
108
  });
109
  button.addEventListener('pointerup', () => button.classList.remove('active'));
 
147
  if (typeof Dos !== 'function') { status.textContent = 'js-dos 核心載入失敗'; return; }
148
  Dos(host, { wdosboxUrl: 'https://js-dos.com/6.22/current/wdosbox.js' }).ready((fs, main) => {
149
  status.textContent = '正在載入 DOS 開機磁碟…';
150
+ if (!window.XIAOMAO_B64) { status.textContent = '啟動失敗:dos.b64.js'; return; }
151
+ const bin = Uint8Array.from(atob(window.XIAOMAO_B64), (c) => c.charCodeAt(0));
152
+ const zipUrl = URL.createObjectURL(new Blob([bin], { type: 'application/zip' }));
153
+ fs.extract(zipUrl, '/').then(() => main(['-c', 'boot XIAOMAO.img']))
154
  .then((ci) => {
155
  controller = ci;
156
  window.etController = ci;
157
  canvas.tabIndex = 0;
158
  status.textContent = 'DOS 6.22 已啟動;點選畫面輸入';
159
+ })
 
160
  .catch((error) => { status.textContent = '啟動失敗:' + (error.message || error); });
161
  });
162
  })();
wdosbox.js DELETED
The diff for this file is too large to render. See raw diff
 
wdosbox.wasm.js DELETED
Binary file (132 Bytes)