2012年08月04日

画面描画期間検出(1)

 まず、以下の画像をご覧下さい。DSi で撮ってるので、画像が悪いですが...




 これは、PC-6001 初代機で動かしたものです。外部に余計はハードウエアは付けていません(RAMは32Kにしていますが)。


 境界がちらちらと動くのがイマイチなんですが、一応画面の上半分はSCREEN4、下半分はSCREEN3 になっています。

 これは、ソフトウエアで画面描画期間を検出して、そこから一定時間後に画面の切り替えを行ってます。
 (事前にページ3とページ4を、SCREEN3 とSCREEN 4 に設定しています)



 プログラムがこれです。

vsync.zip



 ・画面描画期間の検出の方法

 画面描画期間の時だけ止まっているCPU で、その止まっている期間を検出するためには、CPU の外部に基準の時計が必要になります。
 今回は、SUB-CPU がつながっている8255 のポートを使用しました(詳細は後述)。

 特定ポートにデータを書き込むと、4MHz で64クロックぐらいかかる処理があります。


 これを使い、画面描画期間を判定します。

 データ書き込み
 ↓
 4MHz で40クロックぐらい待つ
 ↓
 処理が完了しているかを判断する


 画面描画期間以外:処理が完了しない。
 画面描画期間:CPU が途中で止まっているため、実際には40クロック以上の時間が経っており、処理が完了する。

 で判断します。


 ・8255のポートの話

 かなりハード寄りの話です。

 SUB-CPU とメインCPU との通信のために、8255 のモード2を使っている、という話は周知だと思います。
 このモード2ですがもっと細かく見ると、以下のようになります(SUB-CPU に出力時)。

 OUT 0x93,0x08 :INTE2 をリセットして、リード側のポートを無効にする(→ライト側のポートのみ有効になる)。
 ↓
 IN (0x92)  :bit3 とbit7 が 1 になるまで待つ(8255が受信可能になるまで待つ)
 ↓
 OUT 0x93,0x09 :INTE2 をセットする(後のためにINTE2を戻しておく?)。
 ↓
 OUT 0x90,DATA :SUB-CPU へ出力するデータを書き込む。


 最後のデータを出力すると、8255 の port-C の bit7(OBF)が、H→L になります。この信号が、SUB-CPU の割り込み信号になっています。
 ↓
 SUB-CPU は、割り込みが発生すると、データを読み出すためにリードイネーブルをLにします。この信号が、8255 の port-C の bit6 (ACK) になっています。
 ↓
 8255 は、8255 の port-C の bit6 (ACK) がLになると、読み出しが完了したと判断して、port-C の bit7(OBF)をL→Hとして、処理が終了します。



 一連の動きを実機のPC-6601 で測定したものがこれになります。動きとしては、初代機PC-6001 でも同じです。

SUBCPUアクセス


 画面描画期間はちゃんと検出出来ているようですが、毎フレーム検出できるというわけではありません。
 それは、(当然ですが)画面描画期間中に検出ルーチンを通らないと検出できないため、プログラムのループが長い時には、検出できないことがあるようです。






posted by えすび at 14:06| Comment(6) | P6解析:画面周り | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
うわ!ひと月ほど前にこれと似たようなことを考えていました。
https://twitter.com/fuzzball/status/223099132334706688

2msタイマーも止まっちゃうしなぁなんて思ったりしながら‥。
8255を使うのは思い付かなかったです。
何かおもしろいこと出来ないかなぁ。
Posted by fuzzball at 2012年08月07日 23:00
>fuzzballさん

 私も最初は2msタイマを考えていましたが、さすがに長いと思ったので、他を探していました。

 最初に考えたのは、sub-CPU を使う手です。

 sub-CPU にゲームキー検索(CALL 1061 で使っているヤツ)をして、その値が返って来る時間をタイマ代わりにするものです。

 ただ、これも結構時間が長く、水平同期で2ライン分以上(4MHz 換算で500クロック以上)の時間がかかります。

 今回アップしたのは逆に短すぎるようで、検出できないこともしばしばです。


 sub-CPU の方は、もう一度考え直してみる価値はありそうです。

Posted by えすび at 2012年08月08日 11:26
サブCPUの反応速度を利用する方法は思い付きはしたものの、
どのくらいの時間なのかなど、調べたり考察したりする能力が私には無いので、
早々にあきらめていました‥。

私は二画面切り替えの同期を取りたいだけなので、
2HSYNC程度なら使えそうな気が?

でも、最近はVSYNC熱がちょっと冷めちゃってるからなぁ(笑)
Posted by fuzzball at 2012年08月08日 13:16
ちょっと勘違いしていたようで、2つの書き込みで矛盾したことを書いてしまいました。
「8255を使う」というのは、8255へのアクセスで何かウェイトが掛かるのかと思っていたのですが、サブCPUを使うという意味だったんですね。

ゲームキー検索では長過ぎる、サンプルで使用しているCMTクローズでは短過ぎる、
ということでいいのかな?
Posted by fuzzball at 2012年08月08日 14:12
 あ。違います。

 サンプルのバージョンは、8255の応答時間を使っているので、SUB-CPUに送っているデータ(CMTクローズ)は、特に意味はありません。


 Z80 → 8255 → sub-CPU へとデータを送る際に、8255のモード2でハンドシェークみたいな事を行っています。


 Z80 が 8255 にデータを出力
 ↓
 8255 がそのデータをラッチし、同時にデータが入力された事を sub-CPU に通知
 ↓
 sub-CPU がその通知を受けて、ラッチしているデータを読み込む


 が一連の流れで、その分の時間を待ち時間に使っています。


 ちなみに BASICROM の sub-CPU のアクセスで、何やらビットを見て待っているループがありますが、その見ているビットがこれに当たります。



 ゲームキー検索の方は、純粋に sub-CPU からのレスポンスを待つ事になるかと思います。キースキャンを2列分行うので、結構時間がかかります...



Posted by えすび at 2012年08月08日 14:41
なるほど。
純粋に「サブCPUへのコマンド送信に掛かる時間」、
BASIC ROMで言うと call $0e8f の処理時間 ということですね。

ゲームキー検索の方もあまり芳しくないようですね‥うむむ。
Posted by fuzzball at 2012年08月08日 18:38
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。