PIC AVR 工作室->TopPage->AVRの工作->スプライト表示器

スプライト表示器

スプライト表示器の概要

スプライト表示器サムネイル

前代未聞のAVRで作ったスプライト表示器です。UARTで座標とスプライトパターン番号を受信して、スプライトをNTSCの ビデオ信号にして表示します。

現在2つのバージョンがあります。1つは、同時に9個のスプライトが表示できるもの(V2と呼びます)。MSXなどと違い、 横1列に9個同時表示することも可能です。

もう一つは、全画面に同時に25個のスプライトが表示できるもの(V4と呼びます)。こちらは、同時に25個表示できますが、 MSXなどと同様に横1列には4個までしか表示できません。(4個以上横一列に並べて表示すると5個目以降は表示されません。)

いずれのバージョンもスプライト表示だけではやれることに限度があるので、背景表示もできるように 背景表示器も作っちゃいました(別ページ参照)。 メインCPU→スプライト表示器→背景表示器の3つをUARTで直列接続して使うことが出来ます。モノクロ表示です。

多機能とは言いがたいですが、処理速度はそこそこ速いし、最近はTINY2313がPIC16F84並に安く手に入るので、 ちょっとした用途に便利かと。

サンプルムービー:スプライト表示器のキャプチャ画面

キャプチャー画面をフラッシュムービーにしました。画面をクリックすると再生します。
フラッシュで再生すると、なんかちょっとカクカクする時ありますが、実物はちゃんとスムーズに動きます。念のため。

このムービーはスプライト表示器V4をテストボードV1に書き込んでみたサンプルです。 一部のスプライトしか動いてませんが、もちろん全部のスプライトを動かすことが出来ます。

(テストボードV1はコントロール側CPUもTINY2313なので、25個全部のスプライトを表示するにはSRAMが小さすぎでした… スプライト1個につきX軸Y軸スプライト番号の計3バイトが必要で、それだけでも75バイト必要なんです。 メインCPUにMEGA48あたりを使えば25個全部動作できます。例えばPLAYER などならフルスペックで使えます。)

ちなみに、適当なウェイトを入れて表示しています。ウェイトを入れないと速すぎてマトモに見れません。

使い方

V2、V4ともにTINY2313用のプログラムです。

メインCPUはAVRでもPICでもH8でも、UARTで115.2kbpsでデータの送信ができさえすれば何でもいいです。 信号の電圧を5Vppに調整すればPCでも接続OKです(PCに繋いで使う人は居ないでしょうが…)。

横に4つ以上並べて表示したい場合はV2を、とにかくたくさんのスプライトを表示したい場合にはV4を選ぶとよろしいでしょう。

詳しい使い方や仕様、サンプル回路図、サンプルソース、オリジナルビットマップの作り方などをアーカイブにまとめてあります。 下のダウンロードからまずは説明書(PDFファイル)をダウンロードしてご一読ください。

コメント

AVRというタイムマシンで、ようやく80年代まで遡ることはできました!が、70年代のタイトースペースインベーダーや ナムコギャラクシアンまでは遡ることが出来ませんでした…

それにしてもAVRって1命令1クロックで動くので、20MHz動作なら20MIPS! 動作速度に関してはPICじゃ太刀打ち できませんね。速い速い!ずいぶん前に公開されたPIC用のBREAKOUTなどと比べると、ずいぶん細かいドット絵が描けていると思います。 動作が速いことをいいことに、だいぶ悪乗りしちゃいました…。

20MHzのAVRなら、水平同期1本分の中にスプライト表示のデコードがもっとたくさんできるかと目論んでいたんですが、 ソースとにらめっこしてギリギリまで詰め込んでみても9個がやっとでした。まぁ、スプライト9個で作れるゲームはそれほど多く無いだろうと思い、 妥協策として横方向はMSXと同じ4個までの表示と割り切り、その代わりに同時にたくさんのスプライトを表示できるバージョンも作りました。 それでも頑張って25個程度がせいぜいでした。ふぅ。MEGAシリーズならハードウェア乗算命令が2クロックでできるので、 もう少し詰め込めそうな気もするのですが…

