■X680x0エミュレータの実機との挙動の違い

 エミュレータ上でソフトを開発している際に気が付いた実機との挙動の違いについての覚え書き。

 全てを書くとキリが無いので、一部のみ抜粋。

 今後、X680x0のプログラムを作成したり、X680x0のソフトウェア or ハードウェアエミュレータを作成 or 更新する際の参考にでもなれば。

 ※そのうち、各現象を確認できるテストプログラムを作る予定です。

----------------------------------------------------------------------------------------------------
● MPU、メモリ関係
----------------------------------------------------------------------------------------------------

 現象:32bit同士の掛け算の結果がおかしい。

	・WinX68030 v0.11

 原因:CPUコアのバグ。

----------------------------------------------------------------------------------------------------

 現象:ライトオンリーのメモリ領域 or レジスタに書き込んだのに、書き込んだ値がそのまま読めてしまう。(多数)

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)

 原因:考慮不足。

----------------------------------------------------------------------------------------------------

 現象:システム領域へのアクセスの実装が間違っている。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11

 原因:考慮不足。

	・本来、システム領域へのアクセスは 16byte x 512回 のミラーリングとして実装しなければならないが、先頭の16byteへのアクセスしか考慮されていない。

	 例えば、コントラストを変えるためには通常、$E8E001に値を書き込むが、別に$E8E011に書いても、$E8FFF1に書いても変更は可能。

	 エミュレータで実装する場合、システム領域($00E8E000〜$00E8FFFF)へのアクセスは、$00E8E00F(別に$FFFFE00Fでも良いが)とANDを取った値で読み書きすれば良い。

	 これを知っている人は殆どいないと思うので仕方が無いところでしょうか。


	 ちなみに、コントラストに$DEを書き込んだ場合、実機では$FEが読めるが、WinX68k高速版では$0Eになってしまうといった違いもあります。(実機では書き込んだ値とは無関係に未使用ビット部分は1が立つ)

	 こういった違いは挙げていけばキリが無いので、現時点では載せていません。

----------------------------------------------------------------------------------------------------
● CRTコントローラ関係
----------------------------------------------------------------------------------------------------

 現象:CRTCの設定を変更し、独自の画面解像度/フレームレートに変更しても、フレームレートが全く変わらない。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71

 原因:CRTCの設定パラメータから逆算して1フレームレート辺りのクロック数を計算せず、固定値で処理している為。(XM6は可変)

	・31kHzモードでCRTCを弄って60fpsに設定してもエミュレータ側は55fps決め打ちでしか動作しない為、V-SYNCで同期をとっているゲームの場合に見た目で明らかに進行速度が遅くなる。(市販ソフト含め多数)

	・サウンドドライバがV-SYNCの周期を利用してタイミングを取っているソフトでは、サウンドの再生がスローになってしまい理想とする再生速度で再生されない。(SEGA MARK3版 北斗の拳 等)

	・ゲーム中の、ある期間の時間制限を「フレーム数」ではなく「サウンドの再生開始から終わりまで」としている場合は、ゲームのプレイ時間自体が変わってくる。

	 例えば拙作のマッピー(60fps)の場合、サウンドは実時間で進むのにフレーム数は1割弱も遅くなるので、ボーナスラウンドでパーフェクトを狙おうとすると時間が足りず、絶対にパーフェクトが取れない。

	 WinX68k系エミュレータ共通の弱点。

----------------------------------------------------------------------------------------------------

 現象:実機で60.00Hz丁度になるCRTCパラメータをXM6で実行すると、多少速い値(例:60.92Hz)になる。

	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)

 原因:未調査。 誤差が生じるのか、計算方法が実機と少し違うのかもしれません。(XM6シリーズではメモリアクセスのクロック計算の処理を正確にせず、一部端折っているのが原因かもしれません)

