開発メモ(思索ログ): へっぽこプログラマは日々こんなこと考えながらエミュ開発してます(笑) 2003/4/30-5/2 連休突入、実家に帰ってきました。 たごさんのサイトの掲示板に来られていた同郷の方から実機を譲って頂いたので、 早速FDC周りのフラグの挙動を調査してみました。 以下が確認プログラム。 試験に出るX1の、その筋な方のソースを大いに参照しています。 255-?とやっているのはビット反転のためです。 100 out &HDC,&H85 ' MOTOR ON 110 gosub 290 120 out &hD8,&HF0 ' RESTORE 130 gosub 290 140 out &HDB,255-&H10 ' SEEK TRACK = 16 150 out &HD9,255-&H0 160 out &HD8,&HE0 170 gosub 290 180 out &HDA,255-&H8 ' READ SECTOR = 8 190 out &HD8,&H79 200 gosub 290 210 out &HD8,&H3B ' READ ADDRESS 220 gosub 290 230 out &HD8,&H1B ' READ TRACK 240 gosub 290 250 out &HD8,&HF0 ' RESTORE 260 gosub 290 270 out &HDC,0 ' MOTOR OFF 280 end 290 print "[ "; 300 STAT=255-inp(&HD8) 310 print right$("0"+hex$(STAT),2);" "; 320 if STAT and &H81 then goto 230 330 print ":" 340 return Type-1はともかくType-2,3はBASICでは遅いだろうという意見もありそうですが、 データを読み込む訳ではなく単にフラグの挙動を見てみたいだけですので。 BASIC-M25上でフォーマットしたディスクの場合。 MOTOR ON [ A4 A4 .... A4 A6 24 : RESTORE [ 25 25 .... 25 24 : SEEK TRACK [ 21 21 23 21 .... 21 20 : READ DATA [ 01 01 .... 01 07 06 : READ ADDRESS [ 01 01 .... 01 06 : READ TRACK [ 01 01 .... 01 03 07 07 .... 07 06 : RESTORE [ 21 21 23 21 .... 21 25 25 27 25 .... 25 24 : アンフォーマットの場合はこんな感じ。 MOTOR ON [ b4 b4 ... b4 b6 34 : RESTORE [ 23 21 21 ... 21 25 25 ... 25 27 25 25 ... 25 36 : SEEK TRACK [ 21 21 ... 21 23 21 21 ... 21 32 : READ DATA [ 01 01 ... 01 10 : READ ADDRESS [ 01 01 ... 01 10 : READ TRACK [ 01 01 ... 01 07 07 ... 07 06 : RESTORE [ 21 21 21 ... 21 25 25 ... 25 27 25 25 ... 25 34 : MOTOR ONについて: ・ステータスはType-1系? ・ディスクの回転が安定するまで?はNOT READY。 ・HEAD ENGAGEDはつきっぱなし。 Type-1系のコマンドについて: ・HEAD ENAGEDはつきっぱなし。 ・トラック0のときはTRACK00がつく。 ・時々INDEXがつく。 ・アンフォーマットのときSEEK ERROR Type-2,3系のコマンドについて: ・セクタサーチ中はBUSYのみ。 ・READ DATA, READ ADDRESSのときは、アンフォーマット時にRECORD NOT FOUND。 ・非アンフォーマット時にLOST DATAになっても、まだREQUEST DATAは立っている。 ・RECORD NOT FOUNDでない限り一瞬busyは見せるべき? うむむ、うむむ。 取り敢えず、シークやセクタサーチに時間が掛かるようにするのと、幾つかの ステータスの挙動を変えてみたところ、結構色々なソフトが起動するように。 ウイバーン ... 起動可、但しスタートするとフリーズ カラー印刷キット ぱれっと ... 起動可、但し要マウス ゼビウス ... 起動可、但し4096色モードが色化け ドルアーガの塔 ... 起動可 マッピー ... 起動可 マルチプラン ... 起動可 電波新聞モノが結構動くようになってますが、デーモンクリスタルは相変わらず。 テグザーやウィザードリィが起動しないなどの副作用も出ています。 また、何時の間にかBASIC-M25上でFDDにセーブしようとするとアンフォーマット エラーになるという不具合が発生していたり。 中々、難しいですね。 まだまだ実機通りでないところがありますので、今後更に実装を詰めて行きます。 取り敢えず明日はシーク中にトラックレジスタが変化するところからでも。 あれが動かない、これが動かないというのは取り敢えず目を瞑って、挙動を実機に 近づけていくことだけを考えることにしよう。 究極に実機通りになれば、全部のソフトが動くはずなんだから。 2003/5/2 更にFDCの再現性向上を図る。 まずシーク中のトラックレジスタ、ステータスの変動を再現。 ちゃんと一定時間ごとにヘッダを動かして、uフラグが立っていればそれに応じて トラックレジスタやステータスのTRACK00も変動するように。 またインデックスホール検出は従来ステータスを読むごとに更新していたが、 これを時間経過に従って変動するようにする。 変動周期は、毎秒5回転、1トラック16セクタであることを前提に固定値。 これは変更した方がいいかも。 モータがすぐに安定して回転しないように、またすぐには止めないようにすると いうのはまだ未実装。 流石にここまでは要らない気がするけど、これもいずれ実装します。 ウィザードリィ、A列車で行こうが、シーク時のCRCエラーでIPLエラーを 起こしていたので、暫定的にこれを無効にする。 気持ち悪いけど、これで動かなくなるソフトは見当たらなかったので。 根本解決はまた後ほど。 ここまで実装したところ、テグザーが動かなくなっていたのが解消されました。 またBASIC-M25上でセーブしようとしてアンフォーマットエラーになるという 問題も解決しています。 電波新聞最後の牙城、デーモンクリスタルは相変わらずIPL無限ループ。 ウィザードリィはCRCエラー無効化で起動するようにはなったけど、相変わらず マスターディスクと認めてくれない。 ウイバーンもスタート後にフリーズ。これはFDCとは無関係かもしれず。 レリクスは・・・もうどうしてくれましょうか(苦笑) サウンドギャルなんかのように、トラックリードして何かしているプロテクト (多分セクタギャップでも読んでるんでしょう)については、D88フォーマットの ままでは対処できません。 これは、実機でトラックリードしたイメージを補助的に使用できるように しようかと考えています。 いっそそちらだけでもいいんですが、そうなると通常のセクタリードなんかの ときに取り回しが悪くなりそうでして。 2003/5/4 ゼビウスで4096色モード時に画面が化ける問題を対策しました。 テキスト8色が16色にどのようにマップされるかの解釈の問題でした。 で、4096色モードでプレイするゼビウスですが・・・ 美しいです。眼福眼福。 なるほど、これなら8bit機中最高の移植と言われるのも納得。 スクリーンショット用にちょっとプレイしてみたのですが、残念ながら 地上絵までは辿り着けませんでした。 ゼビウスといったら地上絵なんですが・・・すんませんです。 後はデバッグログの出力形式をちょっと変更したくらいです。 小修正ですが、ゼビウス対応は大きいので一応更新しておきます。 明日は通信ROMの吸出しをして、リザードのセーブ問題を調査したら荷造り。 明後日には会社の独身寮に戻らないといけないので。 リザードの問題解決。 インデックスカウントの更新処理のミスで、過剰に長い間インデックスホールを 検出しっぱなしになっていたのが原因。 取り敢えず従来の、ステータスレジスタをアクセスするたびに更新する方式に 戻して様子を見ます。 起きたので作業再開。 まずFDC周りの微調整。 シーク時のトラック番号のベリファイ動作について、最初のセクタのCだけと 比較していたのを、全セクタにわたって検索して、それでも一致するものがない ときだけシークエラーを返すようにする。 1トラック内に同一セクタ番号をもつセクタが複数あるような変態フォーマットの 場合、最初のセクタ以外読み書きできなかったのを修正。 これはリードアドレスと共通で、従来先頭から検索して最初にみつかったセクタ のみアクセスしていたのを、直前にアクセスしたセクタの次から検索を開始する ようにしただけ。 インデックスホールの検出を再度経過時間によって行うようにする(但しホールを 検出するのは一瞬だけ)と共に、検出後セクタの検索開始位置を初期化する。 これによって、インデックスホールを探してそこから順番にセクタにアクセス するようなソフトの場合にうまくいくかもしれない。 これらの修正しても特に動くようになるソフトがあった訳ではないけど、別段 害にもなってないようの、で取り敢えずそのままにしておきます。 通信ROMの吸い出し。 peek@してシリアル出力するいつものやり方で、これはさくっと終わらせる。 マウスの実装の方針。 マウス使用中はマウスカーソルを非表示にして、画面中央(320,200)に移動。 各フレーム毎に、(320,200)からの移動量とボタンの状態を取得して、 マウスクラスに与えてやる。 その上でまた(320,200)にカーソルを移動する。 カーソルを常に中央に持ってくるのは、ボタンを押したら別ウィンドウに 切り替わってしまったということを防ぐため。 またMZのマウスは前回からの移動量を使用するので、1フレーム中の移動偏差 という形の方が扱いやすいということもある。 マウスの有効無効はショートカットキー(CTRL+RETURN)で行うことにする。 で、取り敢えずWin32側の実装から。 ショートカットキーを追加するのと、マウス有効になったらカーソル消して 画面中央に移動、無効になったらマウスを表示するようにする。 ついでにALT+RETURNでウィンドウ・フルスクリーン切り替えも実装しておこう。 2003/5/5-6 独身寮に帰還。 明日からお仕事、だるー。 マウスの実装の続き。 vmクラス内で、1フレームCPUを回す毎に、カーソルの座標偏差とボタンの状態を 取得してマウスクラスに送信、カーソル座標は中心に戻す。 マウス無効の場合は移動量0、ボタンは押していないものとして扱う。 Z80SIOの実装は1から仕切り直し。 必要最低限の部分だけ実装するかわりに、それなりに作り込むことに。 マウスへの送信要求はDTRをH->Lに切り替えることによって行う。 (これは回路図をおっかけて判りました。X1だとRTSらしいですが) 送信条件も考慮して、WR3=c1,WR4=44,WR5=68->e8、で送信要求と判定。 本当は条件おかしくても送信するだけして、受信エラーにした方がいいのかも。 送信内容は4800bpsで10bit×3ということで、要求があってから12500クロックで 最初の1バイトを受信、残り2バイトも12500クロックおきに受信する。 このとき受信成功でキャラクタ受信割込み有効だったらIRQ。 バッファが既に4バイト埋まってるとオーバフローでIRQ。 後はWR0のコマンドなんかを実装したり、バッファの状況によってRR0,RR1の ステータスを変えたりと色々。 こんな感じで、取り敢えず星くずばこでマウスが使えるようになりました。 ただBASIC-M25上でMOUSE 0とやると、暫くしてフリーズしてしまいます。 またぱれっとでは割込みが掛かるとフリーズ。 まだ何か問題があるのでしょう。 この辺は、後日設定でマウスが繋がっているかどうかを設定できるようにします。 2003/5/7 ムーンチャイルドが動かない問題の調査。 マルチセクタなリードデータで指定された個数だけセクタを読み込み、フォース インタラプトでコマンド中断。 その後何故かまたレストアして同じトラックをリードデータ、を繰り返している。 CPUをトレースしてみると、どうもフォースインタラプト後に一定期間待機して、 ステータスが0でない場合はリトライするらしい。 という訳で、フォースインタラプトして一定期間経過後は、別のコマンドを実行 するまでステータスに0を返すようにしてみる。 一定期間、は根拠レスで暫定的に100クロックとする。副作用は後日調査。 ムーンチャイルドで取り敢えずディスク読みっぱなしの現象は改善されました。 キャラクタ作成も可能ですが、ゲーム開始後は乱れたマップが読み込まれます。 まだ何か問題があるのでしょう。 で他のゲームについても動作確認してみたところ… うおおおお、レリクス動いたー!(大歓喜) 2003/5/10-12 九玉伝にて、テキストマスクがおかしい件。 どうも400ラインモードにもかかわらず、200ラインモードでの値が指定されて いるのが原因の模様。 現に200ラインモードで実行した場合は特に問題がないっぽい。 取り敢えず、専用パッチとしてPC=C27Ehのときにtextreg[3]=26h,textreg[5]=EEhと いう値が書き込まれた場合は、textreg[3]=11h,textreg[5]=D9hと補正することで お茶を濁す。 nesterのときは日常茶飯事だったけど、専用パッチに手を出すというのは敗北を 認めるみたいで嫌やなあ。 本来はなぜモニタの種類が正しく認識されないのかを調べるべきなんだけどねえ。 一部ソフトにおいて、ミシン目みたいな描画の乱れが出る件。 例えば殺人倶楽部の会社ロゴとか、200ライン時でのBASIC-M25の計算機など。 これは単純に実装ミス。 80カラム時でモノクロフォントでサイズが8x16のときに、パックドのフォントを ビットに変換する処理において、bit0が抜け落ちてました。 なんでこんなポカミスに気付かなかったんだろ。 右下の「ロ」のキーが効いていなかった問題。 これは仮想キーコードの値をVK_OEM_102に変更するだけで解決。 ついでに他のキーについても調べてみましたが、特に問題なさそうです。 三国志が起動しない件。 I/Oのログを取ってみると、どうもvblank待ちを延々としている模様。 ただ垂直表示範囲が0-456とおかしな値になっているため、いつまでたっても vblankにならない。 垂直表示範囲は、GDEVS=cgreg[8]-[9]、GDEVE=cgreg[a]-[b]となっているが、 下位バイトだけ書き換えて上位バイトを修正しないため、このようなことに なっている。もしかして、下位バイトを書き換えると自動的に上位バイトは 消去されるのかもしれません。 取り敢えず、cgreg[8]を書き換えるとcgreg[9]=0、cgreg[a]を書き換えると cgreg[b]=0、とするようにしたところ、一応三国志が起動するように。 ただ乱数の初期化をはじめたところで止まってしまいます。 ・・・まさか2000年問題じゃないだろなあ(苦笑) 信長の野望全国版も一応起動、ただKOEI PRESENTと出てディスクを読みに いったまま帰ってこない。まだ問題があるみたいです。 レイドック。 何故かドライブ1から起動したのに、途中からドライブ3を読みにいってしまい、 そのままドライブレディを待ち尽くしている模様。why? 暫定的には、ドライブ1〜4全部にディスクを突っ込めば一応ちゃんとプレイは できるみたいです。 その状態でログを取って見ると、なんかドライブ2を読みにいってみたりも。 もう訳わからん。 直前にドライブ選択信号にd4とかd6とか出力しているのが気になりますが、 回路図おっかけてもb0-3,b7しか関わってないはずですし。うーん。 あーそう言えば、FM音源内にドライブ1,2と3,4を入れ替えるレジスタが ありましたっけ。ログを取ってみると確かに反転処理をしています。 で実装してみたものの、今度は全ソフトが起動すらしない。 取り敢えず、これまた暫定的に専用パッチを仕込んでお茶を濁しておきます。 必ずドライブ1からブートしてください。 閑話休題、本日の変なメール。 「ナムコシステム2のROMはどこで落とせますか?」 ・・・あのー、何故俺にそんなこと訊こうと思ったんでしょう(苦笑) 2003/5/12-13 信長の野望全国版が、ディスクを読みにいったまま帰ってこない件。 ログをとってみたところ、延々とリードアドレスを繰り返している模様。 で更に調べてみると、いつも同じセクタのアドレスばかり読んでいる。 多分、ステータスでインデックスホール検出するまで待って、それからリード アドレスを実行しているのではないかと。 現在のソースでは、インデックスホールの検出とリードアドレスで発見する セクタが同期しているため、そういうことになる可能性はあり。 で、インデックスホール検出用のカウントと、アドレスやセクタのサーチ位置 カウントを分けることで、信長の野望が無事動作するようになりました。 但し、私の手持ちのディスクではCRCエラーが発生していたため、CRC無効にする 必要がありました。 場合によっては副作用があるかもしれません。 動かなくなったソフトがあったらご連絡ください。 三国志。 こちらも何時の間にか動作するようになってました。 何で変数の初期化でフリーズしていたのか不明のままで気持ち悪いですが、 まあ動いてしまったものは仕方が無いということで(苦笑) ウイバーンがタイトル画面後にフリーズする件。 どうもFM音源のチャンネルA, B, Cにノイズ・トーンを出力しないようにして、 ステータスを延々と読みつづけている。 とは言え逆アセンブルしてみても、ステータスで見ているのはmsbが立っているか だけで、その後の処理には特に影響していなさそう。 何かしら割り込みが掛かるのを待っているのかもしれないです。 取り敢えず保留。 リグラス。 一旦サイトを更新してから気付いたんですが、これも動くようになっています。 どうもプロテクトとしてCRCエラーをわざと発生させているようです。 CRC無効にしていると、IPLに戻ってしまいます。 あとユーザの方より頂いたご報告。 昨晩の更新で、ROBOWRES 2001、NOBO等が動作するようになった由。 うむ、めでたい。 いやはや、連休に実機を譲って頂いて以来絶好調です。 と実にいい感じのところで、本業が突発的に忙しくなりそうでして。 明日から暫く更新ペースが落ちるかと思います。 とにかく総合オフ会の日の休日だけは絶対死守しないと。 2003/5/18 体調崩し気味。げほがはぐへ。 CPUの各ニーモニックの実装について、LDIRなどの繰り返し命令の途中でも 割り込みが掛かってしまうようになっているのが不安定の原因でないかと 思い立ち、確認してみる・・・あんまり変わらないね。 FDCで、RECORD NOT FOUNDになっているのに意味もなくLOST DATAになってしまう 可能性があったのを修正。これまた特にかわった様子はなし。 ソフト更新はひとまず置いて、動作確認。 ムーンチャイルド。 これ動かない訳ないんだけどなあ、ということでイメージを吸い直してみる。 ・・・動くやんけ(苦笑) 夢幻の心臓2。 実機でフォーマットしたブランクディスクのイメージを用意しておけば、 エミュレータ上でもユーザディスクを作成できることを確認。 ゲーム自体についても特に問題はなさそうな感じ。 2003/5/24 MZ総合オフ。 堪能しました。 まるくんさんのJAVA版MZ700エミュレータのデモを見せて頂いてまず感動。 十分すぎるほどの速度が出ていたことに吃驚しました。 権利関係さえ克服できれば、色々と応用できそうですね。 たごさんのイメージ操作ツール、開発に役立たせて頂きます。 Oh!石さんやまじろじさんの秘蔵資料の数々。眼福眼福。 たごさん、まじろじさん、Oh!石さんはじめ、普段お世話になっている方々と 直接お話できて、嬉しかったです。 それにしても、集まるも集まったり24名。 新世紀に入ってなおこれだけのMZファンが活動しているとは。 潜在的にはもっともっといらっしゃるのでしょう。 遅れてきたMZ党員として、本当に心強いです。 ちょくちょくお会いしてますが、チームMZの皆様。 これからも頑張りましょう。 2003/5/28 熱は無いのですが、どうにも咳が止まりません。 咳のし過ぎで腹筋が痛いという間抜けな状態になってます(汗 それはさておき、FDCを小修正。 キングフラッピーで、どうもアクセスするトラックが1つずれているような挙動を 示していることが気になって、シークコマンドをちょっと修正してみました。 結果ですが、効果絶大。 キングフラッピー、アビス2、トリトーンが動作するようになりました。 副作用が怖いのですが、軽く試した限りではとくに問題はおきていないようです。 という訳で、作業時間10分程度なんですが更新しておきます。 2003/5/30 トリトーンは10キー操作なんですが、下が2ではなく5になっています。 珍しいですが、確かにその方が操作しやすいかも。 ということで、ジョイスティックによるキーボードのエミュレーションに、 4/5/6/8による4方向操作も追加しておきます。 2003/6/6-7 電波新聞社のデーモンクリスタル、何時の間にか起動するようになってました。 ただ256色モードだとキャラが表示されないという不具合が残ってます。 これは256色モードにおいて、グラフィックとテキストのパレット優先設定が 実装されていないからです。 16色のパレットについてのみ優先順位を指定する方法しか判らなかったため 今まで放置していたのですが、MZ-MLで質問したところ >256色モードは16色モードの2枚重ね?なのですが、 >上のプレーンのみパレット/プライオリティーの影響を受けたはずです。 と教えて頂きましたので、これにあわせて実装を修正しました。 グラフィック256色/テキスト64色の画面生成処理を根こそぎ修正することに なったのですが、今のところ特に副作用はでてないようです。 あと、イース3で画面が乱れるという問題がありました。 これもプライオリティの問題で、テキストの不透明な黒色が、常に最優先に なっているというのが原因でした。 これも一緒に修正しています。 ciscさんが新しいfmgenを公開されていたので、これも早速反映。 私の耳ではどこが変わったのかよく判らないのが申し訳ないんですが、 本当にいい音です。 2003/6/8 いよいよカセットテープの音声再生に挑戦。 曲ごとに複数のファイルに分割して、mciで再生する方針でいきます。 DirectSound経由でいくのがスマートなんだろうけど、周波数変換面倒だし、 mp3再生するのも大変そうなので。 まずwavファイルの分割ツールの作成。 先頭から1/64秒単位で左側の音声を取得して、全体の1/8がabs() > 10000と なった場合は、頭出し用のピッという音だと判定。 で、全体の分割をしたところでファイルに出力するように。 この辺は、昔wavファイルを生成するツールを作成したことがあるので、 割とさくっと完成。 カセット側の実装。 早送り・巻き戻しの場合、音声部分は0.5secで進む。 通常再生時はmciで指定のファイルを再生。 曲間はAPSSの頭出し用に、0.5secだけ読み出しデータをHにする。 テープの先頭や終点に行った場合は、設定によっては自動再生・巻き戻しを 行うようにする。 テープがない場合は、従来通り「カセットは入っているけどテープは回って いない」という状態にする。 こんな感じで、意外とあっさり再生できるようになりました。 デモディスクで確認した限りでは、頭出しや曲の終了判定も正常にできて いるようです。 #EXMAN親父、「すっからかんだって、はっはっはっ」って(苦笑) という訳で、遂に野望達成。 長らくお待たせしました>けんじょさん 2003/6/9 fmgenが更新されていたので反映しました。 お疲れ様です>ciscさん、PI.さん 2003/6/12 basic-m25のデモですが、カジノで遊ぶと最後のexman親父のところで テープが再生されないようです。 一瞬再生に行くのですが、すぐに停止してしまっています。 テープ上の現在位置をfloatにして、曲の境目の直前にいるのか直後にいるのかを 表現できるようにしたのと、曲間のギャップのデジタルデータのタイミングをより 正確にしてみましたが、改善されず。 iocsをフックしてapssをwindows側のコードで実行するようにしてみても、やはり 改善されず。 うーむ、難しい。 取り敢えず、iocsのフックは副作用が怖いので、外しておきます。 2003/6/17-18 WinCEではGetKeyboardState()が使えないみたいなので、WM_KEYDOWN/KEYUPで キーボードの状態を取得するように変更しました。 パフォーマンス的には特に変化はありません。 また、MZ側のキー入力の状態更新を、従来のキー状態読込み時から、rowアドレスの 変更時に行うように変更しました。 irqの発生タイミングは実機に近づいたとは思いますが、特に動くようになった ソフトがある訳ではないみたいです。 ウィバーンが動くようにならないかなと、ちょっと期待してたんですが(苦笑) あー、九玉伝が心なしか軽くなっているかも。 多分気のせいだと思いますが。 2003/6/18 wavecut、切り出し時に前後の余白がまだ大きいっぽいので、現行の前後0.5secから 前後2secを除くように仕様変更。 ・・・テープ再生機能、使ってくださってる方、いらっしゃるのだろうか(苦笑) キーボード周りを徹底修正。 ポートAのIRQを使用しているソフトがあるかもしれないので、ポートA, Bともに Z80PIOの一通りの機能を実装しました。 イース3でFM音源が鳴らない件。 単純に、fmgen内のタイマを進めるのを忘れていたため、ステータスでタイマの オーバフローフラグが立たなかっただけでした。この間抜けめが。 蒼き狼と白き牝鹿でpaintがはみ出す件。 リードモディファイライトで4プレーン同時に読み込んだ際に、ラッチに入る 値の解釈が間違っていたようです。 口説き方教えますでグラフィックが乱れる問題も一緒に修正されています。 デモディスクのラインダンスも、色化けについては直っているようです。 後は表示位置がおかしいのをなんとかできれば・・・ 2003/6/20 ぱれっと等では、Z80SIOからIRQが掛かるとフリーズしてしまう。 という訳で、暫定的なパッチとしてIRQの有効/無効の切替をサポートしてみる。 ・・・ぱれっとの場合、結局画面真っ白で駄目なんですが。 印刷をWin32API経由で行う実験。 GetProfileString("windows", "device", ",,,", buf, sizeof(buf)); で標準の プリンタ名を取得して、OpenPrinter(), StartDocPrinter(), StartPagePrinter(), WritePrinter(), EndPagePrinter(), EndDocPrinter(), ClosePrinter() とやれば いけるかなあと思ったのですが、駄目。 どうもANK文字以外はJISにしないと駄目なんだとか。 これは取り敢えず保留ということにする。 2003/6/21 禁断症状に耐えかねて、新宿中村屋へコールマンカレーを食べに行く。 今日はそんな一日。 2003/6/22-23 vm経由でconfigを弄るというのがどうにも気持ち悪かったので、configを グローバル変数化して、iniファイルの操作も一元化することに。 winceではiniファイルの操作ができないから、この場合は構造体まるごと ReadFile(), WriteFile()すればいいかな。 現在CPUからメモリアクセスする際は、parent_VM->memory->ReadMemory()と 2つもクラスを経由しているため、処理速度的に損をしていると思われる。 この対策として、memoryクラスをcpuクラスに移管することを検討中。 設計としては今の方が判りやすいと思うし、基本的に私は高速化のために工数を 掛けることを嫌うタイプなんですが(そのうちPCはもっと高速化しますから)、 将来winceに移植することを考えると、出来る範囲で高速化は図っておきたい。 まあやってみて、効果が顕著であればそのままということで。 でやってみた・・・変わった感じなし。 ついでに、通常のメモリエリアかリードモディファイライトか、の判定で 条件分岐が入っているのが嫌なので、関数のポインタを試してみる・・・ 却って遅くなってる。 という訳で、元に戻すべし。 後はwinceへの移植のための作業を幾らか。 UNICODE対応と、ファイル操作関係をWin32APIに変更する。 ファイル操作の方は、適当なラッパ関数を作って、できるかぎり標準関数と 直接置き換えられるようにする。 但し、カセット再生部のリスト読込み辺りは、fgets()を作るのが余りに 面倒なんでそのまま放置。どうせwinceではmci使えない訳だし。 2003/6/23-24 「EmuZ-2500/sigmarion III」計画、発動。 取り敢えずeVT3.0とH/PC 2000 SDKをインストールしてみる。 方針としては、 ・HPC/2000で開発、但しキーボードや解像度の関係でsigmarin3以外は考慮しない。 ・コンパイルオプションを使って、極力ソースは共通化する。 ・winmain.cppだけは余りに違うので別ソースとする。 ・FM音源、カセット再生、プリンタ、ジョイスティックは未サポート。 ・timeGetTime()はGetTickCount()で代替(精度については目を瞑る) ・iniファイルを使えないので、設定はconfig構造体丸ごと保存してやる。 という訳で、早速プロジェクトを作成してコンパイル。 164エラー、おお、以外と少ない。 その後、winmain_ce.cpp以外は修正して、83エラー。 後はひたすら修正あるのみ。 取り敢えずコンパイルが通るようになったので、実機で実行。 ・・・なんか画面すら出ない。 コードを追っかけてみたところ、Sleep(0)のところでおかしくなっている。 Sleep(10)くらいにしたらいけるらしい。なんでやねん。 で色々やっているうちに無事起動するように。 しかし重たい。多分実機の1/10程度しか出ていないっぽい。 という訳で、高速化にいそしんでみる。 先日やって効果がなさそうだった、メモリクラスをCPUクラスの統合。 これは復活してみると結構効果があった。 どうもXScaleは型キャストするときのコストが大きいらしいので、あちこち無駄に 型キャストしていたところを修正、概ね安定して20%程度の速度が出るように。 まだ探せば高速化する余地はあるかもしれない。 また、どうせフルスピードは出る訳ないので、速度調整機構は削除してしまう。 画面を切り替えたりメニューを開いた後、画面がうまく更新されないという問題。 これは、WM_PAINTの処理の中でvm->UpdateScreen()を実行しなければ問題ない ようなので、適当にフラグを用意して必要なときだけ実行しないように。 あと10キーがうまく働かないようなので、カーソルキーで10キーをエミュレート できるようにしてみる。設定はジョイスティックでのエミュレートを流用。 ダイアログが正常に表示されない問題について、WinCEではグループボックスを 先に作成すると、上に乗っているコントロールが表示されないらしい。 これは直接リソースファイルを弄って修正してやる。 こんな感じで、一応完成。 2003/6/25 引き続き、高速化。 周辺デバイスの内、無駄に高い時間精度で駆動していたものについて、もう少し 駆動頻度を落としてやる。 また、sigmarion3で使用しないデバイスについては、機能を無効にする。 これで大体28%前後まで高速化した。 Win32版でもそれなりに高速化しているかもしれない。 2003/6/26 引き続き、高速化。 従来CPUのクロックは、8dot辺りの実行クロック数2.27というのを正確に表現 するためにfloatにしていたが、これをint型にして、32dot単位で9クロック実行 するように変更した。 また、周辺デバイスの駆動クロックも同様にfloatからintに変更。 この結果、著しい高速化を達成することができました。 /sig3で、平均55%の速度が出るようになっています。 Win32版でも、明らかに速くなっているのが体感できるかと思います。 これだけの速度が出てれば、テグザー辺りでも十分/sig3で遊べそうですね。 微妙に精度が落ちてますが、今のところ副作用は出ていないようです。 2003/6/27 ROMファイルなどのファイルパスを、ダイアログから出来るようにしてみました。 従来でもiniファイルを書き換えれば、実行ファイルからの相対パスで指定 できてたのですが、/sig3だと設定ファイルがバイナリなので、流石に直接 書き換えろというのも無理ですから。 ダイアログのフォントはMS Sans Serifを使っているので、パスにマルチバイト 文字が混じってると文字化けします。 が、/sig3だと化けない。さすがUNICODE対応。 2003/6/29 /sig3だと反応が遅いため、キーは暫く押しっぱなしにしないと入力されない。 これだとBASIC上でコマンド打ち込んでると文字抜けが発生するので、一旦 押したキーは最低3フレームは押された状態を維持するように仕様変更。 (これは/sig3版のみの限定仕様) 2003/6/30-7/2 テキスト画面の描画、1文字の描画の処理というのは結構馬鹿にならない重たさ なのですが、実際のソフトでは結構テキスト画面を殆ど使っていないものが 多い訳で、いちいち馬鹿正直に80x25文字も描画するのは無駄だろうと。 で、空白部分については描画処理をとばすことで高速化を図ってみることに。 まず、vramの空白部分にどのようなデータが書き込まれるのか、各ソフトごとに 調査をしてみました。 - TVRAM1[] = 0x80, TVRAM2[] = 0x8c, ATTRIB[] = 0x07: 英雄伝説サーガ、殺人倶楽部、ロボレス2001、信長の野望、A列車、 リバース、テグザー等、多数(IPL標準の消去) - TVRAM1[] = 0x80, TVRAM2[] = 0x8c, ATTRIB[] = 0x00: トリトーン、リグラス - TVRAM1[] = 0x81 or 0x82, TVRAM2[] = 0x8c, ATTRIB[] = 0x07: ムーンチャイルド - TVRAM1[] = 0x80, TVRAM2[] = 0x8c, ATTRIB[] = 0x08: イース3 - TVRAM1[] = 0x81, TVRAM2[] = 0x81, ATTRIB[] = 0x06: レリクス - TVRAM1[] = 0x02, TVRAM2[] = 0x80, ATTRIB[] = 0x07: オービット3、九玉伝 - TVRAM1[] = 0x00, TVRAM2[] = 0x80, ATTRIB[] = 0x06: NOBO ふーむ、結構まちまち。 とりあえず色々試行錯誤した結果、 if((tvram1[src] & 0x7c) == 0x00 && (tvram2[src] & 0xfe) == 0x8c && (attrib[src] & 0xf8) == 0x00) return; if((tvram1[src] & 0x7c) == 0x00 && (tvram2[src] & 0xfe) == 0x80 && (attrib[src] & 0xf8) == 0x00) return; という条件であれば、目に付く誤爆なく空白を弾けられるようになりました。 (イース3については空白部分でもPCGを指定しているため、今回は無視) /sig3で8フレームスキップで大体実機並の速度が出るようになっています。 ゼビウスやエキサイトバイクのように、画面一面にPCGで背景を表示している ようなソフトだと効果ありませんが、それは流石に仕方ないです。 BASIC-M25のデモにおいて、ラインダンスがずれて描画される件。 画面開始アドレス>スクロールエリア終了アドレスと指定されているのが原因。 どう考えてもこれは指定自体がおかしいんですが・・・ パッチとして、このような場合は画面開始アドレス-0x40E0とすることで対応。 0x40E0という値は、描画のずれの大きさから算出した実測値です。 正しいのかどうかは判らないですが、まあ違和感なければ良しということで。 あとは、イース3で垂直方向の画面マスクがずれていたのを修正しています。 2003/7/18 取り急ぎ、帰省前に一回バージョンアップしておきます。 何日に何をやったのか忘れてしまったので、作業内容は纏めて書きます。 Intel謹製のXScale最適化コンパイラが出てたので、試用版を試してみる。 コンパイル自体はそのまま通ったものの、実行してみるとフリーズ。 むーん。 色々試行錯誤して判ったのは、どうもmemset()で落ちてるらしいということ。 標準関数なのがあかんのかと思ってZeroMemory()やFillMemory()に置き換えて みたものの改善せず。 結論としては、サイズが大きいとだめらしい。 また落ちないまでも、値が入らないことも。 大体64KBずつならば問題ないようなので、サイズが大きい場合は分割して 初期化することで対処する。 で、速くなったのかというと・・・んーどうなんだろ。 55000円と結構な値段なんで、実際に購入するかどうかは保留します。 クロック可変機能を追加。 4MHz〜20MHzまで、0.66MHz単位で切り替えることが可能です。 但しCPU内だけのクロック変更ですので、VSyncやタイマにあわせて駆動している ようなソフトでは全く速度に変更無しです。 ジョイスティック。 取り敢えず、トリガ3, 4でトリガ1, 2を連射するようにしてみる。 要望のあった入れ替え機能はまた次回。 仕事でDirectShow関係の開発をしていたので、それを生かしてスーパー インポーズ機能の実装を実験してみる。 DirectShow関係の処理は全部DLLに纏めておいて、それを使って画面上に キャプチャした映像を表示できるところまでは実験済み。 内容的には、普通のキャプチャなコードにサンプルグラバを追加して、 DIBSectionをバッファ領域として画像を取ってきて、それをStretchBlt()で 持ってくるだけ。 MZ側は、4096色モード時に黒色部分がスーパーインポーズ画面になるという 解釈でいいのかな? これも最終組み込みは次回。 不安定問題、とうとう解決しました(大歓喜) 原因はZ80コアの割り込み周り。 実際はEIを実行したら、その次の命令を実行してから割込みが有効になる べきなんですが、これがすぐ割込み許可してしまっていました。 てっきり仮想マシン側の問題だと思っていたのですが、これは盲点でした。 トラ技スペシャルのZ80特集号を徒然に読んでいて気がついたんですが。 あの不安定の権化のようなテトリスや星くずばこシリーズだって安心。 最近リザードがフリーズしがちだったのも解決。 これでやっと、実用に耐えるレベルにまで達することができました。 追記。 config構造体の内容が変わった影響で、/sig3の設定ファイルの互換性が なくなっています。 私以外にユーザがいるかどうか不明なんですが、もし試される場合は 一旦mz2500.cfgを削除してください。 2003/7/19 家族で奈良見物。 薬師寺の面白いお坊さんがお亡くなりになったのは聞いていたのですが、 ちゃんと漫才の伝統を継ぐお弟子さんがいらっしゃったのは嬉しい限り。 ドイツ人の方よりメールあり。 非XscaleなポケットPCで不具合があったようです。 なんか却って遅くなってますし、MS純正のコンパイラに戻すことにします。 しかしまあ、ドイツにもMZ-2500ユーザが居たんだなあと驚き。 現状ではsimarion3に特化してしまってるんですが、やっぱりポケットPCにも 対応した方がいいんでしょうか・・・ sig3版も、私以外に使っているという話を一度も聞いたことないんですが。 2003/7/20 という訳で、スーパーインポーズ対応。 4096色モード時に、RGBI=0000の部分にキャプチャデバイスからの映像が透過 されるようになります。 専用ディスプレイテレビのMZ-1D24は200ライン専用だったような気もする のですが・・・まあ、機能自体に需要があるとも思えないですし。 CPUコアを弄ってて気付いたのですが、何故かM1サイクルにウェイトが掛かって いませんでしたので、さくっと修正しておきました。 BASIC-M25のデモで、テープと画面のタイミングが概ね合うようになってます。 ジョイスティックのボタンの入れ替えは、もうちょっとお待ちください。 今後の展開ですが、各デバイスの実装も安定してきましたので、そろそろ 中断セーブの実装を考えています。 別段そう難しいものでもないですので、仕様を確定したらなるたけ早い内に 実装するつもりです。 その次の課題は、プリンタ関係ですね。 今はVBを使った外部プログラムを使うというインチキ実装になってしまって いますので、それは何とかしたいところです。 それ以外の大物というと、やはり優音の対応でしょうか。 是非やってみたいネタではあるのですが、HD64180の資料が手元にないのと、 作業の重たさの割に、余りに需要がなさそうなのが何とも。 ボイスボード対応は考えてはいるのですが、実デバイスを持っていないのと、 持っていたとしても結局はROM外して直接イメージ吸い出すしかないのが ちょっと敷居が高すぎるんですよねえ。需要についても?ですし。 ボイスコミュニケーション機能ですが、流石に電話絡みの機能は色々と問題を 孕みそうですので、怖くて手を出せないです。 MZ-80B/2000モードは、最初から手を出すつもりはありません。 いっそ、EmuZ-3500という無人の荒野を開拓するというのも魅力的。 そんなとこ開拓しても他に誰も住み着きそうにないですけど、8ビットなMZを 征服し尽くしたいという野望は中々捨てがたいものです。 実機やソフト、技術資料を(相場はわからないですけど)適価で譲って頂ける方が もしいらっしゃいましたら、是非ご連絡ください。大まじめに検討中です。 2003/7/22 中断セーブを実装しました。 全ソフト共通で、1〜4スロットが用意されています。 実装自体は単純で、メモリやCPU内部情報、各デバイスの内部状態を書き出し、 書き戻しするだけです。 また現在挿入されているディスクのファイル名を保持していますので、再開後は 自動的にディスクが挿入されるようになっています。 但し、全てのデバイスについて処理している訳ではないので、場合によっては 不安定になる可能性があります。 特に、ディスクアクセス中の中断セーブは避けてください。 またFM音源内のデータは全く保存されませんので、再開後はBGMが途切れてしまう 可能性があります。(というか、途切れない可能性もある程度) 2003/7/23 まず最近の修正の尻拭いから。 BASIC-M25のデモのラインダンスで描画ずれが発生する問題のパッチが、 殺人倶楽部のメーカロゴの描画で誤爆していました。 これは、パッチの適用条件を厳しく判定することで対策しておきます。 CPUのM1サイクルにウェイトを入れるようにしたところ、アビスII 帝王の涙が Device I/O Errorで起動しなくなってしまいました。 これについては、設定でウェイトの有無を切り替えられるようにすることで 対処しておきます。 次、中断セーブ機能。 再開後にFM音源が鳴らないのは寂しいけど、fmgen内部の値を保存・復帰するのも 余りに大変そう。バージョンアップ後はまたやり直しだし。 で、出力したレジスタの値を控えておいて、再開後にそれを出力することで設定を 再現するという方式を考えてみる。 で、やってみた。 んー、確かに音はなるけど、何か音程が高くなってしまうなあ。 という訳で、FM音源のレジスタの仕様を調べてみる。 まず、2Dh〜2Fhのプリスケーラの設定は、最後にアクセスしたアドレスのみ 出力すればよいらしい。 また28hは、下位2bitでチャンネル毎の設定をするようになっているため、 各チャンネル毎に値を控えておく必要があるっぽい。 同様に、A0h〜AEhもb3〜b5でブロック毎に設定するようになっているため、 こちらも各ブロック毎に値を控えておく必要があるっぽい。 以上で、大体問題なく演奏を再開できるようになったようです。 またEMMは従来保存していませんでしたが、星くずばこで積極的にEMMを活用して いますので、こちらも保存するようにしておきます。 但し、綾波仕様で16MBのサイズであっても、先頭640KBまでしか保存されません。 なお、以上の修正の結果、従来のバージョンのバックアップデータとは互換が 取れなくなっていますのでご注意ください。 一応ヘッダにバージョン情報が入っていますので、バージョン違いのデータは 読み込めないようになっています。 あと内部的なこと。 諸般の事情により、またメモリ関係をメモリクラスに分割しました。 処理速度は体感ではそれほど変わらないみたいなんで、まあ良しとしよう。 本日で連休も終わり。 明日からまたお仕事です。だるー。 2003/7/25-26 I/OポートのE2hのb2にある、ダイレクトサウンド出力の対応を考えてみる。 専用バッファを用意しておいて、一定周期で書き込みポインタをインクリメント しつつ書き込み。 FM音源側とはDirectSoundのバッファに書き込むときに合成、この際DirectSoundの 周波数に応じて読み込みポインタを適宜インクリメントする。 読み込みポインタのインクリメントはHSyncに1回程度でいいかな。 この場合、サンプリング周波数は55.4*440=24376で24.376KHzとなるので、 理屈の上では約12KHz程度までの音であれば再生可能ということになる。 という訳で、適当に実装してみる。 この機能を使っているソフトとしては、例えば星くずばこ12号の百人一首が あるが、実際に試してみると人間の声程度なら結構それっぽく聴こえるのは驚き。 但し、CPUで直接パルスを生成しているため、CPUのクロックを標準の6MHzから変更 していると、音がおかしくなるかもしれないので注意。 ・・・えと、修正です。 百人一首、別の方法でPCM再生してました。 更に、E3h経由でポートCの出力値を変えた場合の対応を忘れてました 駄目じゃん>私 で、いらんとこでプチプチ言って五月蝿いので、E2h直叩きは無視して、E3h経由で 叩いた場合のみ再生するように変更しました。 実質、星くずばこ特別号のおしゃべりBEEP専用です。 2003/7/27 とある筋よりPocketPCに対応するべしと強い圧力掛かってまして(苦笑) 結局土曜にカレー食いに上京したついでにE-3000を買ってきました。 という訳で対応作業を進める。 PocketPCの画面サイズは240x320なので、640x400の画面を200x320に縮小する 必要がある。 これについては、回転を伴うのとStretchBltで縮小した画質が酷かったので、 自前で縮小処理を行うようにする。 処理の内容は、4ドットのRGB各々の平均をとるだけ。 16x16の漢字なんかでも、結構それなりに認識できるようです。 タスクバーは邪魔なので、FindWindow(_T("HHTaskBar"), _T(""));でハンドルを 取得して、ShowWindow()にSW_HIDEを指定して隠してやる。 メニューも邪魔なので、画面をタップするごとに表示・非表示を切り替える。 入力はカーソルボタン、カーソルボタンの押し込み、アクションボタン、の 3つがあるので、これらを取り敢えずジョイスティックに割り当てる。 その他はまった点としては、DIBSectionを作成するときは、ビットフィールド型 でなければならないことと、GetOpenFileNameの挙動が微妙に違っていること。 そのままでいけたsigmarion3が、CEマシンとしては異端だったのかなあ。 以上で一応仮完成。 設定ダイアログは240x320には大きすぎるので、適当なサイズのものを用意する 必要があるのと、残りの40x320の部分に仮想キーボードを表示する予定。 2003/7/28-29 仮想キーボードについては、標準のIMを使用する方針で。 IMのキーをクリックするとWM_CHARが飛んでくるので、LOBYTE(wParam)から 仮想キーコードを生成すればよい。 但し記号や大文字がきた場合は、SHIFTも同時押しにする必要がある。 F1〜F10については仮想キーボードにはないので、アクションボタンと1〜0の 同時押しでファンクションとみなすようにする。 ただアクションボタンを押すと、WM_KEYDOWNとWM_CHARが両方飛んできてしまう のが問題。この辺は、WM_SETTINGCHANGEが来たらSIPの情報を取得して、 ON/OFFに応じて処理を変えてやればよいか。 大体こんな感じで実装したところ、問題なくキー入力ができるようになりました。 まだ設定関係は手付かずだけど、一応実用にはなるかと。 2003/10/10 Sobig.Fが12000通/日オーバで大爆発だったりとか、PCがクラッシュしたりとか、 仕事が大忙しとか、プライベートで云々だとか、今更に怒首領蜂とかぐわんげに はまっていたりとか、何だか色々で暫くお休みしてました。 そろそろまた創作意欲が湧いてきたので再開です。 まず宿便になっていたデータレコーダの実装。 ロードについては単純に、時間経過に従ってwavファイルからサンプリングして、 0/1で値を取れるようにしただけ。 テープを回したり戻したりという辺りは飛ばしてます。 で、問題なのは、MZ側の処理が単純にCPUの処理速度に依存してるっぽいこと。 どうもレートが合わないみたいでまだロードには成功していません。 もうちょっと調整する必要があるみたいです。 2003/10/11-13 大学時代の同期連中でちょいと伊勢志摩方面に旅行に行ってました。 で、旅行中に、画面生成部の高速化に関して電波を受信してみたり。 2003/10/13-14 という訳で、受信した電波を早速実装してみる。 MZのVRAMはプレーン型なので、これをビットマップにするために、各プレーン毎に ビットシフトして合成するという処理を行っているのが結構負担になっている。 これを、事前に展開したデータを持っておいて、そこから転送するように変更。 で、試してみたところ、大体20%程度は描画の高速化が図れた模様。 まだ多色PCGのところが従来のままなので、ここもキャッシュ化することを検討中。 ゼビウスとかエキサイトバイクなどで効果がありそう。 2003/10/15-17 気が付いたら、sigmarion IIIのSDKが公開されていた模様。 ということで、sig3版の開発環境をeVT3.0から4.0に変更する。 ところでWinCEでもDirectSoundをサポートしているらしいので試してみる。 SetFormat(), SetCooperativeLevel()で仕様に違いがあるのを除けば、基本的には そのままでいけるっぽい。 試してみたところ・・・だめ、全然CPUパワー足りてない(苦笑) サウンド周りを見直し始めたついでに、waveOut系のAPIを使用した実装も追加。 基本的にはciscさんのM88の処理をそのまま流用している。多謝>ciscさん 環境によってはDirectSoundより軽く動作するかも。 私の環境では、waveOut系の方が安定しているように感じます。 sig3では・・・んー、まだDirectSoundの方がましかな。 という訳で、いっそレートを落とした方がましだろうということで、2/4/8kHzも 設定できるようにしてみたところ、2kHzでなんとか音楽らしく聴こえるように。 2003/10/19-20 sig3のCPUパワーでは、結局どうやってもfmgenでサウンドを鳴らすのは無理そう という結論に至ったため、自前の簡易エンジンを使用することに決定。 とにかく軽く軽くということで、各チャンネル毎に周波数、ボリューム、キーの on/offだけ取得して、音自体は矩形波として生成するという超簡易実装。 (但しFM音源パートについてはブロック4で代表) 実行スピードの調整を端折っているため速くなったり遅くなったりと不安定だけど、 元々SSGのみのエキサイトバイクのみならず、リバースやウィバーンなどでも旋律 自体はそこそこ聴き取れるのは意外。 周波数は落としても大して効果なかったので、2/4/8kHzは廃止することに。 sound.h内の#defineを弄れば、PC版でも簡易エンジンを使用できるので、興味の ある方は一度お試しを。 2003/11/3-4 CPUコアの高速化。 現在switchで各ニーモニックを実行していますが、これはイマイチ速くないという ことで、以前関数ポインタのテーブルを使用する方式を試みたことがありました。 が、クラスのメンバ関数のポインタを取得するにはメンバ関数自体をstaticにする 必要があり、そうするとクラス内の他のメンバ変数にアクセスできなくなるため、 このときは結局断念。 thisを渡してやると遅くなりそうだし、cpuをグローバルで実装して、それを クラスでラッパーしてやるところまで深入りしたくないし… という訳で、ちょいと妥協。 従来caseが256個並んでいたところを、まずcmd & 0xf0で16個に振り分けて、 その中で更にニーモニック毎にcaseを並べるという2段構成に変更。 速くなったのかどうかは判らないけど、まあ遅くはなってないと思います。 ジョイスティック&キーボード周り。 ジョイスティックから情報を取得する度に、joyGetNumDevs()を実行して、 joyGetDevCaps()を実行してたのを、初期化ルーチン内で1回だけ実行するように。 なんでこんな無駄な事してたのか覚えてませんが、修正した結果CPUの使用率が 2〜3%減少したので、まあよし。 winmain内の速度調整部。 速度に余裕がない場合でも、ある程度のSleep()を実行するように変更。 スキップ率が上がる代わりに、幾らかは軽くなったかと。 7/26のバイナリと比較すると、CPU利用率が大体20%程度は低くなってます。 また、スキップフレームの設定を変更しました。 原則として、CPUに余裕があれば描画するようになっていますが、余裕があっても 最低これだけはスキップすべしという最小スキップ数と、余裕がなくてもこれだけ スキップしたら1度は描画すべしという最大スキップ数の2つを指定するように なっています。 2003/11/7-9 PentiumIII 1GHzな開発マシンにといて、M88はCPU使用率が1〜2%内外。 EmuZ-2500は、最近やってる高速化を含めても35%前後。 なんでこんなに差が付くかなあということで、ふと思い立って画面生成&更新を 止めてみたところ、なんと1〜2%内外に。 CPUコアを中心としたエミュレーションコア自体はそれ程重たい訳ではなく、 画面生成と、BitBltで画面更新してる処理が異様に重かったようです。 更に調べてみると、テキスト/CGの各画面を生成する部分を走らせてもやはり 1〜2%で、両画面をプライオリティに応じて合成するところが重たい模様。 そこで、合成ルーチンを見直して高速化を図ってみることに。 パレットレジスタの判定周りをループ外に出したり、ループ内のデータを インデックスアドレッシングでアクセスするようにしたり、など。 bitbltが遅いのは、スクリーンと内部のDIBSectionでモードを合わせていない からというのもあります。自動的に合わせるのも面倒なので、画面モードは 16bpp推奨ということで。 DirectDraw化も考えてはいますが、工数的に重そうなので。 http://www.sun-inet.or.jp/~yaneurao/intensive/diw1.html ここら辺りが参考になりそう。 ついでに、ウィンドウタイトルにフレームレート表示機能を実装してみたり。 確認してみると、最小スキップ数を0にした場合は22fpsでCPU使用率が20%、 256色モード時は15fpsで30%前後となりました。 画面更新を止めると45fps前後、bitbltが大きく足を引っ張ってますね。 今後のTO DOを纏めておきます。 DirectShowを使用した描画の高速化。 エミュレーションコアから入力関係の処理の分離、一括化。 漢字プリンタ MZ-1P17のフル実装。 設定画面の再構築。 2003/11/11 sigmarion3用GameAPIが存在するということで、試してみました。 しかしGAPI関係の資料、本当に少ないですね(苦笑) 大して難しくないのがせめてもの救い。 16bppでもsig3の場合はRGB565のようなので、RGB555と切り替えられる用に修正 する必要があること以外は特に手間取ることもなく実装完了。 で試してみたところ・・・馬鹿っ早。 速度調整処理をwinmain_hpc.cppに復活させた上で、実機並の速度で8〜9fpsは 出てるみたいです。 2003/11/13〜 たごさんの掲示板で、どうもSleep()の精度が環境によっては怪しいのではないか という話が出てきました。 ネット上で情報を漁ってみましたが、確かにそういう事もあるみたいです。 Sleep(1)を入れているのはCPUの使用率を下げる為だけなのに、そこで環境に よっては14msec以上も待たされるというのは不本意。 とはいえ、Sleep(0)だとタスクスイッチは問題なくても、CPU使用率が100%いって しまうというのも、Windowsアプリとしては些かみっともない。 将来はSleep(0)とSleep(1)を切り替えられるようにするという前提で、取り敢えず 次回は試験的にSleep(0)なバイナリで出してみようかと思います。 2003/11/22〜 たごさんがDirectDrawを使用した実装を色々と試みてくださっているのですが、 なかなかDIBSectionを使用した実装より速くならないようです。 高速化はさておき、ティアリング対策によいのではないか、という話も出て きましたので、私のほうでも試してみました。 BitBlt()前に、WaitForVerticalBlank()とか、GetScanLine()でループとかを 入れるという、割とお約束な実装を試してみたのですが、どうも却って ティアリングが酷くなってしまう始末。 これは私の環境がノートマシンであることも関係しているかもしれませんが、 取り敢えず保留。 2003/11/26〜 エミュレータスレッドで、ちょっと妄想を吐き出してみました(笑) その関係で、Win32側のコードを今後開発していくエミュレータで再利用できる ようにするために、エミュレーションコアとWin32側のコードの分離作業を 進めています。 具体的には、 従来のVMクラス(仮想マシン)とは別にRMクラスを新設。DIBSectionを利用した 画面表示、DirectSoud/waveOutを使用した音源再生、mciを利用したmp3の再生、 キーボード、マウス、ジョイスティック管理などの処理を全てそちらに移す。 またVMクラスにRMクラスのポインタを渡して、PCを操作する処理はそれを 経由してRMクラス内の関数を呼び出す。 といった感じ。 DirectSound/waveOutは各々上位サウンドクラスの派生クラスとして実装する ことで、簡単に処理を切り替えられるようにしています。 実装はまだですが、プリンタ操作部もRMクラスに移行する予定です。 その他、簡易FM音源もfmgenと同じようなインターフェースを持つクラスとして 再実装して、これも簡単に切り替えられるようにしてあります。 まだVMクラス内にWin32 APIが残ってしまっていますが、随分コードの見通しが 良くなったように思います。 やはり多少はオーバーヘッドがかかってるようで、sig3版では平均1fps程度 落ちてしまっていますが、まあこの程度なら許容範囲でしょう。