ファミコンの完全自作ROM&カセット作ろう!〜cc65で起動ROMをつくる〜

先日、ファミコンに直差しできるROMカセットを作るというお話をしました。しかし、いくらハードウェアができたとしてもプログラムがないと動かないただの鉄の塊です。

■cc65は、僕らに新規の6502コンピューターを作らせてくれない


 そこでプログラムを作って書き込もうとしましたが、問題はcc65でROMに書き込める普通のプログラムデータを作成することが非常に困難であるという点でした。
 つまりどういうことかというと、cc65というコンパイラソフトは「新規の」6502ハードウェア開発向けには作られておらず、コモドール64やファミコンのエミュレーター向けの開発を考えられているのです。それがわかる仕様として、アセンブラで書いたプログラムをcc65で書き出す際に、どのハードウェア向けに書き出すかという旨を指定する必要があるのです。
 もし指定しなければ自動的にコモドール64向けに書き出されます。そして、プログラムの内容がそれに沿っていなければエラーとして判断され、かきだされることもありません。

■使いやすさの視点の違いから生まれた仕様


 もうひとつ、cc65が抱える問題としてORG命令が本来の動きとして働かないという点です。
 ORG命令とは、そのプログラムがメモリのどの位置から開始されるのかをしていする重要な命令です。これによってジャンプ命令やラベルがまともに使用できるし、6502においてはリセット割り込み(ゲームを開始する際に読み込まれるメモリ)の情報を書き込むメモリの位置を指定しなくてはいけないので、非常に重要な命令なのですがなんとcc65ではほぼ封印されています。ジャンプ先としては読み込まれきちんとコンパイルされますが
プログラムをコンパイルした際に指定した場所にプログラムが書き込まれていないのです。非常にバカバカしくなります。

ではcc65にはORG命令の代わりに何が使われているのかというとSEGMENT命令が利用されています。プログラムをSEGMENTで切り分け、その段階ではまだどこからそのプログラムを配置するのかを指定しません。指定はコンフィグファイルという別のファイルにて指定します。つまり、アセンブラファイルだけではプログラムを作成することができないのです。また、コンパイルした際にこのコンフィグファイルを結合させ、正しい位置にプログラムが配置されるようにしなければならないのです。さもなくば、書いたプログラムは頭から順番に詰め詰めに配置されまともに動くことのない文字の羅列として吐き出されることになります。

■「正しい」6502用プログラムをcc65で作成する方法

エミュレーター向けでなく、純粋にROMに書き込むためのプログラムをcc65を使って書き出す方法です。

・アセンブラ内での書き方の例

.segment “MAINPROGRAMNAME” 
LDA $09
STA $80

.segment “WARIKOMI
NMI: .byte $00,$00
RESET: .byte $80,$00
IRQ: .byte $00,$00

------------------------------------------------------------------------------------------------------------------
説明:.segment がいわゆるORGにあたる。“ ”の間にこのセグメントの名前を書き込む。
このセグメント名がコンフィグファイル内でのSEGMENTS内で使用する名前になる。
出来上がりましたらお好きな名前.asmとして保存します。.asmとはアセンブラファイルの拡張子です。
今回はmain.asmという名前で保存したことにします。

・コンフィグファイルの書き方の例(別のファイルを作成)

MEMORY{
MAINNAMAE: start = $8000, size=$7ffa, file = %O,fill = yes, define = yes;
 NAMAE: start=$7ffa,size=$0006,file=%O,fill=yes,define=yes;
}
SEGMENTS{
MAINPROGRAMNAME:load = MAINNAMAE,type = ro, define = yes;
WARIKOMI: load = NAMAE,type = ro,define = yes;
}
------------------------------------------------------------------------------------------------------------------
説明:SEGMENTSの中に先ほどの.segment 以降に書いた" "で挟んだ名前を書く。その後ろに各セグメントに対応したメモリの開始位置とサイズを記載した名前をload以降に記述する。どこが同じ部分なのかわかりやすいように色分けしておきました。

MEMORYの中には各メモリ配置とそのサイズ、データの記述がない範囲をどうするのかなどを記載します。スタート位置とサイズはかなり重要です。また、file後の%OのOは英語のオーの大文字ですのでご注意ください。

出来上がりましたら、ファイル名をお好きな名前.cfgにて保存します。.cfgはコンフィグファイルの拡張子です。
今回はmain.cfgという名前で保存したことにします。

・コンフィグファイルをコンパイラに読み込み、バイナリファイルを作成する方法

これはwindows版の書き出し方法なので、Macの場合インストール方法によってファイルディレクトリへの移動は必要ない場合があります。

C:¥cc65¥bin> cl65 -t none -C main.cfg -o main.bin main.asm

上の説明をしますと、C:¥cc65¥bin>がディレクトリの今の位置を示します。windowsの場合はここまでいかないとexeファイルを実行できないのと、同じ位置にコンパイルしたいアセンブラファイルとコンフィグファイルをおかないとダメです。

cl65 は今回使用するコンパイラです。cc65にするとC言語コンパイラになってしまうため、今回はこちらを使用します。

-t はターゲットの略で、コモドール64とかファミコンとか対象にしたいものをこの後に指定できます。今回は生ROMを作成したいので none にしています。

-C はコンフィグの略で、この後にコンフィグファイルの名前を書きます。拡張子まできちんと書いてあげましょう。

-o はアウトプットの略だと思われます。書き出したい形式をここで指定できますが、なんとHEXファイルには対応していません。おとなしくバイナリファイルにします。拡張子をつけた名前をつけてあげましょう。.binが拡張子になります。

最後のmain.asmがコンパイルするアセンブラファイルになります。最後にコンパイルするアセンブラファイルは記載しましょう。

これでエラーがなければ無事にコンパイルされ、cl65のexeファイルがある場所と同じところにバイナリファイルが作成されているはずです。あとはこれをROMに書き込めば完成というわけでございます!!!

と、今回はここまでで失礼いたします。次回は一つプログラムを書いて、実際にファミコンを動かすところをお送りできたらと思いますノシ
次の記事
Macintosh Plusを起動せよ その10 「フロッピードライブコネクタDsub-19Pinを自作する」
前の記事
ファミコンの完全自作ROM&カセットを作ろう!!その1~立ちはだかるコンパイラの壁~

コメント

このブログの人気の投稿

ファミコンの完全自作ROM&カセットを作ろう!!その1~立ちはだかるコンパイラの壁~

74HC595を使ってarduinoの16ビットパラレル出力に挑んでみた