|
FM TownsのSprite Busyのタイミングについて研究してみた。結論を先に書いてしまうと、以下のようなことがわかった。
VSYNCとSprite Busyフラグの関係については、FM Townsテクニカルデータブック(通称赤本)の369ページ[1]に記述がある。この赤本は、FM Townsの技術情報のバイブルのようなもので、非常に貴重な情報がたくさん載っている反面、エラーも多かった。まず、1について、赤本ではSpriteハードウェアが画面消去を開始するタイミングはVSYNC終了時であるという記述がある。この図ではSprite転送終了でSprite Readyになると記述してあるものの、どの時点でSprite Busyになるのかの説明が無い。ただし、本文によるとこの図は「スプライトの動作と同期信号の関係」とあるので、この図がSprite Busyフラグについて書いていると考えるのが自然と言える。しかし、この図ではSpriteハードウェアの動作が始まるのはVSYNC終了時と解釈できるが、計測によるとVSYNC開始時だった。
そして、赤本369ページの図では、最初の32usで画面消去、その後スプライト1枚につき75usの転送時間がかかると書いてある。しかし、FM Towns II MXで計測した結果、スプライト1枚の転送にかかる時間は57usだった。当時の印刷は今ほど自動化されていなくて、原稿と印刷の間にかなりの手作業が入る。この手作業で上位と下位の桁を間違えてしまったのではないか。(追記: その後津軽ユーザの方からの情報でMA/MXでは初期型よりもスプライトが高速化しているとのことなので初期型は75usだったのかもしれない。2Fは手元にあるけどすぐに引っ張り出してテストできない。)
また、赤本369ページの図によると、スプライトハードウェアは動作を始めて最初の32usでVRAMをクリアするとある。この32usはSprite Busyフラグは1なのか0なのか図からは曖昧でわからなかった。Sprite Busyフラグの意図としては、SpriteハードウェアがSprite RAMをアクセスしている間にCPUが同時にアクセスしないようにするということだと考えられる。だとするとVRAMをクリアしている間はCPUがSprite RAMをアクセスするのは自由だからBusyフラグは0でもいいはず。この疑問は実機での計測によって、クリア中もBusyフラグは1であることが確認できた。VRAMクリアにかかる時間は、実機計測だと約29usという結果になったが、大雑把な値なので32usは十分近い値と言える。
それからもう一点わからなかったのはVSYNCに実際どの程度の時間がかかるのか。これも調べるついでに計測したところ、60usということがわかった。CRTのリフレッシュサイクルは1/60秒だから、16.7ms。水平同期周波数で480ラインを走査するのにかかる時間を差し引くと1400us程度になる計算だったのだが、実際はその23分の1程度しか時間がかかっていないことがわかった。
FM TownsのSprite Busyフラグの動作とVSYNCの関係を見るために、簡単なCプログラムを書いた。最初、プログラムは、
そこで、プログラムを以下のように修正した。
このことから、1リフレッシュサイクルにかかる時間16666usを290で割ることで、スプライト1枚の転送にかかる時間は57.46us程度であることがわかる。(VRAMクリアに32usかかると仮定しても16634/290=57.35us)この値はFM Townsシリーズを通して一定のはず。そうでないとスプライトBusy/Readyでタイミングを取っているゲームがMXの高速モードでスピードが変わったりするはずだ。もうひとつわかったのは、Sprite ReadyからBusyに切り替わるのは必ずVSYNCの立ち上がりであるということ。おそらくSpriteのハードウェアはVSYNCの立ち上がりで動作を開始している。赤本が言うように経ち下がりではない。このことから、スプライトの転送が次のVSYNCの立ち上がりまでに間に合わなかった場合、次の動作開始はその次のVSYNCの立ち上がりまで発生しない。
もう少し精密に計測できないか、サンプリングインターバルを変更できるようにして計測してみた結果が以下の通り。サンプリングインターバルを5usまで下げても結果は安定していたが、4usでギリギリ、3usに下げると不正確な値が出始めた。
なお、数字"12 5"は、VSYNCが1と計測された回数が12回、サンプリングインターバルが5usを意味する。このことから、VSYNCが1となる期間の長さは12*5=60usであることがわかった。予想では、1リフレッシュサイクルから480ラインの走査に必要な時間を差し引くと1400us程度かかると見ていた。実際はVSYNCが1になるのは、それよりもかなり短い期間ということがわかった。
また、スプライト個数を10個~14個まで変化させたとき、かかる時間は、119*5=595us, 130*5=650us, 141*5=705us, 153*5=765us, 164*5=820usという結果になった。サンプル数が少ないので大雑把だが、これを最小二乗法でy=ax+bにフィットすると、
y=56.5x+29
という結果になる。スプライト1枚あたり56.5usとして、VRAMクリアにかかる時間が29us。32usに近い。
VSYNCとSprite Busyのタイミングがはっきりわかっていなかったので、FM Townsエミュレータ「津軽」でGenocide 1/2, Shadow of the Beast等でスプライトが更新されなくなる問題が起きていたが、実機サンプルを取ったことで、曖昧だった実装を実機に合わせることができた。また、一部ではFPGAでTownsを再現しようという動きもあるようなので (FPGAのDOSから始めれば十分可能のはず)、スプライトのタイミングを解明できたのは、Townsの保存にそれなりに有益かもしれない。
しかし、こんなことを調べても直近には何の役にも立たないので、何の役にも立たないプログラムを書くのはやっぱり楽しい、と、思った。(それが結論か!)
Comments are welcome. Send E-Mail to: |