もう5年以上前の話になるのか。PS/55モデル5550-TでDOSを動かした動画を撮影した時、テキスト画面のスクロールはJ-DOSよりDOS/Vの方が早く見えることに気づいた。これは私の中で長年の未解決問題、というと大げさだが、ずっと少し気にはなっていた。最近、DOS/Vのテキストスクロール周りを調べる機会があったので、ついでにこの疑問を解消してみる試み。

テキストスクロールに掛かる時間の比較

まず早い話、テキストスクロールにどれほど時間が掛かるのか。次はDOSVAX上で1000サイクル/ミリ秒の速度にしてDOS J5.0/Vのreadme.txtをTYPEコマンドで最後まで表示するのに掛かった時間。括弧内はDOS/V(/HS=ON)に掛かった時間を1にした比。

PS/55テキスト PS/55モノクロ DOS/V(/HS=ON) DOS/V(/HS=LC) DOS/V(/HS=OFF)
10秒(1.1) 110秒(12.2) 9秒(1) 13秒(1.4) 27秒(3.0)

各列の意味は以下の通り。

  • PS/55テキスト(画面モード8h) : PS/55の24ドットフォント単色文字モード。
  • PS/55モノクロ(画面モードAh) : PS/55の24ドットフォント単色グラフィックモード。
  • DOS/V(/HS=ON) : DOS/V + ハードウェア・スクロール。
  • DOS/V(/HS=LC) : DOS/V + ライン・コンペア・スクロール。
  • DOS/V(/HS=OFF) : DOS/V + ソフトウェア・スクロール。

エミュレーター上で調べた結果ではあるが、この結果は実機でも比はだいたい一致する。

DOS/Vの日本語テキスト表示手法

スクロールの話をする前に、まずDOS/Vのテキスト表示手法について説明しておく。

DOS/VはVGAの16色グラフィックモード(画面モード12H相当)を使用してテキストをグラフィックとして描画している。

Image: VGAビデオメモリー モード12h
(引用元:『OADGテクニカル・リファレンス(ハードウェア)』、PCオープン・アーキテクチャー・推進協議会、2000年)

ビデオメモリーはアドレスA0000hから64KBが割り当てられ、4プレーンが重なっている。読み書きを行うプレーンはグラフィックス・コントローラーのレジスターにて指定し、4プレーン同時書き込みが可能。従って、16×16フォントの全角文字1字を表示するのに必要な書き込みバイト数は、16ビット×16ライン=32バイトとなる。(※実際は文字ボックスの大きさが16×19なので38バイト。)

さらに実際には文字コードを解釈してフォントデータを読み込む処理が入るため、表示に掛かる総時間は単純な計算では求まらない。

まず、DOS/Vの起動時に$FONT.SYSがディスクからフォントデータを読み込み、拡張メモリーへ格納する。$DISP.SYSは画面モードを設定し、基本メモリーに約20KBの仮想的なテキストメモリー(疑似ビデオ・バッファー)を確保する。

Image: DOS/Vのメモリ・マップと表示動作
(引用元:日経バイト 1990年12月号)

DOSやアプリケーションは疑似ビデオバッファーに文字コードを書き込み、BIOSコールで画面更新処理を呼び出す。$DISP.SYSは文字コードに対応するフォントデータを拡張メモリーから基本メモリー内のフォント・バッファーに一時的に転送し、これを実ビデオ・メモリーに転送する。少し回りくどいやり方になっている理由は、DOS上で拡張メモリーにアクセスするにはリアルモード・プロテクトモードの切り替えが必要になるため、先にフォントデータをまとめて基本メモリーに転送している。これは内部的にはBIOSのINT 15h, AH=87hを使用している。プロテクトモードへ切り替えずに拡張メモリーへ高速アクセスする裏技(LOADALL)があるが、これを使用しているかどうかはその機種のBIOS次第ということになる。

DOS/Vのテキストスクロール