それにしてもここまで悪乗りしちゃうと、次は「カラー化」「3Dポリゴン対応」ですね! (3Dポリゴンは冗談です!でも、カラー化については色々考えてみました。 クロックが20MHzや14.3MHzでカラーコンポジット信号のドット表示はムリがあると思いますが、コンポーネント出力 (もしくはD1端子出力)にして、メモリがもう少し大きいAVRを使えば出来そうな気がしています。 実際、ソニーのWEGAシリーズのD1端子の輝度端子(コンポーネントでいう緑端子)にこのスプライト表示器の出力を繋いでみたら、 ちゃんと白黒映像は出ましたよ!あとはRとBの色差端子用信号を作るだけ?

ダウンロード

スプライト表示器V2用アーカイブ(クリックすると開きます)

スプライト表示器V4用アーカイブ(クリックすると開きます)

(注)ビットマップデータ書き換えツールの入力ファイルは、V2が標準でd:\99\ntsc_sprite02_orgin.hexに、 V4が標準でd:\99\ntsc_sprite04_origin.hexになっているので適宜修正して使ってください。 使い方の詳細はスプライト表示器V2/V4説明書(PDFファイル)をご参照ください。または、他の言語に移植するなりして もっと使いやすくしていただければ助かります。

99BASICインタプリタについては、VECTORなどで「99BASIC」と 検索して頂けばすぐに見つかります。別途ご用意ください。

オマケ

アセンブラソースはかなりスパゲティー状態なので、当面非公開にしたいと思います。(質問受けても1つ1つに答えられないと思うので)  スパゲティーだかミートソースだかわからんがソース見てみたいぞ!というご意見がたくさん集まるようでしたら公開したいと思います。 リクエストしてください。ただ、ご自身でもこんなようなの作ってみたいという人向けに、処理タイミングが一番シビアな「画面表示のロジック」部分 だけひとまず記しておきます。クリックするとソースの一部が開きます。 ご参考になるかは分かりませんが…。

一応簡単に解説します。

o_dataは表示するための8ビット(1バイト)のデータが格納されるレジスタです。SRAM上のLINE_IMGのところに1ライン分 20バイト(160ビット)をあらかじめ格納しておくと、ここからo_dataに1バイトずつ読み出されて、1ビットずつ表示します。 (ただし表示されるのは2バイト目~18バイト目の17バイト分=136ドットだけです。)

1ビット目~7ビット目は比較的余裕を持って処理できるのですが、8ビット目は表示後にSRAMから次の1バイトを読み出す 必要があり、ここの処理の長さが肝になります。今回はプログラムメモリの省エネを考慮し、1バイト毎に17回ループさせて処理しているので、 切り詰めて切り詰めても6クロックが限界だと思いますが、ループをさせずに136ビット分を直列で処理すれば1ドット3クロックまで縮められるはずです。 その代わり、かなりプログラムメモリを消費しますが。

ちなみに、今回のプログラムのように、1ライン置きにドットを表示するような場合、20MHzのAVRでは6クロック毎に ドットを表示すると縦横比がほぼイコールになります。(計算上は、6クロックより少し長いのですが、クロックは小数に出来ないし、 7クロックでは少し横長になっちゃうし。パッと見も正方形に近いのでOKとしました。)

もし1ライン置きでは無く毎ライン表示を行う場合は、縦方向のドットサイズが半分になるので、それに併せて3クロックで表示すると 大体正方形のドットが描けると思います。

あと、ソースをご覧になると分かると思いますが、PB0の1端子だけに出力するのではなく、Bポート全体に1バイト分出力しています。 ビット単位で出力をするともっとクロック数が必要になってしまうため、ローテイト/シフト命令を利用してクロック数を稼いでいます。 この結果、Bポートのほかのピンには常にゴミデータが出力されることになります。ご注意。