終わった仕事にしたつもりが、まだ終わっていなかった。5550には24ドットフォントのモデル(フォント24)と16ドットフォントのモデル(フォント16)があり、フォント16は5550特有の変わった画面モードを持っているので、これをエミュに追加できないかと考えていた。仕組みが分かってしまえば実装は簡単なんだけど、そこにたどり着くまでに大変だった。
IBMの16ドットフォントというとDOS/Vを思い浮かべるが、5550のフォント16はそれとはいくつか異なる点がある。まず、表示方法の違い。DOS/Vはフォントドライバー ($DISP.SYS) が起動時にJIS第2水準までの全ての文字のフォントをディスクからメインメモリーにコピーして、ディスプレイドライバー ($DISP.SYS) が仮想的なテキストバッファーを用意し、その内容に基づいて、フォントデータをメインメモリーからビデオメモリーへコピーする。ハードウェアとしては単純にビデオメモリーの内容をビットマップデータとして表示しているに過ぎないので、これは完全にソフトウェアによる制御と言える。
5550の場合、DOSは起動時に一部の文字(フォントマップファイルで常駐として指定した文字で、USRFNTユーティリティーから変更可能)のフォントをディスクからビデオメモリーにコピーする。5550はビデオメモリーとは別にテキストバッファーを持っており、DOSがここにビデオメモリー内のフォントへのインデックスを書き込むと、そのフォントが画面に表示される仕組みになっている。例えば、40桁×25行の画面を “あ” という文字で埋め尽くしたい場合、DOS/Vでは “あ” のフォントデータ(32バイト)を 40 x 25 = 1,000 回コピーする必要がある。5550の場合、最初の1回だけ “あ” のフォントデータをビデオメモリーにコピーすれば、後はそのインデックスと属性(下線、反転、ハイライトなどの装飾)を示す2バイトのデータをコードバッファーに1,000回書き込むだけで済む。この仕組みはEGA/VGAの英数テキストモードと同じだが、ビデオメモリーのサイズはフォントの全てを収めるには不足しているため、フォントマップで指定されていない文字フォントはキャッシュ(必要に応じて取捨)するという点で異なる。

この方法の利点は、フォントセットを自由に変えられることと、コードバッファーに書き込む値が文字コードに依存しないため、中国語や韓国語などの多言語に対応するには都合が良い。もちろん、外字もこの仕組みを流用して追加できる。よく使うフォントはフォントマップファイルに指定すれば、DOS起動時の待ち時間が若干増えるだけで、後は高速に文字を表示できる。
DOS/Vに比べての欠点は、ビデオメモリーにない文字フォントは都度ディスク上のフォントファイルから読み込まれるため、特にディスケットで運用する環境では文字の表示が遅くなる。また、DOS/Vではディスプレイドライバー次第でフォントサイズや装飾などを自由に変えられるが、5550ではハードウェアで文字を表示する以上、表示方法に一定の制約がある。
ここまではフォント24とフォント16の共通する特徴である。フォント16のさらに興味深いところは、文字フォントサイズが 9x21 となっていて、ビデオメモリーは9ビットワードのアクセスモードを持っていることだ。ビデオメモリーのサイズはフォント24モデルでは256KB、フォント16モデルでは144KBとなっているが、これはビデオメモリーが同じアドレス範囲(A0000-DFFFFh)に配置されながらも、フォント16が1ワード = 9ビットとなっているためだ。もちろん、画面解像度もDOS/Vと違って640x480ではない。

9ビットワードはグラフィック処理では扱いにくい。このため、テキストモードではA0000-BFFFFhとC0000-DFFFFhの128kワード×2バンク×9ビットになっているところを、グラフィックモードでは8ビット単位で偶数アドレスと奇数アドレスに各バンクのメモリーを割り当て、A0000-BFFFFhで128kワード×16ビットでのアクセスを可能にしている。余った1ビットはどこへ行くのかというと、おそらくC0000h以降に割り当てられている。
これを見つけるまでに丸10日かかったが、とりあえず形になったことでホッとしている。これでやっと開発は一段落を終えたんじゃないか。