DOS/VはIBM純正機だけでなく互換PCでも動くように3種類のテキストスクロール手法が用意されている。

ハードウェア・スクロール (/HS=ON)

VGAの表示開始メモリアドレスと周回特性を利用した手法。

ディスプレイ・コントローラー・レジスターの開始アドレスレジスターを1行(※ここでは水平1ピクセルの走査を1ライン、横1列の文字を1行とする)のメモリーサイズ分だけ加算する。するとメモリー上の表示開始位置が1行分ずれる。

ビデオメモリーは実空間アドレスでA0000hからAFFFFhまでの64KB(×4プレーン)あるが、実際に表示に使うのは画面サイズ640×475(データサイズにして38KB×4)だけ。BIOS(ここでは$DISP.SYS)は26行目となる位置に次に表示する文字を予め書き込んでおき、開始アドレスレジスターを1行分加算する。すると画面上は下から1行分一気に25行目へ出てきたように見せることができる。行送りの度にこれを繰り返し、アドレスAFFFFhまで到達したらA0000hからまた書き込んでいく。

この手法はアドレスがAFFFFhまで行ったらA0000hに周回することが前提となっている。しかし、一部のVGAクローン(主に256KBを超えるビデオメモリーを持つSVGAチップ)はこの周回が機能せず、AFFFFhの境界までスクロールすると画面に空白やゴミが現れることになる。この問題はライン・コンペア・スクロール(後述)によって解決された。

ソフトウェア・スクロール (/HS=OFF)

ビデオメモリー上のデータを1行分上にずらして書き換えていく力業。ただでさえI/O上のメモリーは普通のメモリーよりアクセスが遅いのに、スクロールの度に画面の全領域(DOS/Vなら38KB、PS/55モノクロ画面なら96KB)を書き換えるため非常に遅くなる。

ライン・コンペア・スクロール (/HS=LC)

VGAの表示開始メモリアドレスとライン比較レジスターを使った手法。CONFIG.SYSファイルで$DISP.SYSに/HS=LCスイッチを付けると使用できる。DOS J4.07/V以降でサポート。

ディスプレイ・コントローラー・レジスターのライン比較レジスターは、1画面を描画中に指定したライン数まで達すると表示開始メモリアドレスに関わらずアドレスを0にリセットする機能がある。元々これは画面を上下に2分割して、上画面は表示開始メモリアドレスを変更してスクロールし、下画面は表示開始アドレスが0固定なのでスクロールの影響を受けないという使い方が想定されていたようだが、DOS/Vのスクロールではこれを巧妙に使用している。

ハードウェア・スクロールと同様、表示開始メモリアドレスを1行分ずつ加算してスクロールする。次のラインの開始アドレスがAFFFFhを超えそうな時、ライン比較レジスターをそのライン数に設定し、次のラインのデータはアドレスA0000hからまた順次書き込んでいく。すると画面上は上下が繋がっているように見える。この後は行送りの度にライン比較レジスターを1行分(19ライン)減算し、表示開始メモリアドレスを1行分加算する。分割ラインが画面上の1番上まで行った時は、すなわち表示範囲がメモリ上で周回をまたがなくなったということなので、また表示開始メモリアドレスだけを加算してスクロールしていく。

ハードウェア・スクロールより一手間増えるが、ビデオメモリーの操作量はさほど変わらない。

PS/55のテキストスクロールについては次回。

PS/55のテキストスクロールはDOS/Vよりも遅い? [2]PS/55のテキストスクロール


※コメント欄が表示されない場合はdisqusについてJavascriptが有効であることを確認して下さい。コメントはスパム防止フィルターによる承認制のため、投稿してもすぐに反映されない場合があります。

管理人 : Akamaki (akm)

は、PCとVTuberに夢中になっている電気技術者です。

私はレトロコンピューティングの愛好家ですが、そのようなリグはもう収集していません。

私の活動はトップページで見ることができます。読んでくれてありがとう!