上に戻る
3.ROMイメージの内部構造
概要
 ROMのファイル内の構造を書いてみようかと。
 一応、ファミコン、スーファミ、GBの3機種分。
 まぁ、ファミコンがメインなんですがね……
NESの3大(?)内部構造
 .nesファイルは、その中のデータを2〜3のカタマリに分類できます。
 それぞれ、『ヘッダ』『プログラム(PRG)ロム(PROM?)』『キャラクタ(CHR)ロム(CROM)』です。
 『ヘッダ』の役割は、続く『PROM』『CROM』のサイズを指定したり、ROMカートリッジ内の構造をあらわすデータなどです。
 本物のカートリッジの場合、物理的におかれた部品により指定・制御されますが、イメージですので、こういった風にヘッダを付けて、どんな構造をしているか……というのを示す必要があるみたいです。
 したがって、『ヘッダ』のデータは、ROMカートリッジ内には実際には存在していないデータです。ついでに、昔は、『ヘッダ』がついていないイメージもあったらしいです……(ファイル名で区別していた?)
 『プログラムロム』は、文字通り、プログラムが書いてあるROMです。プログラムといっても、数値データも含みます。マップ改造をする場合なんかは、この中の、数値データの方を主にいじっていくことになります。
 『キャラクタロム』は、グラフィックデータが書いてあるROMです。中には、『プログラムロム』内にグラフィックデータがあって、『キャラクタロム』の存在しないソフトもあります。
どんな風に並んでる?
 ファミコンは息の長いハードでしたので、多種多様な容量のソフトが存在します。
 で、そのサイズを指定するのが、先ほど出てきた『ヘッダ』です。
 『ヘッダ』は必ず16バイトです。適当なROMをバイナリエディタで開いてみてください。ここでは、例によって^^μブロック002を開いてみます。一応ここに置いておきます
μブロックのヘッダ
 範囲選択されている、ファイル先頭から16バイトがヘッダです。
 詳細は省略しますが、最初の4バイト(4E 45 53 1A)は、NESROMがNESROMであることを誇示(?)するデータです。エミュで走らせるとき、この4バイトがコレと一致しなかったら、まずエラー終了するでしょう……
 大事なのは次から2バイトです。
 5バイト目(位置は04h)のデータは、『プログラムロムのサイズ÷4000h』です。
 6バイト目(位置は05h)のデータは、『キャラクタロムのサイズ÷2000h』です。
 正常なROMイメージであれば、『ヘッダ』の後に『プログラムロム』が、上記の量だけ、さらに続けて『キャラクタロム』が上記の量だけ存在するはずです。
NESロム図解
作ってから思ったが、この図どう考えても要らないよな……
ROM拡張
 ファミコンは、本来(?)、『プログラムロム』は8000hバイトまで、『キャラクタロム』は2000hバイトまでしか扱えないものでした。
 しかし、カートリッジ内に、MMC(メモリマッパーコントローラー)という物を積むことで、この制限を突破し、より多くのサイズのロムを、『切り替えて』使うことができます。
(ハードウェアはさっぱりなんだが、最初からそういう風にできる仕様だったのかな?
 どうも、後付で、こんなことができようになるとは思えないんだけどなぁ)
 あくまでも、切り替えであるので、(例えば)離れたところにあるデータは同時に参照できなかったりします。
 『プログラムロム』の領域は2000h毎、『キャラクタロム』の領域は400h毎に区切られており、それらを本来の制限である8000hと2000hに『割り当てて』使用します。
(これは一例ですが……)
 わかりづらい説明ですが、図解してみました……余計わかりづらいような(汗)
