240115 PS/55エミュ製作 [28]BitBltとグラフィック実装は9割完了
BitBltの開発を始めて11日目。JDOSの$BITBLT.SYSには矩形範囲をブロック転送するファンクションがある事が分かり、その処理を解析してビットシフトやアドレスの計算方法をどうにか見いだすことができた。
それをまたエミュレーターに実装して上手く動かすには時間が掛かったが、ついにWindows 3.0は高解像度ドライバーで表示できるようになった。下のスクリーンショットは意図的に画面外のビデオメモリーのデータも表示させている。
これで安堵するも束の間、Windows 3.1では同等仕様の高解像度ドライバーを使用しているにもかかわらず、表示がぶっ壊れる。
これはI/Oポートに特定のレジスターへ値を代入する処理をセットアップしたら、8割方正常に動くようになった。テキスト表示がなんか変。
これも「ワケ分からん!」と言いたくなる話だが、VGAもディスプレイ・アダプターも内部レジスターへのアクセス方法が色々あって面倒くさい。
例えば、ある内部レジスターのインデックス番号01にデータFFh(16進数)を書き込む方法は、
- I/OポートAに01を出力し、I/OポートBにFFを出力。
- I/OポートAにワード単位でFF01を出力。
- I/OポートAに01を出力し、同じくI/OポートAにFFを出力。(ラッチ切り替え処理)
- I/OポートCにFFを出力。(このポート自体がインデックス01のデータポート?)
この4通りがあることが分かっている。JDOSやWindowsのバージョンが変わると、知らないI/Oポートやレジスターへのアクセスが出てきて、コード実装も私の頭の中もスパゲッティ化していく。
今回問題のテキスト表示にはBitBltは使われていない。従来のJDOS上でのグラフィックの書き込み方法と同じで、EGAのプレーン同時書き込みと同じような方法が使われている。ディスプレイ・アダプターにはEGAのGraphics Controller Registerと同等の機能があるが、今回はそれにはない追加のインデックスのレジスターへの書き込みが影響していると疑っている。ROPがAND演算の時だけ何かのビットフラグが設定されているが、その意味を解かないと解決できないだろう。