ROMの先頭192バイト、つまり0x800_0000..800_00BF
はカートリッジヘッダです。
マルチブート時に、スレーブGBAではこのカートリッジヘッダの内容が0x2000000..20000BF
にもロードされます。(マルチブート専用のカートリッジヘッダエントリも0x20000C0
以降にロードされます)
オフセット | サイズ(バイト) | 内容 |
---|---|---|
0x00 | 4 | ROMエントリポイント (32bitのARM分岐命令, 例: B rom_start ) |
0x04 | 156 | Nintendo Logo(圧縮されたbitmap) |
0xA0 | 12 | ゲームタイトル (大文字ASCII) |
0xAC | 4 | ゲームコード (大文字ASCII) |
0xB0 | 2 | メーカーコード (大文字ASCII) |
0xB2 | 1 | 0x96 |
0xB3 | 1 | 0x00 |
0xB4 | 1 | デバイスタイプ (基本的に0x00) |
0xB5 | 7 | 予約領域(0) |
0xBC | 1 | ソフトウェアバージョン (基本的に0x00) |
0xBD | 1 | ヘッダのチェックサム |
0xBE | 2 | 予約領域(0) |
マルチブート時
オフセット | サイズ(バイト) | 内容 |
---|---|---|
0xC0 | 4 | RAMエントリポイント |
0xC4 | 1 | ブートモード |
0xC5 | 1 | SlaveID |
0xC6 | 26 | 未使用 |
0xE0 | 4 | JOYBUSエントリーポイント |
エントリポイントではCPUはシステムモードで実行されます。
カートリッジの実際のスタートアドレスにリダイレクトする32bit ARMオペコード用の領域で、通常は B ${start}
命令が入ります。
注意: このエントリはMultibootスレーブGBAでは無視されます(実際には、このエントリは上書きされ、以下で説明するように別のMultibootエントリポイントにリダイレクトされます)。
起動時に表示される任天堂のロゴを圧縮したデータが含まれています。このデータが欠損していたりするとカートリッジは動作しません。
圧縮データのコピーはBIOSに保存されており、GBAは2つのデータを比較し、BIOSのデータがカートリッジ(またはマルチブートヘッダ)と一致しない場合は動作を停止します。
これは、上記の任天堂ロゴのメモリ領域の一部であり、一般的には0x21
(0b0010_0001
)に設定する必要がありますが、bit2とbit7には他の値を設定することができます。
両方のbitがセットされる(つまり0xa5
)と、BIOSのFIQ/未定義命令ハンドラのロックが解除され、ハンドラはこれらの例外をカートリッジROMのユーザー定義ハンドラに転送します。
このとき、エントリーポイントは0x0800_00B4
(後述)に定義されています。
その他のbitの組み合わせは、現在のところ特別な機能を持っていないようです。
ここもまた、上記の任天堂ロゴのメモリ領域の一部であり、一般的には0xf8
(0b1111_1000
)に設定する必要がありますが、bit0-1には他の値を設定することができます。
起動時に、BIOSはあらかじめ定義されたアドレスストリームからいくつかのダミーリードを行います。これらのリードは一見無意味に見えますが、市販のカートリッジ内部のリードプロテクトを解除するためのものである可能性があります。
16個の事前定義されたアドレスストリームは、4bitのキーナンバーによって選択され、上位2bitは0x0800_009E
のbit0-1から得られ、下位2bitはヘッダーバイト0x9D..0xB7
のチェックサムから得られます。(XORして40hで割ったもの)
ゲームタイトルがASCIIフォーマットで格納されています。
最大12文字、全て大文字で00
が終端文字を表しています。
ゲームカセットのAGB-UTTD
に対応するゲームコードが格納されています。
- U: ユニークコード
- TT: ショートタイトル
- D: ROMの発売地域・言語
例: ロックマンエグゼ6 電脳獣ファルザー(JPN): AGB-BR6J
U: ユニークコード
ユニークコードは次のようになっています。
ユニークコード(U) | 内容 |
---|---|
A | 通常のゲーム (2001~2003) |
B | 通常のゲーム (2003~) |
C | 通常のゲーム (未使用) |
F | NESシリーズ |
K | 『ヨッシーの万有引力』 & 『コロコロパズル ハッピィパネッチュ!』 |
P | e-リーダー |
R | 『まわるメイド イン ワリオ』 |
U | 『ボクらの太陽』 & 『続・ボクらの太陽』 |
V | 『スクリューブレイカー 轟振どりるれろ』 |
TT: ショートタイトル
ショートタイトル(TT)は、基本的には、文字通りタイトルを省略したものが入ります。例えばPac Man
のショートタイトルはPM
です。
省略したものが別のゲームでTTとして既に使われているゲームには適当な2文字をTTにしている場合もあるようです。
D: ROMの発売地域・言語
D | 地域(言語) |
---|---|
J | 日本 |
F | フランス |
S | スペイン |
E | アメリカ(英語) |
D | ドイツ |
I | イタリア |
P | ヨーロッパ,その他 |
TODO
Code | Maker |
---|
ヘッダのチェックサムで、これが正しくない場合カートリッジは起動しません。
次のように計算します。
chk := byte(0)
for i := 0xA0; i <= 0xBC; i++ {
chk = chk - [i]
chk = (chk - 0x19) & 0xff
}
以下は、マルチブートされるソフトウェアのみ必要です。
マルチブートでは、上記192バイトをヘッダブロックとして0x2000000..0x20000BF
に転送し、実際のプログラム/データブロックの先頭(0x20000C0..
)にいくつかの追加ヘッダ情報を配置する必要があります。
この拡張ヘッダは、正しく設定する必要のあるマルチブートエントリポイントと、ブート処理によって上書きされる2つの予約バイトで構成されています。
この項目は、スレーブGBAがノーマルモードまたはマルチプレイモードで起動した場合のみ使用されます。
ここには通常、ARM32bitのB <start>
命令が格納されており、実際のブート処理へとジャンプします。
スレーブGBAのダウンロード処理では、この部分をマルチブート転送モードに対応した値で上書きします。
Value Expl.
01h Joybus mode
02h Normal mode
03h Multiplay mode
カートリッジでは、基本的にこのバイトはDCB 00h
で0x00
にしておきます。
マルチブートで転送するプログラムには、この位置や以下のIDバイトの位置に重要なプログラムコードやデータが含まれていないことを確認してください。
スレーブGBAがノーマルモードまたはマルチプレイモードで起動された場合、このバイトはそのスレーブGBAのスレーブIDで上書きされます(ノーマルモードでは常に0x01
になります)。
Value Expl.
01h Slave #1
02h Slave #2
03h Slave #3
カートリッジでは、基本的にこのバイトはDCB 00h
で0x00
にしておきます。
Joybusモードで起動した場合、この値は変更されず、マスターGBAから転送された値のままです。
見たところ使われていません。
GBAがJoybus転送モードを使ってブートされた場合、エントリポイントは20000C0h
ではなくこのアドレスに位置します。
ブート処理をこのアドレスに直接置くか、ここにB <start>
オペコードを格納して実際のブート処理にリダイレクトします。
また、Joybusモードをサポートするつもりがない場合(おそらくほとんど使われないでしょう)は、このエントリを無視してください。