----------------------------------------------------------------------------------------------------

 現象:グラフィック画面256色モード(2プレーン)や65536色モード(4プレーン)で、プレーン毎のスクロールレジスタへの設定値、およびプレーン内容が反映されない。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)

 原因:実用的な速度で動作させる為の、重ね合わせ処理の大幅な簡略化。

	スクロールレジスタ関連の水平座標は描画中も含め常時変更可能なので、厳密に実装するとしたら1ドット毎にその瞬間の複数プレーンのスクロールレジスタの値、
	および$E82500に設定されるプレーン内容(同一プレーンを設定する事も当然可能)を参照して色(パレット)を決定する処理をしなければならない為、実用にならないほど処理が重くなる。

	これを利用して擬似半透明処理、その他の演出を行っているソフトウェアでは見た目で不具合が起こる。(ゲーム、ビュワー、ぱにっくデータ、その他)

	この辺りに力技で解決しなければならないソフトウェアエミュレータの限界を感じます。

	おそらく全てのX68000エミュレータで手を抜かれている代表的なポイントの1つです。

----------------------------------------------------------------------------------------------------
● スプライトコントローラ関係
----------------------------------------------------------------------------------------------------

 現象:スプライトパレットの1〜15に$0000を設定すると黒にならず透明色扱いになり背景が見えてしまう場合がある。(SEGA MARK3版 北斗の拳 等)

	・XM6 2.06

 原因:考慮不足。

	「SP/BG画面」のプライオリティ設定($E82500.b)が「テキスト画面」より上にある場合、
	スプライトパレットのカラー1〜15に$0000が設定されていると、下位のテキスト画面の内容が表示されてしまう。

	例えばこんな場合。

		move.b #%01101111,$e82601   ;|--|SP|TX|G4|G3|G2|G1|G0|

	としてから、以下の何れか

		A. move.b #%00_00_01_10,$E82500 ; SP & BG > TEXT > GRAPHIC
		B. move.b #%00_01_10_00,$E82500 ; GRAPHIC > SP & BG > TEXT
		C. move.b #%00_00_10_01,$E82500 ; SP & BG > GRAPHIC > TEXT

	X68000の「SEGA MARK3版 北斗の拳」は背景をテキスト画面に描画しているので、この現象が起こります。

	※スプライトとテキストの間にBG画面が表示されていても、それを無視してテキスト画面の内容が表示されます。

	ちなみに、スプライトパレットのカラー1〜15に$0000が設定されている場合、
	下位の内容が表示されるプライオリティ設定の組み合わせも存在しますが、
	今回の組み合わせでは黒く表示されるのが正しいです。

----------------------------------------------------------------------------------------------------

 現象:スプライトコントローラのH-DISP、およびV-DISPの値が全く反映されていないので、設定値を変更してもスプライトの表示エリアの重ね合わせの基準位置が変わらない。

	・XM6 2.06

 原因:XM6では現時点で未実装の為。 ドラゴンバスター(他多数)などでスプライトの表示位置がずれて見えるのはこれが原因です。

----------------------------------------------------------------------------------------------------

 現象:スプライト表示エリア(512x512)の実装が間違っている。(※スプライト座標系(1024x1024)の話ではないので注意)

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)(後述する、これに関連する不具合有り)

 原因:スプライト表示エリア(512x512)の左右は、円筒スクロールのように繋がっていなければならないが、それが考慮されていない。(但し、左右端でのクリッピングは存在する)

	・スプライトコントローラのH-DISPは単純な重ね合わせの表示開始位置ではなく、(スクロールレジスタのように)重ね合わせの基準位置を決めるもの。

	 例えば256x256ドットモードにおいて、H-DISPの基準値に+16(+128ドット)した場合、

	 実機:

		画面の中心から右半分に水平座標1〜143のスプライトが表示される。

			但し、0の場合は表示エリア左端に完全にクリッピングされるので全く表示されず、1〜15の場合もクリッピングは行われるので当然表示の一部は欠ける。

			また、144の場合は表示領域対象外なので全く表示されず、129〜143の場合も右端は表示領域対象外なので一部表示されない。

		画面の中心から左には水平座標385〜527のスプライトが表示される。

			但し、384の場合は表示領域対象外なので全く表示されず、385〜399の場合も左端は表示領域対象外なので一部表示されない。

			また、528以降は表示エリア右端に完全にクリッピングされるので全く表示されず、513〜527の場合もクリッピングは行われるので当然表示の一部は欠ける。

	 エミュレータ(例:WinX68k高速版)の場合:

		画面の中心から右に水平座標1〜143のスプライトが表示される。

			但し、左端でしなければならないクリッピング処理がされていないので、水平座標0〜15の場合でもスプライトの全体が表示されてしまう。

			また、144の場合は表示領域対象外なので全く表示されず、129〜143の場合も右端は表示領域対象外なので一部表示されない。

		画面の中心から左には何も表示されない。

	 エミュレータ(例:XM6 2.05 TypeG(2010/09/12))の場合。

		画面の中心から右に水平座標1〜143のスプライトが表示される。

			但し、0の場合は表示エリア左端に完全にクリッピングされるので全く表示されず、1〜15の場合もクリッピングは行われるので当然表示の一部は欠ける。

			また、144の場合は表示領域対象外なので全く表示されず、129〜143の場合も右端は表示領域対象外なので一部表示されない。

		画面の中心から左には何も表示されない。


	・ちなみにV-DISPはそもそもラスターの表示開始位置なので、左右の場合と違って繋がって見えたりする事は無い。

	・XM6 2.06の場合は、そもそもH-DISPやV-DISPの値が反映されないので、現時点では関係が無い。

