Z80 ゲーム機を作ろう(その10)

このゲーム機の工作記事も,もう 10 回目になるんですね。結構時間が掛かったな~と思いつつ,完成まであと少し残っているので,引き続き頑張っていこうと思います。

前回は,スプライトのラインバッファ基板を作成し,スプライトが表示できるようになりました。

Z80 ゲーム機を作ろう(その9)

今回は,BG 画面とスプライト画面の表示プライオリティ制御,パレット変換とRGB 信号出力の基板を作っていきたいと思います。

各画面の重ね合わせと優先順位

このゲーム機,BG 2 画面と,スプライト画面があります(BG 画面は,まだ 1面しか作っていませんが)。

そして,これらは互いに独立していますので,最終的には,それぞれを優先順位に従って重ね合わせてから,画面に出力してやる必要があります。(これらを便宜上,それぞれ「面」と呼ぶことにします)

この面の優先順位の設定ですが,1 バイトのレジスタをアドレス空間に割り振って,そのレジスタに対して,値を書き込むことによって設定します。面は,3 つあるので,その順番は 6 通りあるのですが,ここは簡略化して 3 通りにします。

これらの面は,画面の走査線に合わせてドットを表示するとき,BG も,スプライトのラインバッファも,同じタイミングでドットデータを送ってきます。

という事は,優先順位が決まれば,その中で一番手前になる面のドットを選んで,モニターに出力してやれば良いと言うことになりますよね。

ただ,それぞれの面が重ね合わせられるということは,ドットを表す色に透明色が必要ですよね。(透明色がないと BG 面の下は完全に隠れてしまいます)上になる面が透明色の場合は,その下にある面のドットが表示されることになります。

まぁ,当たり前ですよね。

優先順位決定の流れ

結局のところ,画面に表示するドットを,BG のドットなのか,スプライトのドットなのかを判定すればよいのです。

その流れですが…,あくまで一つの方法ということで説明します。(…と言っても,とある古いアーケード基板を参考にしているので,その基板の仕様…とも言えますけど)

面の優先順は 3 通りなので,これを 2bit の選択入力として,マルチプレクサを通して,優先順を決定します。

ただ,上で書いたように,最前面のドットが常に表示されるわけではなく,透明色のドットは,表示されずに,その下になる面のドットが表示されなくてはなりませんよね。

この透明色の判定ですが…,この辺りのプログラミングをした方ならおわかりだと思いますが,透明色は,概ねカラーの 0 に割り当てられることが多いです。これは,プログラム的にわかりやすいという理由もあるかもしれませんが,全ビットがゼロになるので,回路も単純になるんですね。(と思います。多分…)

そして,これらの優先順情報と透明色判定情報をプライオリティエンコーダに突っ込んで,最終的に一番上に表示される面を決定します。

出力する面が決定したので,あとは,この面から出力されるドットデータを,マルチプレクサで選択,パレット変換回路へ入力して最終的な色が決まるというわけです。

パレット変換してアナログ RGB 信号へ

優先順位に従って,決定されたドット情報は,パターンのドットデータと,カラー番号から構成されています(厳密には,スプライトの場合,このカラー番号からカラールックアップテーブルを経由していますが)。

このカラー番号によって,同じドットの形をしていても,色を変えて表示することができるんですね。

…で,この変換はどうするのかと言うと…。

入力に対して出力が一対一になっています。そうです。マシン語でもお馴染みのテーブル変換です。

マシン語では,出力データのテーブルを用意しておき,入力データからアドレスを決定して,テーブルからデータを引きますよね。

これとほぼ同じです。

一般的に,このテーブルはパレットテーブルなどと呼ばれます(…よね?)。

ただ今回は,パレットのデータは,ROM の中に入れておいて,パターンデータとカラーデータをアドレスにして,この ROM から読み出します。

当然,ROM なので,予め用意されたカラーセットしか使えません。

RAM にすると,プログラマブルにパレットのデータを変更できますが,書き込みと読み出しを排他制御する必要があるので,面倒くさいことになります(笑)。

ちなみに,MSX1 は,パレット固定で,MSX2 以降は,パレットに任意の色を設定できます。

このパレット ROM から出力された RGB データはデジタルなデータです。

モニターに入力するアナログ RGB 信号は,その名の通りアナログな信号なので,抵抗などを通してアナログ変換してから最終的な信号として出力します。

これをモニターに入力してやれば,カラフル(?)なドットパターンが表示されます。

プライオリティコントロール基板

作成した基板がこちらです。

なんか,毎回 IC がズラッと並んだ基板なので,全く変わり映えしない感じですね…。(チョットだけ,アナログな回路もありますけど)

そして 9 階建て

毎回,1 枚ずつ増えていって,とうとう 9 枚です。

前々回くらいから,そろそろ不安定になってきそうなことを書いていましたが,不安定になりました!(笑)

電源投入直後は,IPL(イニシャルプログラムローダー)みたいなコードを,外部から DMA でメモリに書き込むのですが,この時点では,書き込んだデータをベリファイして問題ないことを確認してるのですが,その後,Z80 をブートすると,うんともすんとも言わなくなってしまうんです。

Z80 が暴走したものだとばかり思い込み,ノイズかな~と思っていましたが,Twitter のフォロワーの方から,電源周りでは?とのアドバイスをいただきました。そこで電圧を測定したら,4.5V くらいまで下がっています。今回,デバイス類は,ほとんど CMOS を使っていたので,この時点では,あまり気にしていませんでした。

そこで,ロジックアナライザで,ブート後の Z80 の波形を観察してみることにしました。そしたら,バスとコントロール信号がハイインピーダンス状態になっています(実際はプルアップされて H レベル)。「ん?」と思い,/RESET 信号を見てみたら,L になっているではないですか!

「なんでリセット解除されないの~?」と悩んでいたら…

  • 電圧低下
  • リセット

はい。このような動作をする IC があります。そうです。リセット IC です。

今回,使用したリセット IC は,その閾値を設定することができるのですが,それを 4.6V にしていたんですね。当然 4.6V を割り込むと,リセット信号を出します。ある意味,意図通りなのです。(笑)

まぁ,こんなことを繰り返すと,経験値上がります。

作って,失敗して,調べて,学ぶ。電子工作は,完成させることももちろん大事だと思いますが,私は,この新しい発見とか経験が一番大事かな~と思います。

そして動かしてみました

テストプログラムを作って,BG とスプライトを重ねて表示してみました。また,プライオリティ設定レジスタのチェックもしてみます。

MPEG4, 750bps, 7MB

ちょっとわかりづらいですが,スプライトと BG の優先順位変更もできています。

次回が最後の基板となる予定です

次回は,スクロール BG の基板を作ります。

回路自体は,以前作った BG 基板とほぼ同じですので,多分問題ないでしょう。

これでいよいよこの「Z80 ゲーム機」も完成…になるといいなぁ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA