オレ仕様のゲーム機を作ろう(その29)
前回からオレ仕様ゲーム機「重禄」の制作に入り,インターフェース基板を作りました。
Raspberry Pi から,バスにアクセスしてメモリ(入出力ポート)内容の読み書きを確認できました。これで Raspberry Pi から,プログラムやデータをメモリに転送できるようになりそうです。
今回は,モトローラの MC68000 MPU を搭載した MPU 基板を作成したいと思います。
MC68000 について
このサイトをご覧になっている人には説明が不要かもしれませんよね。歴史やアーキテクチャについては ウィキペディア に詳しい説明が書いてあります。
今回の「重禄」は,基本的な表示周りの回路は,前回制作した「鶏八」から概ね流用しようと思っていますので,主な違いは,この MPU になります。
今までは,ザイログの Z80 CPU を扱ってきたので,その違いや気づいたことについて書いてみたいと思います。
データバス
まず,データバス幅が 8bit から 16bit へ倍になりました。当然 1 回のメモリアクセスで 16bit のデータを読み書きできます。32bit のデータの読み書きもできますが,Z80 の 16bit データ読み書きと同じように,2 回に分けてアクセスされます。
今回も,メモリは従来と同じ一般的な 8bit データバスの SRAM を使いますので,かならず 2 個をワンセットにして使うことになります。
Z80 のメモリアクセスは,8bit アクセスのみなのですが,信号は,/MREQ,/RD, /WR でアクセスしていました。アドレスバス出力後に,/MREQ をアクティブにして,/RD で読み込み,/WR で書き込みみたいな感じです。
対して,MC68000 は,基本 16bit アクセスなのですが,メモリへバイト(8bit)書き込みする場合は,2 つある SRAM のどちらか一方に書き込むことになります。
そのため,アドレスバスに信号を出力した後の /AS(アドレスストローブ),データを入出力するときの /UDS,/LDS(それぞれ上位バイト,下位バイトのデータストローブ),読み書きを指定する R/W を使って制御します。
/UDS をアクティブにすると,メモリの偶数アドレス,/LDS をアクティブにすると,メモリの奇数アドレスへのアクセスになるんですね。もちろんワード(16bit)アクセスの場合は,どちらもアクティブになります。
ウェイト
Z80 は通常はノーウェイト動作をしていて,メモリアクセスウェイトなどを掛けたい場合,CPU の外部から /WAIT 信号で必要な長さのウェイトをかけるようになっています。
MC68000 の場合は,この発想と逆になっているというか,通常はウェイトを掛ける前提になっています。
…というのは,/DTACK という信号を外部からアクティブにしない限り,メモリアクセス後,ウェイトが掛かりっぱなしになるんですね。
比較的速いデバイスは,アクセス後にすぐに /DTACK をアクティブにすれば良いし,MPU にウェイトを掛けたい場合は,アクセス後,必要な長さのあとで/DTACK をアクティブにすれば良いということです。
割り込み
Z80 の割り込みは,マスク(禁止)することができるマスカブル割り込み(/INT)と,マスクすることができないノンマスカブル割り込み(/NMI)の 2種類がありました。
多数の割り込みを使いたい場合,割り込みの優先順位などは外部の回路で制御する必要があります。
対して MC68000 は,7 つの割り込み(レベル 1 からレベル 7)を入力することができ,それぞれに優先順位がついています。
その中のレベル 7 割り込みはマスクすることができないノンマスカブル割り込み(NMI)です。
ゲーム機レベルで使う分には,これだけで十分便利に使えますね。
その他
内部レジスタ構造や特権レベル,命令セット,アドレッシングモードなどは,MC68000 でプログラミングした人ならもうお馴染みだと思いますので省略します(笑)。Z80 に比べたらめちゃくちゃ強力だと思います(当たり前だ)。
作成した基板

(クリックで拡大します)
簡単に説明します。
その存在感で一目瞭然(笑)な,一番大きな 64 ピンのパッケージが 68000 MPU です。東芝製の CMOS なので,TMP68HC000 です。それにしてもデカイです。
右側には,SRAM があり,大きな方はプログラムコードを入れるメモリで,最大4MB まで搭載可能です。
なんと!X68030 の搭載メモリに匹敵します!(もういいから…)
ただ,手元に 6 個しかなかったので,現状は,3MB です。
その下の小さい方のメモリは 64KB のワーク RAM です。
今回は,ROM エミュレータではありませんので,プログラム転送後も書き換え可能です。自己書き換えもできます(自分はやらない方ですけど…)。
左下にある D-SUB 9 ピンのコネクタはお馴染みのジョイスティックコネクタです。メガドライブパッドを接続します。この辺は「鶏八」と同じですね。
割り込みは,VBLANK 割り込みと,HBLANK 割り込み,NMI ボタンからの割り込みを入れることができます。
左上のジャンパスイッチで,68000 の動作クロックを 7.5MHz と 15MHz に切り替えることができます。15MHz 動作時は,対応した 68000 が必要になりますね(多分)。
右下のジャンパスイッチで,メモリアクセス時に,1 ウェイトを入れることができます。遅い SRAM を使うときはウェイトを入れられるようにしましたが,多分使うことがないような気がします。
動作確認
いつものように,基板を上にスタックしていきます。

68000 MPU とジョイスティック,外部割り込みを使うことができるようになったので,それらを使ったテストプログラムを作りました。
Eclipse を使ってデバッグができるようにしてあるので,ソフトウェアの開発はこれを使って行っていきます。
もちろん,Eclipse からビルドをすることもできます。ボタン一発で各ソースファイルをアセンブル,リンクして実行ファイルを作成できますが,自分は,bash ターミナル上から make しています。

動作確認用のテストプログラムを動かしてみます。
最初は,VBLANK 割り込みの確認です。1/60 秒間隔で割り込みが入りますので,これを 60 回カウントすると 1 秒になります。1 秒おきにカウンタをインクリメントして,それをそのまま発光ダイオードレジスタに書き込んでいます。
続いて,パッド入力の確認です。これは,メガドライブパッドからの入力をそのまま発光ダイオードレジスタに書き込んでいます。
最後は,NMI ボタンによる割り込みです。プログラム動作中に,NMI ボタンを押すと外部からのブレークとして,Eclipse 上でプログラムをブレークすることができます。再度 Elcipse から動作再開することができます。(動画には写っていないですね…)
なんとか,うまく動作しているようですね。
今回も一発動作したのですが,BG やスプライト基板からのウェイト信号のチェックがまだできないので,安心はできないかも…(笑)。
さて,今回はここまでです。
次回は,画面出力信号周りの基板を作りたいと思います。
それでは次回に続きます!