-
Notifications
You must be signed in to change notification settings - Fork 2
Escape Sequences
DOS の画面出力(INT 21h の AH=0x02 や AH=0x09)には、
画面制御のためのエスケープシーケンスが解釈されます。
テキスト VRAM へ直接書き込む方法と違い、カーソル位置や属性を DOS 側の管理と
食い違わせずに画面を操作できます。
このページの内容は FreeDOS(98) と NEC MS-DOS 6.20 の両方で実測しています。
ESC(0x1B)に続けて [ と引数を並べます。AH=0x02(1文字出力)で
1バイトずつ送っても、AH=0x09($ 終端の文字列出力)でまとめて送っても解釈されます。
| シーケンス | 働き |
|---|---|
ESC [ 行 ; 桁 H |
カーソルを移動する(1始まり) |
ESC [ s |
カーソル位置を退避する |
ESC [ u |
退避した位置へ戻す |
ESC [ > 5 h |
カーソルを消す |
ESC [ > 5 l |
カーソルを表示する |
相対的に動かすこともできます。
| シーケンス | 働き |
|---|---|
ESC [ n A |
上へ n 行 |
ESC [ n B |
下へ n 行 |
ESC [ n C |
右へ n 桁 |
ESC [ n D |
左へ n 桁 |
ESC D |
1行下へ(桁はそのまま) |
ESC E |
1行下の左端へ |
ESC M |
1行上へ |
数字を省くと 1 として扱われます。
| シーケンス | 働き |
|---|---|
ESC [ 0 K |
カーソル位置から行の右端まで |
ESC [ 1 K |
行の左端からカーソル位置まで |
ESC [ 2 K |
行全体 |
ESC [ 0 J |
カーソル位置から最終行まで |
ESC [ 1 J |
先頭からカーソル位置まで |
ESC [ 2 J |
画面全体(カーソルは左上へ) |
K は行の中だけ、J は画面の範囲、と覚えると間違えにくいです。
どちらも 0 は「カーソルから後ろ」、1 は「カーソルまで」です。
| シーケンス | 働き |
|---|---|
ESC [ n L |
カーソル行に n 行挿入する(以降は下へ) |
ESC [ n M |
カーソル行から n 行削除する(以降は上へ詰まる) |
一覧の書き換えなど、行単位の編集に使えます。
ESC [ 数字 m で、以降に表示する文字の見た目が変わります。
| 値 | 色 |
|---|---|
| 30 | 黒 |
| 31 | 赤 |
| 32 | 緑 |
| 33 | 黄 |
| 34 | 青 |
| 35 | 紫 |
| 36 | 水色 |
| 37 | 白 |
| 値 | 働き |
|---|---|
| 0 | 既定に戻す |
| 2 | 縦線を引く |
| 4 | 下線を引く |
| 5 | 点滅させる |
| 7 | 反転 |
| 8 | 文字を隠す(何も表示されない) |
| 1 | ハイライト。カラーでは効きません(モノクロ専用) |
40〜47 は 地の色です(30〜37 は文字の色)。番号の並びは同じで、
41 なら地が赤になります。
ESC [ 0 m で戻すのを忘れないでください。 属性は変更するまで続きます。
| シーケンス | 働き |
|---|---|
ESC [ > 1 h |
最下行(25行目)を使えるようにする |
ESC [ > 1 l |
最下行をファンクションキー表示に戻す |
ESC [ > 3 h |
画面を 20行にする |
ESC [ > 3 l |
画面を 25行にする |
行数の切り替えは INT 18h の AH=0x0A でもできます(→ テキスト VRAM)。
実測ではどちらの方法でも同じ結果になりました。
既定では 25 行目にファンクションキーの表示が出ていて、そのままでは使えません。
ESC [ > 1 h を送るとこの表示が消え、25 行目へ書けるようになります。
ESC [ > 1 l で元に戻せます。 解放 → 書き込み → 復帰 → 再度解放、まで確認しています。
常駐プログラムが終了するときに戻しておくと、画面が元の状態に片付きます。
常駐プログラムのステータス行などに使えます。実測では、ESC [ > 1 h の後に
ESC [ 25 ; 1 H で移動して書き込むと、ファンクションキー表示が消えて
その内容が表示されました。24 行目と 25 行目へ別々の文字列を書き、
取り違えでないことも確認しています。
mov dx, statusline
mov ah, 0x09
int 0x21
statusline:
db 0x1B,'[s' ; カーソル位置を退避
db 0x1B,'[>1h' ; 最下行を解放
db 0x1B,'[25;1H' ; 25行1桁へ
db 0x1B,'[7m' ; 反転
db 'STATUS'
db 0x1B,'[0m' ; 属性を戻す
db 0x1B,'[u' ; カーソル位置を復元
db '$'| シーケンス | 働き |
|---|---|
ESC ) 0 |
漢字を扱うモード(システムの既定) |
ESC ) 3 |
グラフ文字を扱うモード |
ESC ) 3 にすると、全角文字が扱えなくなります。
2バイトが結合されず、1バイトずつ別の文字になります。
実測では、全角「亜」のバイト列を出力したとき、
- 既定(
ESC ) 0)→ 全角1文字として表示 -
ESC ) 3→ 半角2文字に分かれる
戻し忘れると、以降の日本語がすべて壊れます。 使ったら ESC ) 0 で戻してください。
出力側では 0x80〜0x9F は破棄されません。 全角文字の第1バイトは
この範囲に入るものが多いのですが、AH=0x02 で1バイトずつ送っても、
AH=0x09 でまとめて送っても、そのまま画面に出ます。
FreeDOS(98) と NEC MS-DOS 6.20 の両方で、テキスト VRAM 上の JIS コードが 1つ残らず一致しました。
入力側の話と混同しないでください。 「CON が 0x80〜0x9F を捨てる」という
挙動は入力側のもので、出力側には当てはまりません。
INT 21h をフックした常駐プログラムのハンドラの中からでも、
エスケープシーケンスと全角の出力ができます。呼び出し元のカーソル状態も、
ESC [ s と ESC [ u で挟めば壊れません。
ただしハンドラの中から INT 21h を呼んではいけません。 自分のハンドラに
再入します。退避しておいた元のベクタを pushf + call far で直接呼んでください。
-
行と桁を 0 から数える。
ESC [ 行 ; 桁 Hは 1 始まりです。 -
ESC [ 0 JとESC [ 0 Kを取り違える。Kは行の中だけ、Jは画面の範囲です。 -
属性を戻し忘れる。
ESC [ 0 mを送るまで、以降の文字すべてに効き続けます。 -
最下行を解放したまま終了する。
ESC [ > 1 lで戻せます。 -
ESC ) 3から戻し忘れる。 以降の日本語が1バイトずつに分かれます。 -
1(ハイライト)で目立たせようとする。 カラーでは効きません。7(反転)を使ってください。 -
30〜37と40〜47を取り違える。 前者が文字、後者が地の色です。 -
ESC [ > 1 hを送らずに 25 行目へ書く。 ファンクションキーの表示が出たままで、 書いた内容が見えません。 -
ハンドラの中で
int 21hを呼ぶ。 自分のハンドラに再入して戻ってきません。 -
出力側でも
0x80〜0x9Fが消えると思い込む。 消えません。
現時点で確認できているものはありません。 ただし 測定はすべて np2kai 上で行っています。 実機での確認は行っていません。
- カーソル位置の問い合わせ(
ESC [ 6 n)。BIOS のキーバッファには入りませんでした。 DOS の入力を経由して受け取るものと思われますが、確認できていません - 31行モード(ハイレゾ専用のため、この環境では試せません)
- キーボードへの文字列割り当て
検証: 2026-08-24 / WebNP2 (np2kai) / FreeDOS(98) と NEC MS-DOS 6.20 の両方 /
再現: guest/probes/ESCT1.ASM, ESCT2.ASM, GIO4.ASM(任意のシーケンスを流す橋)
テキスト画面
キーボード
グラフィック画面
時間と割り込み
BIOS / DOS
ディスク
サウンド
メモリ