#author("2023-04-14T18:36:10+09:00","","")
#freeze
#author("2023-05-29T23:50:16+09:00","","")
* カードリッジ [#yc5ce3cb]
前回のメモリエリアについてはカードリッジ以外のメモリ(IWRAM, EWRAM, PAK ROM)にコードや変数を置く方法を説明をしました。ところが電源を入れたとき、すべてのデータはROM領域(カードリッジ)にあります。その時点からいったいどうやってIWRAMやEWRAMに配置されていくのか、その流れを見ていきましょう。先に答えを言っておきますとROM領域にアクセスされた時「C:\devkitPro\devkitARM\arm-none-eabi\lib\gba_crt0.ld」([[github:https://github.com/devkitPro/devkitarm-crtls/blob/master/gba_crt0.s]])がまず一番最初に実行されます。よかったら平行して読んでみてください。~
前回のメモリエリアでは、カードリッジ以外のメモリ領域(IWRAM, EWRAM, PAK ROM)にコードや変数を置く方法を説明をしました。ところが電源を入れたとき、すべてのデータはROM(カードリッジ)にあります。その時点からどのようにしてIWRAMやEWRAMに配置されていくのか、その流れを見ていきましょう。

** .gbaファイルの正体 [#g45fc3f0]
実機のGBAにカードリッジを挿し電源をONにすると、そのカードリッジ内容はメモリの0x08000000からアクセスできるようになります。つまり.gbaファイルとは、その内容をファイル化しただけのものです。もちろんカードリッジはROM(リードオンリーメモリ)なので書き換え不可。あと大昔ということもあってデータは暗号化もされていませんでした。いい時代やったなあ・・・。~
** gbaファイルの正体 [#g45fc3f0]
実機にカードリッジを挿し電源をONにすると、そのカードリッジ内容はメモリの0x08000000からアクセスできるようになります。gbaファイルとは、その内容をファイル化しただけのものです。もちろんカードリッジはROM(リードオンリーメモリ)なので書き換え不可。大昔ということもあってデータは暗号化もされていませんでした。いい時代でしたねー・・・。ROM領域にアクセスされる最初のファイルは「C:\devkitPro\devkitARM\arm-none-eabi\lib\gba_crt0.ld」([[github:https://github.com/devkitPro/devkitarm-crtls/blob/master/gba_crt0.s]])です。よかったら軽く読んでみてください。

** ヘッダ [#jd52d4aa]
GBA上だと0x08000000~0x080000bf、.gbaファイル上だと0x00~0xbfまでの192(0xc0)サイズ分をヘッダと呼びます。内容は特に気にすることはないので素通りしましょう。一応次のような意味を持っています。~
GBA上だと0x08000000~0x080000bf、gbaファイル上だと0x00~0xbfまでの192(0xc0)サイズ分をヘッダと呼びます。内容は特に気にすることはないので素通りしましょう。一応次のような意味を持っています。

- Headspin's Guideから引用~
| 0x00 - 0x03 | 32 bit ARM B Jump to start of ROM executable |
| 0x04 - 0x9F | Nintendo Logo data                           |
| 0xA0 - 0xAB | Game Title                                   |
| 0xAC - 0xAF | Game Code                                    |
| 0xB0 - 0xB1 | Maker Code                                   |
| 0xB2 - 0xB2 | 0x96 Fixed                                   |
| 0xB3 - 0xB3 | Main Unit Code                               |
| 0xB4 - 0xB4 | Device Type                                  |
| 0xB5 - 0xBB | Reserved Area                                |
| 0xBC - 0xBC | Mask ROM Version                             |
| 0xBD - 0xBD | Compliment Check                             |
| 0xBE - 0xBF | Reserved Area                                |

エミュレータで見るとこのようになります。(Tools -> Memory viewer)~
エミュレータで見るとこのようになります。(Tools -> Memory viewer)
#ref(1.png,nolink)

** main関数までの処理 [#z40b2fe9]
main関数が実行されるまでの流れは以下のとおりです。~
main関数が実行されるまでの流れは以下のとおりです。

- 電源ON
- BIOSから起動し任天堂のタイトルロゴを表示する
- ROMの先頭領域0x08000000番地へジャンプ
- 割り込みベクタと、スタックの設定

- EWRAM領域を0クリア
- IWRAM領域のbssを0クリア
- EWRAM領域のsbssを0クリア

- IWRAM領域のdataへ変数(初期値)をコピー
- IWRAM領域のiwramへコードをコピー
- IWRAM領域のiwram0へiwram0のコードをコピー~
iwramとiwram0は別定義です。gba_cart.ldに.iwram0~9までが定義されています。詳しい事はわかりませんがおそらく容量が少ないために再配置できるように区切りを設けたのではないかと思います。
iwramとiwram0は別定義です。gba_cart.ldに.iwram0~9までが定義されています。詳しい事はわかりませんがおそらく容量が少ないために再配置できるように区切りを設けたのではないかと思います。普段のプログラミングでは指定しない内容なのでここではスルーして大丈夫です。

- EWRAM領域へコードや変数(初期値)をコピー~
変数にはあらかじめ初期値が決められているものがあります。その為のコピーです。~
変数にはあらかじめ初期値が決められているものがあります。その為のコピーです。

- libcやmalloc等の設定
- main関数へ

エミュレータで逆アセンブルするとこんな表示になります。~
エミュレータで逆アセンブルするとこんな表示になります。

- gba_crt0.ld(抜粋)
 @---------------------------------------------------------------------------------
 start_vector:
 @---------------------------------------------------------------------------------
 	mov	r0, #0x4000000			@ REG_BASE
 	str	r0, [r0, #0x208]
 
 	mov	r0, #0x12			@ Switch to IRQ Mode
 	msr	cpsr, r0
 	ldr	sp, =__sp_irq			@ Set IRQ stack
 	mov	r0, #0x1f			@ Switch to System Mode
 	msr	cpsr, r0
 	ldr	sp, =__sp_usr			@ Set user stack

#ref(2.png,nolink)

** チェックサムを忘れずに [#x859b6f6]
自作ゲームを作って実機で動かそうとしたらタイトルロゴで止まる、でもエミュレータでは大丈夫という現象。こんなことがあったらロムが壊れていないかのチェックサムを疑ってください。devkitProにはgbafix(C:\devkitPro\tools\bin)と呼ばれるチェックサム変更ツールがあります。忘れずに実行してください。

** マルチブート [#x118a29a]
マルチブートとはカードリッジを使わずに通信ケーブル(ブートケーブル)などで起動をする仕組みです。実機を2台持っていて対戦をしたい場合を想像するとわかりやすいと思います。一方はマリオカートのカードリッジを装着していて、一方はない状態で通信ケーブルのみで繋がっている。ホスト側からゲスト側にデータを転送します。この仕組みをマルチブートと呼びます。~
マルチブートとはカードリッジを使わずに通信ケーブルなどで起動する仕組みです。たとえば実機を2台持っていて、対戦ゲームをしたい場合を想像するとわかりやすいと思います。一方はマリオカートのカードリッジを装着していて、一方は通信ケーブルのみで繋がっている。この状態でホスト側からゲスト側にデータを転送して対戦をする、という仕組みです。devkitProではカードリッジなし状態を想定した制作も可能です。VBA-1.8.0-beta3ではファイル名で区別しており、xxx.gbaでしたらxxx.mb.gbaまたはxxx.mbとなります。インターネットでダウンロードしてきた自作ゲームがフリーズする場合、そもそもIWRAM, EWRAM領域にのみ展開されることを想定して作られているわけで、そりゃフリーズしますよね、という話です。

devkitProではカードリッジなし状態を想定したマルチブートロムの制作は可能です。VBA-1.8.0-beta3ではファイル名で区別しており、xxx.gbaでしたらxxx.mb.gbaまたはxxx.mbです。インターネットでダウンロードしてきた自作ゲームがフリーズする場合、そもそもIWRAM, EWRAM領域にのみ展開されることを想定して作られているわけでそりゃフリーズしますよね、という話です。~

** 履歴 [#ifbbf29c]
- 2023/04/12
- 2007/09/14


トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS