QEMU on Windows
This is the tentative page to provide QEMU windows port binaries as Kazu's proxy.
Snapshot binaries will be provided every month.
Please refer Kazu's site for more details.
NOTE:
You can download kqemu-1.4.0pre1 in QEMU official site.
kqemu-1.4.0pre1.tar.gz includes the windows binary.
mailto:
t-takeda@m1.interq.or.jp
QEMU/9821 on Windows
This is the experimental work to support NEC PC-9821 on QEMU.
2009/10/29
qemu-develにV3パッチを投げました。
ついでにこっちのアーカイブも更新しておきます。
SDLのstdoutの件はまた後日にでも。
2009/10/28

86音源を実装してみました。
既存のadlibがMAMEのOPLコアを元にしているので、同じバージョンのMAMEのOPNAコアを
引っ張ってきたら、QEMUとの結合が簡単かなあと思ったのですが。
MAMEのソースアーカイブを遡って調べてみたら、Fork元のバージョンが0.59だったようで。
またえらく古いなあ(苦笑)
で、頑張って結合させてみました。
まあ一応音はなっているのですが。
OPNAのタイマを使ってFM音源を駆動してるソフトだと、再生速度が微妙に安定しないんですよね。
タイマの駆動に使っている、QEMU側のタイマのrt_clockの分解能が1/1000秒しかないので、
タイマの精度がどうしてもいまいちなのが原因だと判ってるんですが。
double型で誤差を蓄積させて、タイミングが大きくずれないようには処理しているのですが、
音の生成処理というのは実時間とちょっとでもずれると人間の耳には判っちゃうのですよね。
vm_clockだと1/1000000000秒の分解能ですが、いまいち実時間の流れとリニアでないみたいで。
サウンドバッファの生成は実時間とリニアなんで、FM音源の駆動源のタイマもリニアでないと、
もうそもそも再生テンポが狂いまくりになっちゃいます。
PCM音源みたいに、バッファからバッファに垂れ流すだけなら悩まないんですが。
なんとも難しいですね。
もうちょい何とかならないか調整してみます。
2009/10/25

256色モードでクラッシュする問題を修正しました。
夢幻泡影で確認しましたが、綺麗に表示できているようですね。
後は480ラインモードとCLGD5430の確認もしないと。
2009/10/24

テキスト画面で、黒色の文字が表示されていなかったのと、
カーソルが表示されていなかったのを修正しました。
DOS SHELLでちゃんと文字が表示されるようになっています。
現在の実装では、VRAMやパレットが書き換えられたり、GDCの設定が変わるなど、
必要なときだけ画面を再描画します。
しかし、カーソルの表示位置を指定するのに使用しちえるCSRWコマンドが、
本来は3bytesのパラメータを指定するところが、PC-98のBIOSはどうも2bytesしか
指定してくれないようで、GDCのコマンドの終了判定がうまくいきませんでした。
カーソルキーを押して次のCSRWを発行すると、やっと前回のCSRWが終了したと
判定して画面を更新するため、カーソルが遅れて動くように表示されるなど、
ちゃんと動作するようになるまで結構苦労してたりします。
2009/10/22
そろそろ、本家MLにv3パッチを投稿するためにソースを整理中です。
うっかりパッチが受理されると、その後の大幅な変更が困難になりそうなので、
今後の実装予定も踏まえて見直しをしています。
あとはPC-9821Rv20のITFをサポートするため、PCI周りの作業をしていました。
注意点は、QEMUのSMRAMの実装が、0xa0000-0xfffffがバンク切り替えされないことを
前提としたものになっているため、その辺の対応が必要になることと、
C-BUSブリッジが0x30番に決めうちでぶら下がっていることと、
ERRSTSの値でPARITY ERRORを検出していることと、
メモリチェックで取得したRAM容量とDRBを比較していること、でしょうか。
現状では、ITFのハードウェアチェックは突破できるようになっています。
ただBIOSに切り替わってから、あさってなアドレスにジャンプしてしまいますが(苦笑)
もうちょい調査が必要ですね。
PC-9821Rv20に対応できたら、次はPC-9821Nr300の対応もしないと。
2009/10/21
Neko Project2を参考に、PnP BIOSを潰すようにしたところ、
FreeBSD/pc98 7.2-RELEASEがインストール&ブート出来てしまいました。
2009/10/6に試してみたときにクラッシュしていたのは、
PnP BIOSで何か処理をしていたのが原因だったみたいですね。
インストール作業の動画をこちらにアップしました。
ついでにニコニコにもアップしてみたり。
んー、これがブートするのが最終目標だった筈なんですが(苦笑)
まだWindowsがインストールできない問題も残ってるし、当面は開発を継続します。

NEC純正のハードディスク起動画面も使えるらしいですが、
FreeBSD/pc98のブートセレクタをインストールしてみました。

ブート中。

rootでログインしてみたところです。

PC-9801BX4のハードディスクの容量制限を勘違いしていたため(ぉぃ)、
今回はMinimalインストールしてしまいましたが、
今度はX環境もインストールして試験してみたいですね。
あと古のPlamo Linux/98も試してみないと。
学生時代にPC-9821Rv20にインストールして遊んでいたんですよね。
2009/10/20
これまで画面の解像度を640x480固定にしていましたが、
画面モードに応じて400/480ラインに変更するようにしました。
数年前に最初にQEMUを弄りだした頃、画面の解像度を640x400にしたところ、
QEMUモニタに切り替えて復帰するとクラッシュするという問題があったため、
それ以来ずっと640x480固定にしていたのですが。
今回試してみたら、何時の間にか現象が発生しなくなっていました(苦笑)

ついでにVGA周りも修正しています。
EGCのリセット処理で、EGC構造体を丸ごとmemset()でクリアしていたため、
VGA構造体のポインタが壊れてしまっていた(恥ずかしい)不具合の修正とか、
GDCからのVRAMアクセスに、EGC/GRCGをかませるようにしたりとか。
N88BASICでは、画面描画にGDCのコマンドを積極的に使っているのですが、
(過去の経緯、でしょうかね)
LINE/CIRCLE命令で正しく描画できない問題が解決しているようです。
2009/10/19
1.23MBのフロッピーディスクに対応できました。
READ IDで取得されるNの値を、セクタ長にあわせて変更したのと、
READ SECTORで、転送するセクタ数の計算方法を修正しました。
(これは、82078とuPD765Aの仕様の違いなのかな?)

また、ディスク交換を検出したときに発生するIRQの処理を変更しています。
ディスク交換でIRQを発生させたとき、偶にこのIRQが処理されないままとなり、
その結果、BIOSがFDCにコマンド送らなくなってしまったり、
既に割込み要求中に更にIRQが発生してしまい、ディスク交換を検出できないなど、
(特にブート時に)タイミングに依存した不具合があったため、
IRQがペンディング中でないときのみ、パルスでIRQを発行するようにしました。
2009/10/18
PC-98で標準的に使われる、1.23MBのフロッピーディスクの対応中です。
QEMUのFDCは、セクタ長が512bytesであることを前提として実装されています。
これに対して1.23MBのフロッピーは、セクタ長が1024bytesです。
この辺の対応が結構面倒くさいですね。

で、取り敢えず実装してみたのですが…
ディスクを読み込み始めるのですが、MSDOS.SYSのロード中にエラーとなります。
中々難しいですね。
2009/10/17-2
Roy Tamさんのご指摘により、一部修正を行いました。
CBUSブリッジの初期化処理の不具合と、PCIなしの場合の割り込みの修正です。
特に前者は危なっかしいので、アーカイブを修正しておきました。
2009/10/17
昨日の時点のgit repositoryをベースに、ソースを整理しました。
MLへのパッチの投稿はもうちょっと先ですが、仮にここでリリースしておきます。


特に意味はないけど、取り敢えずT2からスクリーンショットを2枚ほど。
普通に動いてます。
こうなると、FM音源の実装もしたくなってきますね。
2009/10/15


IDEのコア側の実装が、強制的にLBAとするようになっていたのを修正したり、
Initialize Drive Parametersで最大セクタ数や最大ヘッダ数をちゃんと設定するようにしたところ、
IDEハードディスクからMS-DOSがブートするようになりました。
WIN98SEのCD-ROMの中身を全部コピーしても、セクターエラーが発生しなくなっていますので、
これで実用上は問題なさそうですね。
2009/10/10
IDE BIOSの逆アセンブルした結果を、CPUトレースログ比較しながら処理を追っかけてみました。

ドライブをリセットする前でも、パワーオンの自己診断結果をステータスに出すようにしたり、
F8E8:0010にIDEドライブの接続状態を入れるようにしたり、その他色々修正した結果、
BIOSがIDENTIFYコマンドを実行して、ハードディスクの容量を取得できるようになりました。
FDISKでパーティションを作成することも可能です。

ただし、ハードディスクからのブートはまだ出来ていません。
またWin98SEのインストールを試してみたのですが、データのコピー中に失敗してしまいました。
その後SCANDISKを実行すると、不良セクタになってるようです。
IDEのコア側の実装に、CHSでのアクセスの実行について何か問題があるんじゃないかなと思います。
後は、システム領域などにあるIDEドライブの存在フラグが、ブート時に正しく設定されない件も
調査しないといけませんね。
というか、どうしてあんなにあちこちにあるんだろう(苦笑)
2009/10/6
現状の実装で、最新のFreeBSD/pc98 7.2-RELEASEがどこまで動くか実験してみました。

フロッピーディスクを何度か入換えしつつ、起動中。


ブートメニューが表示されたので、Defaultでブートしてみます。
CPUが約1.8GHzの686-classと認識されています。

結局ブート中に一般保護エラーが発生して御仕舞いです。
まだまだ先は長いですね。
2009/10/5
FDISKを実行しても、IDE関連のI/Oにアクセスせずに「装置がありません」になってしまうのは、
そもそもブート前にドライブを認識してないのが問題なのかなあと。
その辺の検証のために、ITFからBIOSに処理が移るタイミングで、システム領域の0000:0457,
0000:055Dを書き換えて、無理やりドライブを認識した状態にしてみました。

HDUで一応ドライブの存在を認識できているようです。
でもちゃんと初期化を経ていないからか、シリンダ数や容量がおかしなことになっています。



DISKINITでドライブを初期化して、FDISKでパーティションを設定しようとすると、
run-time内で0割りが発生して強制終了してしまいました。
やっぱり容量を認識できていないと駄目なようです。


仕方ないので、ディスクイメージを直接バイナリエディタで書き換えて、無理やりパーティションを
作成してみたところ、一応はFORMATしてデータの読み書きが出来るようになりました。
IDEコア側の実装は問題なさそうなので、後は何故ブート時にドライブを認識できないかの追及ですね。
取り敢えず、CPUのトレースログを取ってみましたが…
あれ、ブート前にIDE BIOS内のコードを全然実行していない? あれ、あれれ???
2009/10/4-2

IDEの実装の検証中です。
ATAPI CD-ROMは正常に動作しているようで、MS-DOSから普通にアクセスできます。
純正のNECCD.SYSとMSCDEX.EXEで大丈夫です。
IDE HDDはまだ駄目です。
FDISKでも「装置がありません」とエラーメッセージが出てしまいます。
セクタサイズの問題かなとは思うのですが…
スクリーンショットでは判りませんが、地味にビープも実装しました。
2009/10/4

RTCについては、従来はuPD4990として実装していましたが、PC-9801BX4のBIOS側は
uPD4993Aとしてアクセスしており、時間を正しく取得できていませんでした。
uPD4993Aのデータシートを発見できなかったのですが、タイムリード時に0.1秒の桁?の
4bitをLSBに追加するのと、シリアルコマンドに対応してやることで、一応動くように。
常にホスト側の時間の値を返すだけで、ゲスト側の時間設定はできません。
sfish様にLGY-98のI/O周りの情報をご提供いただきました。
わざわざご調査いただき、ありがとうございます。
で、実装を修正した上で、LGY-98設定ディスクで確認をしてみました。
MELCHKを実行してみましたが、認識できてないみたいです。

LGYSETUPでもやっぱり駄目でした。
そもそもLGY-98のI/Oにアクセスしてないみたいですが、IRQ関係かなあ。
2009/10/2

ne2000-isaベースでLGY-99を実装してみました。
PicoBSD(98)で見てみる限り、認識している…のかな?

SENSE DEVICE STATUSで、ドライブの状態(ドライブの有無、ディスクの有無)に応じて
返るステータスを修正したり、ディスク交換時に割込みを発生させるようにした結果、
MS-DOS上でディスクの交換を検出できるようになりました。
DALKで試してみましたが、取り敢えず問題なく動いているっぽいです。
2009/10/1-2

CG WINDOWの実装を見直した結果、DALKで文字が表示できるようになりました。
そういやテキストもグラフィック画面に描画してるんでしたっけ(汗)
あとバスマウスもちゃんと動作しているみたいです。




フロッピーベースのPico BSD(98)も、何となくブートするようになりました。
ハードウェアの検出中に止まってしまうのですが、Ethernet関係かな?
NE2000の実装をベースに、LGY98をサポートすることを考えています。
2009/10/1
せっかくMS-DOSがブートするようになったので、てけとーにソフトの動作確認など。



だからって、何故これで動作確認するかなあ(苦笑)
文字が表示できていないですが、グラフィック画面は一応動作しているようですね。
2009/9/30
QEMU本家へのマージを目標に、コードの整理中です。
target-i386に統合して、-M pc98pciでPC-98x1を指定するようにしました。

FDCの修正の結果、MS-DOS 7がブートするようになりました。
現状では1.44MBフォーマットのフロッピーからのみブート可能です。
FDCがセクタ長512bytes固定なので、1.2MBフォーマット対応は難しそう。
2009/9/8
昨日の時点でROM BASICが起動中にフリーズしていたのは、
GDCのステータスの、FIFO EMPTYの挙動の問題だったようです。
従来の実装では、実行中のコマンドに必要なパラメタが全て入力されるまで
EMPTYじゃない扱いにしていたのですが、パラメタ数の多いコマンドなどにおいて、
パラメタ転送中でもEPTYになるまで待機するような場合に問題になってました。
取り敢えず、EMPTY立ちっぱなしにしたところ、ROM BASICが立ち上がって、
操作ができるところまでいきました。
ディスクをまったく読まずに、ROM BASICにいってしまう問題はありますが、
曲りなりにもブートしたのは目出度い限り。

FDC上で、SPECIFY+RECALIB+SENCE INTSTATコマンドを実行して、ドライブの有無と
ディスクの挿入チェックは出来ているっぽいのですが・・・
2009/9/7
FDCで、RECALIBを実行したあとのSENCE INTSTATの挙動を修正中。
取り敢えずN88BASICがブートしようとするところまで来ました。

…これで、やっと前回頓挫したところまで追い付いただけ(苦笑)
その他、TARGET_I386に寄生して実装していたのを、
コードをTARGET_PC98に分離して別バイナリにしたりしてました。
QEMUでは、同じCPUで異なるアーキテクチャのマシンを実装することを
余り考慮していないみたいで、TARGET_I386でCPUコアのコードを括ったり、
PC/AT仮想マシンのコードを括ったりしてるのが面倒です。
今回は、CPUコアを括っている部分の#if defined(TARGET_I386)を、
defined(TARGET_I386)||defined(TARGET_PC98)に置き換えて済ませましたが、
CPUの種類とアーキテクチャの種類を示すdefineを分離することを
提案した方がいいかもしれませんね。
2009/9/5
ITFも随分と処理が先に進むようになりました。
RAMウィンドウを実装することで、BIOSやIDE-BIOSを裏RAMにコピーして
そっちに切り替える処理も通るようになりました。
TIMER INTERRUPT ERRORの問題も、パッチなしで動作するようになっています。
後はプロテクトモードチェックが通れば、もうBIOSに処理が移るところまで
いきそうです。
で、ITFの処理を追っかけていて、起動時点での外字領域の値によって
実行される処理を幾つか見つけました。


ITFやBIOSの書き換え用ルーチン?
この処理に入る前に、やはり外字領域の値によって、FLASH ROMの電源電圧を
5Vから12Vに変更する処理もありました。


ハードウェア情報やBIOSのバージョンチェック。
こちらはそのままメモリカウントに移行するようです。
2009/9/3
前回のTIMER INTERRUPT ERRORで引っかかってるチェック処理。
xor ah,ah
sti
test ah,FF
jnz 849E
stiの直後に割り込みが発生することを期待してるんだろうけど、
この辺はQEMUのCPUとPICの実装次第だしなあ。
ということで、取り敢えずITFにパッチを当てて無理やり突破。
$B0000-$BFFFFのEMSは素直に実装。
VRAMと同じくメモリマップドI/O扱いなので、裏RAM上のコードを実行すると
クラッシュしてしまう筈だけど、まあ仕方ないですね。


うーん。
PC-98のA20ラインマスクって、PC/ATのようにA20だけマスクでなく、
A20より上が全部マスクという仕様で良かったでしたっけ?

起動時にA20ラインをマスクしないとエラー。
まあそりゃそうだろうなあ(苦笑)
2009/9/2
外字領域、不揮発メモリ、ソフトウェアディップスイッチの初期値を設定してやることで、
メモリチェックに進むようになりました。

EMSエラーはまだ未実装なので仕方ないですね。
TIMER INTERRUPT ERRORが発生するのはちょっと解せないです。
2009/8/28
PC-9801BX4をターゲットに仕切り直し。
現状では、正面からITFのハードウェアチェックを突破すべく、
少しずつ実装を進めているところです。

外字領域を何かしらのフラグに使っているようで、起動した時点で
然るべき値が入っていないとSET THE SOFTWARE DIP-SWITCHとなります。

こっちは描画処理の虫取りがまだ済んでいなかったときの画像。
TAKEDA, toshiya's HOME PAGE