----------------------------------------------------------------------------------------------------

 ※以前調べた上記と現象が矛盾している気がするので、以下の現象については条件などを再調査中。 描画されないのは確かなので別の理由かもしれない。

 現象:(前述、スプライトエリア表示実装に関連)スプライトX座標0〜15の際、画面にスプライトが一部、または全部描画されない。

	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)

 原因:以下の通り。

	IOCS等で用意されている標準的な画面解像度では、一部または全部が「画面外になる座標(スプライトX座標0〜15)」があるが、
	スプライトコントローラ($EB080C:水平表示位置)を弄って、CRTCコントローラに対する画面の重ね合わせ位置をX方向にずらせば
	当然その「画面外になる座標」を表示範囲内(例:画面中央など)に持ってきたりすることも可能。

	しかし、この範囲が無条件にクリッピングされているので、スプライトが表示されない現象が起こる。

	本当にクリッピング開始しなければならないX座標は「16」ではなく「0」から。

----------------------------------------------------------------------------------------------------

 現象:単純なスプライト&BG画面の重ね合わせ処理が間違っている。

	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・XM6 2.06

	X68000エミュレータに限らず、このような重ねあわせ処理をしているエミュレータをよく見かけます。

	例:X68000の場合

		1.SP/BGプライオリティ下位のスプライト(スプライト番号0〜127)の描画
	                    ↓
		2.SP/BGプライオリティ下位のBG画面(BG番号0〜1)の描画
	                    ↓
		3.SP/BGプライオリティ中位のスプライト(スプライト番号0〜127)の描画
	                    ↓
		4.SP/BGプライオリティ上位のBG画面(BG番号0〜1)の描画
	                    ↓
		5.SP/BGプライオリティ上位のスプライト(スプライト番号0〜127)の描画

	単純に考えるとコレで合っていそうな気がします。

	ですが、殆どのラインバッファなアーキティクチャのスプライト&BG画面の重ねあわせについて、
	エミュレータでこのように重ねあわせ処理をしても、絶対に実機と同じ表示にはなりません。

	元々、スプライトコントローラはこんなに正確に重ね合わせ処理などしていない(そんな余裕などある訳がない)ので、
	上記のようにまじめに重ね合わせをすると逆に実機と違ってしまうのです。

	この問題はX68000エミュレータに限らず、市販/フリーを問わずに数多くのエミュレータで手を抜かれているポイントの1つです。

 原因:コレでは何がダメなのか、自分で考えてみてください。

	ヒントとしては、
	「SP/BGプライオリティ中位や下位のスプライトは、SP/BGプライオリティ上位のBGの裏に隠れる」
	という考え方自体が間違っているとも言えます。

	これが再現出来ていないエミュレータでは、拙作のパック&パルのオレンジボックス内におけるスプライトがまともに表示されません。