拡張の方法な図
 一例とか言いましたが、実際にはMMCやカートリッジ内部の構造により、どんな風に区切られていて、どんな風に割り当てられるかは変わります。
 規格が統一されていなかったのか、やたらめったら規格に種類があります……ソフトを調べる前に、どんな規格であるかを意識する必要がありそうです。
 そのソフトがどんな構造であるかは、やはり『ヘッダ』に書いてあります。
 ヘッダの内容の詳細については、Google等で調べればすぐにわかると思いますが、例えば、
 『いつも通り』:http://izumo.cool.ne.jp/itsumodori/index.html の、
 http://izumo.cool.ne.jp/itsumodori/old/023.htmlで解説されています。
 スーファミ.smcの構造
 正直よく知らんのですが^^スーファミのイメージにはヘッダがあることと無いことがあるようです。
 違いは簡単で、カートリッジからダンプしたデータそのままのものが、ヘッダ無しのもので、それにヘッダをつけたのものがヘッダ有りのものです。(なんか当たり前のような……)
 ヘッダは200hバイトだと思います。あるエミュのソースの読み込みルーチンを見る限り^^
 自分がダンプに使ったソフトではヘッダをつけないのでわかりません……
 ファミコンと違い、ヘッダ以外の、その中身はプログラムとキャラクタの区別はありません。
 全部プログラムROM……と見ればいいでしょうか……
 ヘッダつきはわからんので無視します^^ROMの先頭から200hバイト削ればヘッダ無しになるようですし……
 スーファミのROMのタイプ
 正直よく知らんのですが(こればっか……)、スーファミのROMには、LoROMとHiROMという2種類があるようです。
 LoROMは、8000hバイト毎に区切られています。HiROMは10000hバイト毎に区切られているようです。
 LoROMとHiROMでは、アドレスの割り当てられ方が異なるようです。
 スーファミの埋め込み情報
 スーファミのROMカートリッジには、そのカートリッジがどういうものなのか……という情報が埋め込まれています。
 だから、ヘッダをつけなくてもエミュレーションに支障が無いようです。
 問題は埋め込まれている場所で、実は、LoROMとHiROMで場所が異なります……
 LoROMですと、7FB0hバイト目〜、HiROMだと、FFB0hバイト目〜です。
 よくみると、これらは、上で述べた『区切り』……最初の『区切り』の最後のほうです。
 こういった情報は、エミュレーションに欠かせない情報ですが、じゃあどうやってLoROMとHiROMが区別できるのでしょうか。
 埋め込み情報の中に、ある計算をするとかならずFFFFhになる部分がある……などということをヒントに特定するようです。
 手元のエミュのソースによると、他にもいろいろな情報をまとめて、LoROMであるかHiROMであるかを点数化して、どちらかを決めているようです。
 しかし、大雑把な方法ですが、人間には簡単に見分けがついたりします^^
 適当なスーファミROMをバイナリエディタで読み込んで、7FC0h辺りと、FFC0h辺りをそれぞれみてください。
 どちらかに、そのゲームの『タイトル』を表しそうな文字が見えるはずです。
 実はこれも埋め込み情報の一つです。よって、7FC0h辺りで見えた場合LoROM、FFC0h辺りで見えた場合はHiROMだと思います。
 ……とか書いてみたけど、実はよく知らんのですよね^^最後までこればっか。
GBの構造
 GBにはヘッダが無いようです。
 GBにもいくつかタイプがあるようですが、それ以外わからないので、MBC1というタイプのカートリッジのみ説明してみます。
構造といっても……
 これも、プログラムとキャラクタに区別はありません。(というか、ヘッダがあったり、キャラクタROMに別れていたりするファミコンが例外か?)
 プログラムは、4000hバイトごとに区切りになっているようです。
 少し前にヘッダが無いことを書きましたが、GBにも、プログラム内に埋め込み情報があるため、ヘッダの必要が無いようです。
 埋め込み情報は、100hバイト目〜です。
オチ?
 なんつーか、ファミコンもですが、それ以外の解説は特にグダグダですな……っていうのは置いておいて。
 ファミコンやGBのプログラムは、ある一定容量毎に区切られています。
 そんなわけで、アクセスに制限があったりするわけです。
 ちなみに、スーファミでも、一応区切りはありますが、区切りを超えたアクセスをする命令がCPUにあったりして、そんなに意識する必要は無いみたいです。
(13)2007年1月14日 プレさ兵衛
inserted by FC2 system