CuteMouseのDOS/V対応版を作りました。
→ Releases · akmed772/ctmousev
CuteMouseはFreeDOSプロジェクトで開発されたオープンソースのマウスドライバーです。オリジナル版はDOS/Vの疑似的なテキスト画面モード (ビデオモード 03, 73h) に対応していないので、グラフィックモードでしかカーソルを表示できませんでした。この派生版はそれらのモードに対応しています。
DOS J5.0/V標準ドライバーのメモリー常駐サイズは15.2KBなのに対し、CuteMouseは3.9KBと軽量で、UMBメモリーに収まりやすくなっています。BIOSの使用やEGAサポートの削除、メモリー常駐域の最適化によってミニマムを実現しています。
しかし、今回の最大の利点はUSBマウスが使える事です。DOS/V標準のマウスドライバーはPS/2(ハードウェア)インターフェイスに依存しますが、CuteMouseはBIOSのINT 15hインターフェイスのみを使うので、BIOSさえUSBマウスに対応していれば、DOS/VでUSBマウスを使用することができます。もちろん古いPS/2マウスも使用できます。まあ、この「BIOSがUSBマウスに対応していること」という点がネックですが、Intel製やVIA製チップセット用のUSBドライバーが有志によって開発されているので、これと組み合わせることで、BIOSがUSBマウスに対応していなくてもDOS/V上でUSBマウスを使用できます。
IBM DOS J5.02/VのDOSSHELLとMicrosoft Works 2.5 日本語版、Visual C++ 1.51 日本語版のCodeViewで動作することを確認しています。その他の極東DOS/Vでも動くように作ったはずですが、動作確認までできていません。Windows 3.1のマウスドライバーはINT 33hを介さないため、CuteMouseを入れても特に効果はないどころか、DOSボックスと相性問題を起こす可能性があります。
前回の記事を書いた後、パーサーにデバッグモニターのコードを追加して調べたら、原因はすぐに分かった。パーサーのコード自体には問題はなく、取得したはずのDBCSベクターテーブルへのポインターが違うアドレスを指していたことが原因だった。
ドライバーのコード配置には常駐部と非常駐部があって、さらに、初回実行後に初期化される動的メモリー確保の部分もある。今回の場合、初回起動時にDBCSベクターテーブルへのポインターを変数に入れておいたはずが、常駐後におかしなことになっていたらしい。これは変数の確保場所を常駐部のコード内に変えることで解決した。
後は動作テストとドキュメントを少し書き直して、問題なければ明日にでも公開できそうだ。
西洋版MS-DOSマウスドライバーをDOS/Vへ移植しようとアセンブリプログラミングしていて、コア部分はほぼ完成しつつある。だけど、一つ重大なバグが残っていて、それがなかなか原因を探るのに苦労している。
それは文字がDBCS(2バイト文字セット、全角文字)かどうかを識別するパーサー。テキスト上でカーソルを反転させるとき、DBCSなら反転する範囲をSBCS(1バイト文字セット、半角文字)より2倍の幅にする必要がある。
シフトJISエンコーディングのテキストからある文字がSBCSかDBCSかを調べるには、文字の第1バイトが81-9FhまたはE0-FChの範囲内にあるかどうかを調べればいい。ところが、シフトJISにはDBCSの第2バイトにもこの範囲を含むという致命的な欠点がある。途中のとあるバイトが文字の第1バイトか第2バイトかを見分けるには、前の文字も調べる必要があり、最悪、テキストの先頭までさかのぼらなければならない。
例えば、DBCSは1字目がラテン文字で、2字目は数字またはラテン文字からなる、2文字で表現し、それ以外をSBCSと仮定する。123A1B1C1
とあったとき、23
だけを見れば3
がSBCSであることは確定する。2
がSBCSかどうかは前の文字を確認する必要があり、この場合は1
なので、そこで初めて2
がSBCSだと確定する。では、先からA1
を抜き出した時はどうか。これだけ見ればDBCSなのだが、確定するには前の文字を見る必要がある。AA-1
というDBCSとSBCSの組み合わせの可能性もあるからだ。今回の場合は3A1
であり、3
がSBCSだろうがDBCSの2字目だろうが、A1
がDBCSであることに違いないので確定する。問題はABCDEA1
と続いた場合だ。こうなるとA1
のA
がDBCSの第1バイトか第2バイトかを調べるには、先頭までさかのぼる必要がある。AB-CD-E[A]-1
となるか、BC-DE-[A]1
となるか、境界が分からないからだ。
こういう面倒な部分もあるが、単純に2バイトがDBCSかどうかを判断するプログラムはアセンブリコードでもそこまで複雑ではない。
; in: al = char, out: CF = 0 (SBCS), 1 (DBCS)
ischardbcs proc
push es
push di
push bx
les di,[dbcstblptr] ;set ES:DI for DBCS lead-byte table
cld
@@looknexttbl:
mov bx,es:[di]
or bh,bl
jz @@issbcs
scasb ;JPN: 81,9F,E0,FC,0,0h KOR:81,BF,0,0h CHT:81,FC,0,0h
jb @@issbcs
scasb
ja @@looknexttbl
;@@isdbcs:
stc
jmp @@endscan
@@issbcs:
clc
@@endscan:
pop bx
pop di
pop es
ret
ischardbcs endp
そのはずだが、問題はこのコードをドライバーに組み込んで実行したとき、エミュレーター(86Box)では期待通りの結果が出るのに対し、実機では違う結果が出ることだ。実機でドライバーコードをデバッグするのは結構手間がかかる。原因はまだ判明していない。範囲は絞られたので、もう少しで分かると良いのだが。現状は見当がつかない。
→ 「オブリビオン」はリマスターで何が変わったのか。主な変更点を紹介 - 4Gamer.net
つい4日前に突如発表・発売されたばかりという The Elder Scrolls IV: Oblivion Remaster。前からプレイしたいとは思っていたけど、PS2(PS3?)クオリティのCGでゲームのモチベが続くか微妙、でも気になると思っていたので、リマスターが出たことは嬉しい。GWはこれに時間をつぶすのもありだな。
NPCやフォロワーのクセのある動きやAI、会話の時のカメラズームアップはそのまま再現されているんだろうか。