----------------------------------------------------------------------------------------------------

 現象:「テキスト&グラフィック画面」と「スプライト&BG画面」の31kHzモードにおける、垂直方向の合成結果が間違っている。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14) ※2011/07/20版より再現性が下がった為

 原因:「テキスト&グラフィック画面」と「スプライト&BG画面」の垂直方向の合成は、ドット単位ではなくラスター単位で行わなければならないが、これが出来ていない。


	「テキスト画面&グラフィック画面」の垂直ライン解像度(256 or 512)の設定は、CRTコントローラ(VICON)の$E80028(bit2-3)へ設定します。

	また、「スプライト&BG画面(CYNTHIA)」の垂直ライン解像度(256 or 512)の設定は、スプライトコントローラ(CYNTHIA)の$EB0810(bit2-3)へ設定します。

	通常、この2箇所には同じ解像度になる値(垂直256dotモードなら両方に00、512dotモードなら両方に01)を設定するのですが、別に違う値(00と01)を設定してもなんら問題はありません。

	そもそも、31kHzモードの垂直256dotモードというのは、VRAM内の1ドットを2ラスター分(2回分)、計512ラスター分出力するという意味なのですから問題が起きるはずもありません。

	つまり、31kHzモードでは「CRTコントローラ」と「スプライトコントローラ」への垂直ライン解像度の設定値の内容の差異に関わらず、常に512ラスターを前提として合成しなくてはならないのです。

	これが正しく実装されていないエミュレータでは、表示結果がおかしなことになります。

	個人ユーザー製作のトイポップ(CRTコントローラの垂直ライン解像度 = 512dot、スプライトコントローラの垂直ライン解像度 = 256dot)が、どのエミュレータでもまともに表示されないのはこれが原因となります。


	また、上記に関連して「テキスト&グラフィック画面」と「スプライト&BG画面」の垂直方向の重ね合わせは「ドット単位」ではなく「ラスター単位」でする物ですから、
	双方共に256ドットモードであっても、片方を上下どちらかに1ラスター(0.5ドット)ずらして重ね合わせすることも可能です。

	さらにこれはラスター割り込みにも言えることで、256ドットモードの1ドット(2ラスター)の真ん中の位置(0.5ドット = 1ラスター)で、
	ラスター割り込みを行いスクロールレジスタを弄れば、1ドットの上下をずらすことも当然可能です。


	上記のような理由がある為、「テキスト&グラフィック画面」と「スプライト&BG画面」双方が垂直256ドットモードだからといって、手を抜いて256ラスター分の重ね合わせで済ましてはいけないのです。

----------------------------------------------------------------------------------------------------
● ソフトウェア毎の動作関係
----------------------------------------------------------------------------------------------------

 現象:一部のぱにっくデータが正常に再生されない。(rei.pan ほか)

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)(2011/06/16版ではパレットによる半透明処理も見れたが、2011/08/14版ではそれも見れなくなり、XM6 2.06と同等になってしまった)

 原因:以下の通り。

	256色以上のグラフィック画面におけるプレーン入れ替え表示には未対応な為、プレーンを入れ替えて他の内容を表示しようとしても表示されず、スクロールが止まって見えたり、そもそも何も表示されなかったり等する。

