このエントリーをはてなブックマークに追加
スポンサーリンク

エスケープシーケンス

エスケープシーケンス

PC-9801はJ-3100やDOS/Vと異なり、BIOSが貧弱でI/Oポートの操作も複雑極まりないです。したがって、テキストV-RAMをアセンブラからまっとうに操作しようとすると、非常に煩雑なプログラミングを必要とします。

しかしながら、一太郎やロータス123のような市販パッケージや、ゲームを作りた場合を除き、ごく普通の業務ソフトを作る場合には高速処理はさほど必要はないでしょう。

そこで、できる限りMS-DOSのAPIを利用します。高速描画を必要としないケースでは、エスケープシーケンスを使ってテキストを表示させる方法がオススメです。PC-9801の場合は、DOS/Vとは異なりANSI.SYSを組み込まなくともデフォルトでエスケープシーケンスを使う事ができます。使い方は簡単で、MS-DOS割り込み(INT 21H)を使って、ESC(1BH)に続いて既定のエスケープシーケンスを表示させるだけです。

エスケープシーケンスの種類

エスケープシーケンスには以下のものがあります。
エスケープシーケンス 意味
ESC [ Pl ; Pc H カーソルをPl行Pc桁へ移動
ESC [nA カーソルをn行上に移動
ESC [nB カーソルをn行下に移動
ESC [0J カーソル位置から右下(80,25)までクリア
ESC [1J 左上(1,1)からカーソル位置までクリア
ESC [2J 画面全消去
ESC [2K カーソルのある行の文字を全てクリア
ESC [>5h カーソルを非表示にする
ESC [>5l カーソルを表示する
ESC [s カーソル位置と現在位置の属性をセーブ
ESC [u ESC [sでセーブした位置にカーソル位置と属性を戻す
ESC [ Ps ; …… ; Ps m 属性の設定 psはセミコロンで区切って複数指定可

また、MS-DOS割り込みには以下のものがあります。
レジスタ 意味
AH 02H
DL 出力文字
DLレジスタにセットした1バイトを表示します。
AH 09H
DS:DX 出力文字列
DS:DXにセットした文字列を$が来るまで表示します。

固定のメッセージを出す場合はAH=09Hの方が扱いが楽なのですが、ユーザーが入力した文字を表示させたり、ファイルから読み込んだ文字列を表示させる場合などは、文字列中に$が含まれている可能性があるので、自前でAH=02Hを使ってループ処理で文字列表示ルーチンを作った方が良いでしょう。

例)文字列の表示(DS:SIに文字列、CXに文字数)
;=============================================================================
;		文字列の表示
;=============================================================================
DISPLAY		=	$
		MOV	AH,2
		MOV	DL,[SI]
		INT	21H
		ADD	SI,1
		LOOP	DISPLAY
		RET

カーソル位置の指定

カーソルの位置の指定は、CUIであるMS-DOS(オフコンじゃないぞ)アプリではほぼ必須でしょう。テキストV-RAMを直接操作する方法だと、オフセット値を計算するのが面倒ですが、エスケープシーケンスを使う方法では簡単です。表示させたい文字列の前に、

1BH 5BH (ライン) 3BH (カラム) 48H

を表示させれば良いわけです。ラインとカラムはキャラクターコードで指定します。例えば0なら30H、10なら31H30Hです。

属性の指定

属性の指定は、テキストV-RAMを直接操作する方法だと、オフセット値を計算するのが面倒だったのですが、エスケープシーケンスを使う方法では簡単です。表示させたい文字の前に、

1BH 5BH (属性コード) 3BH (属性コード) 3BH …… 6DH

を表示させれば良いわけです。属性コードには以下のものがあります。
属性コード 意味
0 属性をクリア
1 明るくする
2 バーティカルライン
4 アンダーライン
5 点滅
7 反転
30
31
32 黄色
33
34
35 マゼンダ
36 シアン
37
40 黒反転
41 赤反転
42 緑反転
43 黄色反転
44 青反転
45 マゼンダ反転
46 シアン反転
47 白反転
属性コードはキャラクターコードで指定します。たとえば、30は33H、30Hという風に出力します。

ただし、これはあくまでMS-DOS汎用のコードであり、機種によって以下の制約を受けます。

[属性コード1]明るくする
・PC-9801ではもともと明るいし、テキスト画面の属性に「暗い」というのがないので、属性をクリアしても暗くはなりません。
・J-3100のモノクロモードでは「明るい」属性にすると網掛けになってしまいますので、明るい属性にしない方が良いです。 それで困るのが、J-3100のカラーモードやVGAモードだと、逆に明るくしないと暗くて非常に見づらくなってしまうという点です。そこで、J-3100では 現在の画面モードを判別して、モノクロなら暗いまま、カラーモードやVGAモードなら明るくするといった関数が必要になります。

[属性コード2]バーティカルライン
・J-3100やDOS/V(VGAモード)にはバーティカルラインという属性はありません。

[属性コード4]アンダーライン
・J-3100のカラーモードにはありません。

[属性コード5]点滅
・J-3100やDOS/V(VGAモード)には点滅という属性はありません。

[属性コード30〜47]色指定
・J-3100のモノクロモードでは無効です。
・45;37のように指定すると、マゼンダの背景に白い文字になります。

・・・で合ってます?タイプミス、資料の写しミスでどっかズレとる((C)音吉)かもしれませんが、おかしいと思ったら自分で検証してみるか、他の文献もあたってみてください。

カーソルを消す

直接テキストV-RAMを操作する場合には気にならない事なのですが、エスケープシーケンスでカーソル移動+文字表示を繰り返していると、都度カーソルが飛び交っているのが見えてカッコ悪いです。

そこで一通りテキストの描画を行っている間はカーソルを消します。
ESC [>5h
1BH 5BH 3EH 35H 68H

描画が終わったらカーソルを表示させます。
ESC [>5l
1BH 5BH 3EH 35H 6CH

参考文献
『PC‐9801スーパーテクニック』 1992年 小高輝真、清水和文、速水祐 著 アスキー
『J-3100解析ハンドブック』 1989年 土屋勝著 ナツメ社
『DOS/Vテクニカル・リファレンス・マニュアル』 1993年 芦達剛著 ソフトバンク
スポンサーリンク