Skip to content

Latest commit

 

History

History
190 lines (123 loc) · 8.49 KB

header.md

File metadata and controls

190 lines (123 loc) · 8.49 KB

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はシステムモードで実行されます。

0x00 - エントリーポイント

カートリッジの実際のスタートアドレスにリダイレクトする32bit ARMオペコード用の領域で、通常は B ${start}命令が入ります。

注意: このエントリはMultibootスレーブGBAでは無視されます(実際には、このエントリは上書きされ、以下で説明するように別のMultibootエントリポイントにリダイレクトされます)。

0x04-0x9f - 任天堂のロゴ

起動時に表示される任天堂のロゴを圧縮したデータが含まれています。このデータが欠損していたりするとカートリッジは動作しません。

圧縮データのコピーはBIOSに保存されており、GBAは2つのデータを比較し、BIOSのデータがカートリッジ(またはマルチブートヘッダ)と一致しない場合は動作を停止します。

0x9c - デバッグ有効フラグ(bit2, 7)

これは、上記の任天堂ロゴのメモリ領域の一部であり、一般的には0x21(0b0010_0001)に設定する必要がありますが、bit2とbit7には他の値を設定することができます。

両方のbitがセットされる(つまり0xa5)と、BIOSのFIQ/未定義命令ハンドラのロックが解除され、ハンドラはこれらの例外をカートリッジROMのユーザー定義ハンドラに転送します。

このとき、エントリーポイントは0x0800_00B4(後述)に定義されています。

その他のbitの組み合わせは、現在のところ特別な機能を持っていないようです。

0x9e - カートリッジのキーナンバーの上位2bit(bit0, 1)

ここもまた、上記の任天堂ロゴのメモリ領域の一部であり、一般的には0xf8(0b1111_1000)に設定する必要がありますが、bit0-1には他の値を設定することができます。

起動時に、BIOSはあらかじめ定義されたアドレスストリームからいくつかのダミーリードを行います。これらのリードは一見無意味に見えますが、市販のカートリッジ内部のリードプロテクトを解除するためのものである可能性があります。

16個の事前定義されたアドレスストリームは、4bitのキーナンバーによって選択され、上位2bitは0x0800_009Eのbit0-1から得られ、下位2bitはヘッダーバイト0x9D..0xB7のチェックサムから得られます。(XORして40hで割ったもの)

0xa0 - ゲームタイトル

ゲームタイトルがASCIIフォーマットで格納されています。

最大12文字、全て大文字で00が終端文字を表しています。

0xac - ゲームコード

ゲームカセットの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 ヨーロッパ,その他

0xb0-0xb1 - メーカーコード

TODO

Code Maker

0xbd - ヘッダのチェックサム

ヘッダのチェックサムで、これが正しくない場合カートリッジは起動しません。

次のように計算します。

chk := byte(0)
for i := 0xA0; i <= 0xBC; i++ {
    chk = chk - [i]
    chk = (chk - 0x19) & 0xff
}

マルチブート時

以下は、マルチブートされるソフトウェアのみ必要です。

マルチブートでは、上記192バイトをヘッダブロックとして0x2000000..0x20000BFに転送し、実際のプログラム/データブロックの先頭(0x20000C0..)にいくつかの追加ヘッダ情報を配置する必要があります。

この拡張ヘッダは、正しく設定する必要のあるマルチブートエントリポイントと、ブート処理によって上書きされる2つの予約バイトで構成されています。

0xc0 - エントリポイント(ノーマル/マルチプレイモード用)

この項目は、スレーブGBAがノーマルモードまたはマルチプレイモードで起動した場合のみ使用されます。

ここには通常、ARM32bitのB <start>命令が格納されており、実際のブート処理へとジャンプします。

0xc4 - ブートモード

スレーブGBAのダウンロード処理では、この部分をマルチブート転送モードに対応した値で上書きします。

  Value  Expl.
  01h    Joybus mode
  02h    Normal mode
  03h    Multiplay mode

カートリッジでは、基本的にこのバイトはDCB 00h0x00にしておきます。

マルチブートで転送するプログラムには、この位置や以下のIDバイトの位置に重要なプログラムコードやデータが含まれていないことを確認してください。

0xc5 - スレーブID

スレーブGBAがノーマルモードまたはマルチプレイモードで起動された場合、このバイトはそのスレーブGBAのスレーブIDで上書きされます(ノーマルモードでは常に0x01になります)。

  Value  Expl.
  01h    Slave #1
  02h    Slave #2
  03h    Slave #3

カートリッジでは、基本的にこのバイトはDCB 00h0x00にしておきます。

Joybusモードで起動した場合、この値は変更されず、マスターGBAから転送された値のままです。

0xc6..0xdf - 不使用

見たところ使われていません。

0xe0 - エントリポイント(Joybusモード用)

GBAがJoybus転送モードを使ってブートされた場合、エントリポイントは20000C0hではなくこのアドレスに位置します。

ブート処理をこのアドレスに直接置くか、ここにB <start>オペコードを格納して実際のブート処理にリダイレクトします。

また、Joybusモードをサポートするつもりがない場合(おそらくほとんど使われないでしょう)は、このエントリを無視してください。