----------------------------------------------------------------------------------------------------

 現象:「LDBMP.X」での「768x512ドット256色モード」でのBMP表示が再現できていない。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)(再現性という意味では今一歩)

 原因:以下の通り。

	LDBMP.xでは、ラスター割り込みを利用することで、通常、X68000では表示不可能な「768x512ドット256色モード」を実現している。

	例えば、768x512ドット256色のBMP画像を表示する場合、前準備として、

	 グラフィック画面0には768x512ドットの左2/3の画像を描画。(X座標が0〜511の範囲の画像)  ※X座標のスクロールレジスタの値は0
	 グラフィック画面1には768x512ドットの右2/3の画像を描画。(X座標が256〜767の範囲の画像) ※X座標のスクロールレジスタの値は256

	以上のように設定する。

	つまり、画像の内容が「ABC」だった場合、

	 グラフィック画面0を表示すると「ABA」という内容の画像が表示される。
	 グラフィック画面1を表示すると「CBC」という内容の画像が表示される。

	となる。

	次に、各ラスターのラスター割り込み開始直後にグラフィック画面0を表示、グラフィック画面1は非表示とする。
	そこから一定時間ウェイトを取り、画面の中央付近でグラフィック画面0を非表示、グラフィック画面1は表示とする。
	(切り替えタイミングとなる「ウェイト」はコマンドライン、または表示中でも自由に調整可能)

	こうすることで、画面には「ABC」という内容の画像が表示され、通常は不可能な「768x512ドット256色モード」が実現できる。

	しかし、各エミュレータで画面を停止し各ラスター毎の表示内容を見てみると、ウェイトをどう調整しても常にどちらかのグラフィック画面しか表示されていない。

	その為、実機では可能な「768x512ドット256色モード」が再現できない。

	どのX68000エミュレータも、ラスター割り込み中の処理、およびラスターのレンダリングの条件はかなり大雑把にしか実装していないようです。

	実機ではラスター表示中であっても常にあらゆる表示条件(座標、色モード、表示/非表示、プレーン内容等)が変わる可能性があるので、レンダリングの際も当然それを考慮する必要があります。

	具体的には、例えば256x256ドットモードならば、1ラスター(256ドット)分のクロック数MPUを動かしてからその時点の設定条件でレンダリングするのをやめ、
	数ドット(CRTCへの水平表示開始/終了位置関係の設定値は8ドット単位なので、8ドット程度が理想か?)分のクロック数MPUを動かし、
	その時点の設定条件でレンダリングする事を1ラスター(256ドット)分繰り返す等すれば良いです。(水平同期期間分のMPUクロックの考慮は言うまでも無いので省略)

	まぁ、世に存在するソフトウェアエミュって、大抵1画面、又は1ラスター単位で大雑把にレンダリング処理されているのですけれど、X68000の既存のソフトにそれは通用しなかったと。

	XM6 2.05 TypeG(2011/08/14)では、なんとか表示は出来るようにはなりましたが、横768モードでは1ラスターを3分割程度(256ドット単位程度?)と
	大雑把にレンダリング処理をしている事に変わりは無いので、条件が変わるのが画面中央で無かったり、ラスター中に2回3回と条件を変えてしまうソフトを書いてしまうと直ぐに破綻してしまいます。

----------------------------------------------------------------------------------------------------

 現象:「パックランド」等で使用されている31kHz、384x256ドット、BG8x8ドットモードの実装が間違っている。

	・WinX68k v0.65
	・WinX68k高速版 v0.95
	・WinX68030 v0.11
	・WinX68k S.E. v0.71
	・WinX68k C.E. v0.71
	・XM6 2.06
	・XM6 2.05 TypeG(2011/08/14)

 原因:以下の通り。

	実機では「スプライト/BG」画面のX座標に対して、重ね合わせの基準位置+256+α(αの値はスクロールレジスタの値によって正確に変わるので計算可能)」から、
	1ラスター(1ドットではない事に注意)分だけ上にラスターずれする現象が起こらなければいけないが、それが再現されていない。
	(これを逆利用して、重ね合わせの基準位置を大幅にずらしラスターずれを無くす画面モードのテクニックがあるが、エミュレータでは全くずれない為にそれが再現できない)

	※正確には、前述の「重ね合わせの基準位置+256+α」までの方が「1ラスター分だけ下にずれる」というのが正しい。
	 BG16x16ドットモードと同じ位置でラスター割り込みをしても割り込み位置が1ラスターずれて見えるのはこれが原因。

	パックランドで画面の上のほうに1ライン、チラチラと見えていたりするエミュレータがあればこれが原因。(単純にエミュレータにBG16x16ドットモードと同じ処理を実装している為)

	仮にこの現象を再現したとしても、31kHzモードの縦256ドット(512ラスター)モードを、512ラスターではなく、256ラスター分で再現しようとするエミュレータ(おそらく現状全て)では当然再現が不可能。


	また、実機では「スプライト/BG」画面の重ね合わせの基準位置+256+β(βの位置は確か固定だったと思われます)の位置からスプライトの残像現象が現れるが、それが再現されていない。
	(パックランドでは特殊なプログラミングテクニックで残像現象を回避している)

	まぁ、エミュレータでこれを再現する必要は無いと思われます。 仮に再現しようと試みても、実際に見たらこんなものはとても再現できない、無理だと諦めるでしょう。

----------------------------------------------------------------------------------------------------

 現象:「やどかり」など、ファイラー操作していると、「システムクロック」、「MPU動作のみノーウェイト」の組み合わせに関わらずテキスト画面に頻繁にゴミが残るようになった。

	・XM6 2.05 TypeG(2011/08/14)

 原因:以下の通り。

	今回の修正によるエンバグと思われます。