現在Windows 3.1の起動までこぎつけられないかと思ってCPUコアをいじってるのですが、まずLARインストラクションで詰まってたのでそれは単にLARを実装して突破したのですが、INT 91Hで詰まってます。
どうやら、Windows 3.1は、リアルモードのバイナリのうち処理を奪う必要がある個所に 63H (ARPL)を書き込んで、Virtual 86モードでINT 6を出させて処理をいったんカーネル側に移して、その後、IP+1から処理を再開、としているようです。最初ARPLを見たときは何かの間違いではないかと思ったのですが、最初のうちそのままで順調に進んでいるようだったので、どうやらARPLを書き込むこと自体は正しいようです。ARPLが書き込まれる場所の多くは、書き込み前は90H (NOP)になっているのも多分この書き換えが意図的なものであると考えて問題なさそうです。
INT 6ハンドラは、0048:00000102ですが、どうも169Cセグメント(DOS?)内でARPLが起きることを想定しているようで、INT 6を受けて、Exceptionが起きたインストラクションが63Hであった場合、Exception発生個所+2バイトに飛び、その場でリアルモードへの切り替えが起こるように書いてあるようです。0048セグメントはひょっとするとEMM386かも。
しかし、あるタイミングでIDTが書き換わって、INT 6をハンドルするのが0028:80006E5Cに変わり、再度0048:00000102に変わった後で、INT 91Hのハンドラの入り口(07F9:000023F4)のARPLでINT 6が出た後、00B8セグメントのあらぬ場所にジャンプしてクラッシュしてます。INT 91Hのハンドラは先頭にARPLが書かれているのですが、+2バイトではリアルモードに切り替わるように書かれていない上に、00B8セグメントのベースは169C0Hを指したままなので、違うセグメントの無意味なアドレスにジャンプということになってます。
MSDOS.SYS以外のINTのARPLは0028:80006E5Cだとうまくさばけるようなので、IDTが書き換わるべきではないのか、INT 91Hは別の処理の仕方であるべきなのか、そもそももっと前の時点で何かがこわれててINT 91Hが出るべきではないのか、なかなか難しいですね。どうもこの INT 91H (コンソールBIOS) はコンソールに1BHを書き込もうとしてるようなので、すでにコンソールは表示されていないことを考えると実はINT 91Hが出ていること自体が間違ってるのか。
なお、Core i9のPCを買いました。最近シングルコア性能は世代が変わってもほとんど変わらんと思っていたのですが、案外変わってたんですね。多分486SXの66MHz近いスピードが出てるようでStrike Commanderが快適になりました。ただ、nVidiaのGPUだったので、OpenGLのVSYNC待ち(なぜかnVidiaはデフォルトでオンにしている)をオフにしないと待ちが入ってスピードが落ちるという問題がありました。
2021-01-21 00:40:27
その後、どうやらクラッシュしてるのはWIN386.EXEが起動に失敗してDOSに戻ろうとする途中のような気がしてきました。なにやらPage Faultが起きてるんですね。そして、そのハンドラの中で同じ場所に突っ込んでPage Faultが起きて、それをハンドルしようとしたところでどうやらあきらめてDOSに戻る途中三度目同じところに突っ込んで、三度目はIDTがEMM386のIDTに書き換わっているようで対応しきれなくてクラッシュ、みたいな感じです。そのPage Faultは000C8000~のFM-R VRAMにアクセスしようとして発生しているので、その領域にアクセスしようとしたらPage Faultになること自体は正しいっぽいのですが、多分、その領域にアクセスするパスに入ってくるべきではなさそうです。
それで、WIN386.EXE (DOS6もだけど)の中で、RETFをCALLFとかJMPFとして使ってる個所がたくさんあって、コールスタックがめちゃくちゃになってしまうんですね。ということで、シンボルに情報としてJMPF_BY_RETF, CALLF_BY_RETFを記録してそこに突入したら適宜コールスタックの更新の仕方を変えてデバッガで流れが見やすくするところから始めようと思ってます。先は長そうですね。IRET_TO_VM86 (Stack Return to Virtual 86)は考えてみたら検出可能なので対応したのですが。
2021-01-23 02:25:01
↑の問題は、Page FaultでCR2にリニアアドレスを入れてないという問題でした。それを直して、今は、INT 31Hが出てるのですが、対応するIDTのエントリが壊れているらしい (80286の16-bit Trap Gateだと思ってる) というとこですね。一応、今Unit Testを流してるので、通ったらそのバージョンのソースをPUSHする予定です。
2021-01-24 07:51:07
異なるPrivilege間のINT/IRETは同じPrivilege間のINT/IRETと微妙に動作が違うことに気が付いて実装したら↑の個所は通過したんですが、INT 31H AX=0602H (Mark Real Mode Region as Pageable)の中で戻るべきリニアアドレスのページテーブルエントリのPresentビットを0にしてしまって、IRETでPage Faultになってるところで止まってます。ひょっとするとこれが正しい動作でPage Faultを出すべきなのかもしれないんですがね、ただ、そこらじゅうでPage Faultのチェックを始めるとCPUコアが明らかに遅くなることが想定されるので、やるならIRETで抜けるところでチェックかと思ってるのですが、しかしここでPage Faultを起こすのも何か変な気がするので現在 INT 31H AX=0602H の中身を見てます。いやな予感としては、メモリを十分搭載していればPage FaultでSwapは起こらないだろうとみていたのですが、V86モードのかたまりのWindows 3.1だとPage Fault起こしまくりでリアルモードメモリをスワップしてたりして。それだと、それに対応するためにTownsオリジナルアプリの動作を遅くするぐらいならWindows 3.1は対応しない方がいいかもしれないですね。ある程度はFractal Engineのために対応してはいるのですが。
2021-01-30 02:36:21
山川機長さんのお気持ちとしては、"FMTOWNSで動作していたソフトウェアは全て動作する"を目指されているのだと思うのですが、状況を見ていると仰る通りTOWNSオリジナルアプリの動作が遅くならない方法が見つかるまではWINDOWS3.1を先送りしても良いように思います。
幸いにしてTOWNSでWINDOWS3.1を動かさないとならない人もかなり少ないでしょうし、実際の所はWINDOWS3.1に対応してもインストールする人は(ほぼ?)いらっしゃらない物とも思われます。(個人的には、WINDOWS3.1<Linux<WINDOWS95の順のような気がします)
それにしても、WINDOWS3.1って相当アクロバティックな作りなんですね・・・
2021-02-01 15:27:12
まさにその通りで、Windows 3.1はとりあえずこの間実機のHDDから既にインストール済みのイメージを抜き出すことができたのでやってみている感じで、Windows 3.1そのものにはあまりモチベーションが無いんですよね。Windows 3.1が動作しなければWindows 95も動作しないと思うのでやってるというか。ひょっとするとLinuxの方が素直にできているかもしれません。
それにしても、本来であればタスクを切り替えるとき、Page Faultが起こらないようにページをマップしたうえで切り替えるべきな気がするんですけどね。試しにIRETしたところでPage Faultを出してみたのですが、これで正しくメモリがマップされて戻ってきたらPage Faultをわざと出させている可能性が高まったのですが、ぜんぜん無関係の領域がマップされたので、それほど単純でもなさそうです。
春学期も始まってしまったので、多分この問題はしばらく放置状態になりそうです。
2021-02-03 00:41:18
ありがとうございます
2021-02-04 11:18:48
うーん、どうしてもWindows 3.1が起動しない原因が解明できないですね。Windows 3.1を起動させるために本来のTOWNSアプリケーションのパフォーマンスが落ちるようであればあきらめようと思っていますが、原因がわからんというのが気に食わないんですよね。原因が解明できた上で、これをサポートする価値は無いという結論だったらそれはそれでいいのですが。
現在、
00A7:0000C7B8 INT 31H
AX=0602h Mark Real Mode Region Pageable
BX:CX=Starting Linear Address (0003:5410)
SI:DI=Size (0008:ABE0)
それで、このときはアドレスサイズ、オペランドサイズともに16という半端なプロテクテドモードで動作していて、Windows 3.1のDPMIインターフェースによると、INT 31H AX=0602Hは、リアルモードの線形アドレスをページ可能にするというもののようです。
この関数の中で、BFFFFHまでのリニアアドレスのページテーブル情報をごっそり消してしまうのですが、問題は、このINT 31Hの発射地点はリアルモードだとAE84:C7B8、物理アドレス=線形アドレス=BAFF8Hにあたり、戻ってきたときページが無くなっててそのままクラッシュになってしまいます。
ひょっとしてページフォールトを検出してマップしなおすのかという可能性も考えたのですが、多分それは正しくないように思います。スワップアウトするでもなく、ハイメモリ領域に移動するでもなく、いきなりページを消してしまったのでは、ページフォールトが起きてももともと何があったのかわからんと思うんですね。なので、使用中のページは消すべきではないと思うんですね。
その仮定が正しいとすると、
(1) INT 31Hを出すときのサイズ(8ABE0H)が間違っている。ちなみに、このサイズは起動時にチェックしたリアルメモリ実装量、TOWNSの場合はC0000Hから計算されている模様。
(2) そもそもこのコードがC0000H以降に置かれるべきコードが何かの間違いでBAFF8Hにある。
(3) INT 31H AX=0602hは本来使用中のリニアアドレスのページは消さないはずだが、間違ってBAFF8H付近は未使用と思ってる。
(4) INT 31Hから戻る前に本来であれば使用中ページはハイメモリに移動してページテーブルもそれに対応して更新してから戻るべきところが、なぜか移動とテーブル更新が起きてない。
などの可能性を考えているのですが、いかんせんWindows 3.1の内部という難敵を相手にしているもので、なかなか難しいですね。
このINT 31H AX=0602hの本来の挙動というのはどうあるべきか、誰か知ってますか?
2021-11-02 10:47:44
(ほぼ需要がゼロなのに)あきらめずにWindows 3.1が起動できないか試しているのですが、自爆しているプログラムがKRNL386.EXEであることまでわかりました。どうやら普通にINT 21H AH=4BH (プログラムのロードまたは実行)を使って起動しようとしているのですが、ただし、既にWindowsが起動しかかっているので INT を使うかわりに INT 21H ハンドラにCALLFを使って飛んでいるようです。その中で、どうやらBFFFhセグメントからバイナリサイズ/10hを差し引いたセグメントにKRNL386.EXEをロードして実行するのですが、上に書いた通り自身の中でリアルモードメモリ0~BFFFFhをページ可能にする、というシステムサービスを使って自分を見えなくしてしまって自爆します。
リアルモードメモリをページ可能にするというシステムサービスは正しい動きをしているようなので、KRNL386.EXEがC0000h未満にロードされる以上、必ずクラッシュするらしく、なぜC0000h未満にKRNL386.EXEをロードしてしまうのか、という謎は、アドレスを計算している場所は特定したものの、BFFFhの出どころがまだ解明できていないため、解決には至ってないという現状です。しかし、INT 21H AH=4Bh のデフォルトの挙動としてはプログラムをC0000h未満にロードするはずなので、何か特別なことをしてないとハイメモリには展開されない気がします。
一度、SETUP2.EXEを使ってハイメモリを有効にする必要があるのではないか、という指摘があったので、試しましたが結果は変わらなかったですね。しかし、これが設定の問題である可能性もゼロでは無いので、TOWNSでWindowsを起動するときなにか設定が必要だったとかもしもおぼえてる人がいたら情報をお願いします。
しかし、津軽でWindows 3.1を実行する需要がほぼゼロという問題はあいかわらずあるんですがね。
2022-01-29 02:05:09
自分ではTownsについては良く判かりませんので 参考になるかも判りませんがTownsで Windows 3.1を起動させているサイトの情報がありました。
http://www43.tok2.com/home/cmpslv/Konjo/019/019.htm
2022-02-15 23:26:42
ありがとうございます。参考にさせていただきます。たしかにMAMEのデバッガで正しい動作がどうなのか追ってみるのも手かもしれませんね。
2022-02-16 12:13:56
MAMEで動くのならCPUでしょうか。
CPUで気付いた点で、おそらくほとんどのプログラムに影響しないのでわざわざ報告するのもなぁと放置していた点が何点かあって、
・NEGがAフラグを変更しない
これに依存するプログラムはおそらく地球上にはないので、こっちはどうでもいいと思います
・オペランドへのストア前に状態を更新している
ちゃんと検証できていないのですが、 push/pop mem で PF が起きるとページをマップして再実行した結果、esp が本来の倍変化するのではないかなあと思っています
2022-02-17 01:26:02
なるほど!CPUコアの問題であることは間違いないと思うのですが、現状津軽のCPUコアはFractal Engineを走らすための必要最低限のExceptionしか対応していないので、多分PUSHでExceptionが起こるとそのままVMがAbortしてしまうかも。
が、考えてみるとWin3.1の問題個所ではPFが出るかと思ったらCS,EIPその他をスタックに詰めないのでDouble Faultになりそうな気がしてきました。実はここはDouble Faultを出すと先に進んだりして。というか、それだとするとやっぱり真面目にInstruction Fetchの段階でもException見ないといかんのかな。これを入れるとTownsネイティブアプリに効いてきそうでちょっとやだな。
2022-02-19 00:02:59
おそらく需要がゼロと思われるWindows 3.1対応ですが、DOSBOX上のDOS用Windows 3.1との動作比較の結果、現在ひっかかっている箇所の問題が特定できました。ページテーブルのbit 5, bit 6 (0x60)をチェックしてるから何かと思ったら、Dirty bit (書き込まれると立つ)とAccessed bit(読み書きで立つ)でした。そういえばDOS Extenderでは使って無さそうだから対応してなかった!
しかし、これ対応しようと思ったらメモリアクセスするたびにフラグ立てなきゃならなくなって、(ただでさえ遅いと言われてる津軽なのに)Townsアプリの実行スピードに影響が出ると思ったので、これはビルドするときにマクロ定義かなんかで対応するとして、Windows 3.1を動かしてみたい人は各自ビルドしてもらう方向にしようかな。
それにこのフラグに対応してもまだ起動までこぎつけるかどうかは不明だし。
2022-04-01 22:53:14
やっぱり需要がゼロと思われるWindows 3.1ですが、pinさんがJCXZとLOOP命令のエラーを発見してくれて(まさかここだけCXとECXの切り替えがオペランドサイズじゃなくアドレスサイズと思わなかった)、さらに先に進むようになりました。が、現在
INT 47H
の中で固まってますね。INT 47Hって、何をするのが正しいのかまだわからんですね。INTの40H番台は、原則デバイスのI/Oに使っていて、47HはPICのブリッジで本来発生しないはずのINTということになってますが、なんかで使ってるようです。手動でNOPにしてAXに0F386Hをセットして先に進めてやるとさらに進むようなのですが、その先でクラッシュしてしまいますね。BRKON INT 47としてデバッガ仕掛けて実行すると、その場所までたどりつけます。
もしも何かヒントになりそうな情報があったらよろしくお願いします!
なお、Windows 3.1を(途中まで)実行するには、i486.hの中の、
// #define TSUGARU_I486_UPDATE_PAGE_DA_FLAGS
個々のコメントをはずしてコンパイルする必要があります。
2022-12-07 11:34:16
githubにTEST386というのを見つけたので(https://github.com/barotto/test386.asm)、High Fidelity Modeなるものを作ってTEST386がすべてパスするようにしてみたのですが、それでもWindows 3.1起動しませんね。TEST386がパスするので、プロテクテドモードは相当再現度が高いと思うのですが、ただ、VM86モードのテストとタスク切り替えのテストは入っていないということなので、怪しいのはタスク切り替えで失敗しているという可能性もありますが。しかしDOS6は割とよく動いているようなので、ひょっとしてデバイスの問題だろうか。
VM86モードをテストするプログラムとかって無いもんですかね。あるいは、DOS6からEMM386の機能をテストするようなプログラムでもいいんですが。
なお、High Fidelity Modeは、トップレベルのCMakeLists.txtの
# add_compile_definitions(TSUGARU_I486_HIGH_FIDELITY)
このコメントになってる行をコメント解除してコンパイルすると利用できます。フラクタルエンジンとか気にしないから一般的なTowns OSアプリが速く動くLow Fidelity Modeも作ろうと思ってます。ほとんどStrike Commander専用になりそうですが。
2023-03-04 14:34:11
もはや需要がゼロのWindows 3.1ですが、わがCPUコアで動作しないのが気に入らないというだけの理由でCMUの春休みを使ってかなり調べたところ、KRNL386.EXE起動までは正常に進んでいるようです。そして、OASYS.DICを開こうとしたところINT 93Hから戻ってこないというのは結構前から同じなのですが、
emb cs:eip B5 00 B8 B0 0E CD 93 EB FE
という無理やりINT 93Hを埋め込むという技を使ったところ、KRNL386.EXE突入直後は普通にINT 93が動作するんですが、INT 21HでOASYS.DICを開こうとした時点ではINT 93Hが動かなくなってるということが確認できました。どこでINT 93が動かなくなるのか究明しようとしてます。
これ、タスクスイッチングとか使い始められるとまったく未知の領域になってしまうのですが、今止まってる箇所はまだタスクレジスタは一個しか使ってなくて、ここは突破できそうな感じなんですがね。
2023-03-11 01:13:51
LAR, LSLインストラクションを見直して、opCode 0FFFH をどうやらINT 6テストに使っているようなのでINT 6を出すようにして、OR BYTE PTR ES:[BX],0 でPage Faultをわざと起こさせるようなので、これもハンドルするようにしたら、Windows 3.1がCRTC2に書き込んで、640x480モードに切り替えて、背景を白く塗るところまで進むようになりました。LAR, LSLは使用頻度が少ないので、Default Fidelity Modeでも動作を実機同様(実機MXで挙動を調べるコードを書いて、それに合わせた)に動作するようにしたので、多分DOS6の再現性にも少し改善があったと思います。
かなり奥まで進むようになったものの、なかなかGUIが使えるところまで進まんですね(^_^;)どうも、Exceptionが出ないように準備して呼び出すというより、Exceptionが出たらそれに対応するような書き方になっているようなので(最近のOSってそういうもん?)、そういうところでひっかかっているのでしょうね。まあ、気長にやっていけば、10年以内には津軽でもWindows 3.1が走るようになるでしょう。
2023-03-16 00:01:30
どうも、CRTC2のパレットは、書き込むとアドレスラッチが自動的にインクリメントされるようですね。その修正を加えたところ、背景がWindows 3.1っぽいグレーになるとこまで来ました。これはひとつTownsOSアプリの実行の正確さにも関連があった鴨しれません。
現在、INT 21H AX=4408H (ただしプロテクテドモードから呼んでいるのでINT 21Hと違う呼び出し)が、内部でBlock DeviceのInterruptの中で INT 93H AX=FAB1Hを出したところで、プロテクテドモードがいったんINT 93Hを迎撃するものの、そのままVM86モードに戻してしまって(そこまでは正常)、その後ARPLによるブレークポイントから先はまたプロテクテドモードが対応すればよかったのですが、コマンドAH=0FAHの場合、またまたそのまま処理をVM86モードに戻すものの、既にSCSI割り込み INT 48H はプロテクテドモードが取ってしまった後で、SCSIがコマンドフェーズに入ったままいつまでもかかってこない割り込みを待ち続ける現象が起きています。
このAX=4408Hを出しているのがSYSTEM.DRVであるということまでは確認して、同じコードはDOS版のWindows 3.1 SYSTEM.DRVにも存在することから、TOWNS特有では無さそうです。また、AX=4408Hはドライブがリムーバブルであるかのチェックということで、これに失敗するとは思えないので、ここに入ってくるまでは合ってると思うのですが、AX=0FAB?H で INT 93H が出てしまうともはや復帰の余地は無さそうです。
ひょっとしてSCSIコントローラがタイムアウトして、Parity Errorビットを立てる(その場合もINT 93H内のループから抜ける)という可能性も考えたのですが、実機で実験したところ、タイムアウトは起こらないようで、Selection Phaseに入れたまま放置するといつまでもSelection Phaseのままで、SELビットを下ろしてData Phaseに入れたまま放置してもいつまでも Data Phase のままのようでした。
というとこで、また万策尽きた感になってます。背景がグレーまで出たんだからウィンドウが開く寸前まで来てるんじゃないかと思うんですがね。なかなか難しいですね。
2023-03-19 13:13:02
High-Fidelity Modeでコンパイルしたら10回に一回ぐらい起動するようになりました!キーボードも反応します!マウスがなぜか出ませんが。
2023-03-24 02:16:57
Windows 3.1、起動できるようになりました!まだ起動できるだけで、何もできませんが、「ぱぱーん」という起動音を聞くことができます。たとえばファイルマネージャを開こうとすると止まりますが(インストラクションからの例外に対応してない)。
最後は80386 Programmer's Reference Manual 1986のIRETリファレンスにも書いてない、CPL<DPLならIFは保存するというのを実装して突破でした。でも、IRETでIFが変更できるとすると変な気がしたんですよね。
まだインストールできるかは試してなくて、プリインストールモデルのHDDイメージから起動ですが。なお、起動するには、High Fidelity Modeでコンパイルする必要があって、srcではなくsrchfに対してcmakeをかけてコンパイルするとHigh Fidelity Modeバイナリができます。そのうち起動オプションで切り替えられるようにしようと思ってますが、Low Fidelity ModeでセーブしたステートをHigh Fidelity Modeで読み込むとクラッシュする場合があります。(それは仕方ない)
とりあえず、いったんWindows 3.1対策はここで一時停止して、High Res PCMやります。
2023-03-25 23:22:56
間違い。 (誤) CPL<DPL -> (正) IOPL<CPL
2023-03-25 23:25:17
はじめまして。
いつの間にかWindows3.1が起動できるようになったとのことで、
もしかしてと思い、Windows3.0Aが入ったHDDイメージを読み込ませたところ起動できることを確認しました!
ただ、こちらもマウスが操作できません。
マウスカーソルも表示されて、コントロールパネルのマウス設定で左右ボタンが反応していることまで確認できるのに非常に惜しい・・・
取り敢えず、キーボードで頑張ればそれなりに動かせそうです。
以上、3.1以上に需要が無いと思われる3.0Aの報告でした。
2023-04-07 00:15:52
テストしていただきありがとうございます!一応、パッドまたは矢印キーによるマウスエミュレーションを使うと、使いやすくはないですが操作は可能だと思います。3.1以降はなんとハードウェアマウスカーソルを使ってくれていたおかげでマウスのインテグレーションは簡単にできてしまったのですが、3.0Aだとマウスカーソル位置が書いてある場所を特定するのが難しそうです。多分、まだ例外処理に対応してない命令や、未対応の浮動小数点演算命令が多いのでよく止まると思いますが、何か気が付いたらお知らせください。
2023-04-08 00:30:11
Windows 3.1対応してて気が付いたのですが、FF95H, FF96Hの漢字JISコードって最上位ビットは無視するもののようですね。Windows 3.1のインストーラで、文字が化ける原因を究明したら、JISコードプラスbit15のコードを書き込んでいて発見しました。他にもどうやらRS232CのINTの出方が実機と違うらしいということもわかって、あとHigh Res PCMがあったらそっちを使うようにできてるようなので、いろいろそれなりに役に立ちそうです。High Res PCMは一応High-Cのライブラリで.WAVファイル再生の例題があるっぽいので、それも使えそうでした。
2023-04-09 05:44:22
High Fidelity Modeですが、最新のソースからコマンドオプション(-HIGHFIDELITY)またはGUIで選択で使えるようにしました。コンパイルしなおさなくても使えます。Virtual関数を使えば割と簡単に実現できたと思うのですが、一秒間に100万回も呼ばれる関数の中で何度もVirtual関数を呼ぶとさすがにパフォーマンスが悪すぎるし、できればMedium Fidelity Modeで使わない機能については、コンパイラが if(false) と判定してその部分を自動的にカットさせたいと思ったので、TemplateでHigh-Fidelity CPUコアとMedium-Fidelity CPUコアの区別を実現してるので、結構大工事になりましたが、テストもすべて通っているので多分大丈夫でしょう。
2023-04-12 22:25:31
そういえば、Windows 3.1の頃って、PC98 Windows 3.1アプリとかTOWNS Windows 3.1アプリとか分かれてましたっけ?
US版のVisual C++ 2.0についてきたVisual C++ 1.5を津軽上のWindows 3.1にインストールしたら、フルスクリーンモードのMS-DOSプロンプトからならコンパイルできるのに、ウィンドウモードのMS-DOSプロンプトでコンパイルしようとするとフリーズしてしまうので調べたところ、INT 4DH (SOUND)ハンドラ内で、プロセスのVMがプロテクテドモードで実行中で、かつシステムVM(多分一番偉いVM)ではない場合、なぜかサウンドの割り込み要因をクリアしないままハンドラを抜けてしまい無限INTになっていました。
さらに調べたところ、本来YM2612のタイマーフラグをクリアするべきなのに、 MOV AL,0 / OUT 0F0H,AL となっていて、I/O 00F0Hなんてなんか意味があるのだろうか?YM2612のタイマーフラグを一発でクリアするとかいう魔法のI/Oなのだろうか?だったらなぜ他の場面で使ってなかったんだろう?と、思ったのですが、そもそもこの MOV AL,0 / OUT 0F0,AL はどのドライバに入っているのか?と思って探したところ、Visual C++のDOSXNT.386の中であることが判明して、さらに調べたところ、DOS上では、BOCHSのドキュメントによるとPICのINT 0DHはFPUの割り込みで、OSDEVのドキュメントによると I/O 00F0H はFPUのBUSYフラグ解除ということで、Visual C++が勝手にテイクオーバーした INT 0DH (CPU的にはINT 4DH) ハンドラが、FPUの割り込みだと思って処理していたため起きていたということが判明して、どうやらDOS用Visual C++はTownsのWindows 3.1では使えない(唯一MS-DOSプロンプトをフルスクリーンモードにすればコマンドから使用可能) という結論になりました。
Visual C++が出すコードは、未実装のFPU命令をたくさん使ってるようだったので、テストプログラムを書いてやろうと思ったのですが、DOSBOX上でコンパイルしたやつを津軽に持ってくる方が良さそうですね。なお、TGDRVはWindows 3.1上でも使えました。
2023-04-17 21:46:51
>27 山川機長さん
Windows3.1の互換性については基本的にはDOS時代からあまり変わらずで、「動けばラッキー」程度だったと思います。
要はアプリ内でWin16APIだけを使っておれば動くけど、それ以外のI/Oアクセスなどを独自に行っていればフリーズする可能性が有るのだと思います。
(DOS時代もDOSのAPIだけで組めばATでも98でもTOWNSでも動くのと基本的には同じではないでしょうか?)
たしか、後の時代(Windows95?)にINTの何番かを無効にするツールが有ったような気がするのですが、見つけられません。
2023-04-19 09:44:18
その後、Visual C++をEドライブにインストールして、DドライブのWindowsをそっくりもとに戻して、E:\MSVC\BIN\MSVCVARS.BAT で環境変数を設定したら、普通にDOS窓からVisual C++が使えるようになりました。TGDRVで共有したドライブのソースをコンパイルできるので、いろいろ実験できそうです。未実装のFPU命令を使ってくれたら動作確認になると思ったのですが、少し試した範囲では使ってませんでした。
ここ数日、Windows 3.1 L10が起動しないという報告があったので、追跡sいていたのですが、なんと、Windows 3.1 L10のSCSIドライバが、DMAのアドレスの最上位バイトに書き込まないため、32MB搭載していると、Windowsがファイルを16MBより上の領域に読み込もうとしたときに正しい場所に読めないという原因でした。L11とL12では解消しているようでした。Windows 3.1がL10だった当時だと16MBは贅沢で、32MBなんてありえない容量だったんでしょうね。
2023-04-21 01:46:53
Windows 3.1 L11にUpdate 2(おそらくL12相当となる修正パッチ)を適用してテストしているのですが、WinGを使うゲームで起動時に行われるWinGのベンチマークプログラムを実行中にフリーズしてしまうようです。次回起動時にベンチマークが完走しなかった旨のエラーメッセージが表示されるので無視すればゲーム自体は問題なく動きます。
フリーズ時の状況
VM Aborted!
Device:486DX
Reason:Clocks-Passed is not set.
Towns TIME (Nano-Seconds): 1169731320080
CS:EIP=1CFF:000004FA LINEAR:80D5023A EFLAGS=00000202 CPL=03
EAX=00000001 EBX=00000000 ECX=00000028 EDX=8000EBF8
ESI=000B8E62 EDI=80000000 EBP=00000004 ESP=0000103E
CS=1CFF(LIN:80D4FD40) DS=30E7(LIN:00000000) ES=0997(LIN:80DB4000)
FS=0000(LIN:0004AEE0) GS=2FD7(LIN:80D95EE0) SS=0997(LIN:80DB4000)
CR0=8000002B CR1=00000000 CR2=000C7847 CR3=0034E000
CF0 PF0 AF0 ZF0 SF0 TF0 IF1 DF0 OF0 IOPL00 NT0 RF0 VM0 AC0
Default Operand Size=32 Default Address Size=32 Stack Address Size=16
SS+00000000:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SS+00000010:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1CFF:000004FA 0FCA
実機TOWNSでWindowsは使っていなかったのでTOWNSにおけるWinGの対応状況はわからないのですが、TOWNS版Windows 3.1特有の問題かエミュレータ側の問題かどちらでしょうか。
2023-04-21 19:10:56
早速テストしていただきありがとうございます!ゲーム自体は動くんですね!デバッガオンにした状態で実行して何か言いますかね?これまでのエラーのうち、ほとんどの場合がCPUインストラクション実行中に例外が発生したとき、CPUステートを元に戻さないまま例外をハンドルしてしまって何かが起きていたので、デバッガを有効にすると、その条件にヒットしていないかテストするようにしました。
他にWinG使ったゲームでフリーでダウンロードできるようなのありますかね?手元にぷよぷよ for Windows (ぷよぷよ通もあるけどこれは95以降のはず) があるので試してみようと思ってますが。
ちなみに僕もTOWNSが現役だったころはWindowsを走らせなかったので、実機がどうなのかよくわかりません。というか実機あるんだから環境作ればいいんですが。
2023-04-22 04:31:05
状況、ぷよぷよ for Windowsで確認できました!これ、BSWAP命令ですね。ここまでやってきて一度も使われたことのない命令で、実装してませんでした。実装してみます。
2023-04-22 07:00:15
BSWAPサポート追加したソースPUSHしました。うちの環境ではぷよぷよ for Windowsが動作するようになりました。が、なんかキー操作がへんてこでちょっと操作に苦戦しましたが。
2023-04-22 08:49:45
> 27 山川機長さん
Visual C++1.0はAT互換機、PC-98、FMR/TOWNS用でそれぞれ別パッケージで存在するのを見た事があります。
機種別に発売されたWin3.1用ゲームは見た事が無いですが、存在するのかは私も気になります。
私の方は機種依存の無さそうな画集ばかり購入していましたので、互換性の問題とは無縁でした。
WinGが登場して、少し動きのあるソフトも登場しだしたのでしたっけ。
Windows3.1L11のCD内にINT10NOP.COMなるINT10を無効にしてくれるファイルが入っていますので、
Windows3.1対応としながらAT互換機でしか動作しない物も一定数はあったのかなと推測したりします。
Windows95になりますが、DOOMIIの95版パッケージにはPC-98用とAT互換機用でCDが2枚入っていました。
2023-04-22 22:29:26
Aochanさん、
MYST日本語版はWindows 3.1用ですが、PC98、FMTOWNS対応って明記してあったので、逆にそう書いてないと対応してなかったということなんでしょうね。MYSTを試したらマウスカーソルが動かなくなってしまって、何かと思ったらTOWNSのハードウェアマウスカーソルは白黒専用なのでカラーがついたらソフトウェアマウスカーソルに切り替えていた影響で、CRTCレジスタからマウスカーソル位置を取得できなくなってしまったというものでした。それで考えて、津軽のHOST-VMインターフェースコマンドにマウス位置の通知というのを追加して、Windows3.1上でバックグランドで動作してひたすらホストにGetCursorPosで取得したカーソル位置を通知し続けるプログラムを書いたところ、無事MYSTもプレイ可能になりました。githubの最新ソースで、winapp/TGMOUSEディレクトリにEXEが入ってて、すぐVMに送れるようにutil/TsugaruUtil.D77にも入ってます。
2023-04-24 22:13:48
ハードウェアマウスカーソルって何だろう?と思ってネット検索などしていましたが、これって赤本未掲載なのですね。
PC-98のグラフィック(PEGC、EGC、GDC)にも無さそうで、GD543Xの資料でやっと同等と思われる機能を見つける事が出来ました。
TOWNSハイレゾってWindowsでの高速化も意識されていたのかもしれませんね。
MYSTを発売したインタープログ社は、その少し前にプリンスオブペルシャ2のTOWNS版、PC-98版を発売していましたので、それ故に両機種の対応表記が出来たのかも。
2023-05-03 23:51:03