なるほどえたきちのブログじゃねーの

チラ裏雑記帳

ポケモン過去作の解析とか乱数調整とかそこら辺。不定期更新。

【FRLG,Em】CartRAMの取り扱いメモ

メモ記事です

ポケモン等のGBAソフトのセーブデータは基本的にCartRAMに保存されますが、このRAMは通常のWorkRAMとは読み書きの方法が異なるので愚直に弄ろうとしてもまず上手くいきません。
この記事ではポケモンで使用されているFRAM(1Mbit)の扱い方について記します。

↓FRLG/Emで使用されているらしいFRAMのデータシート
f:id:BZL:20190922061033p:plain

但しこのデータシートには1MbitのFRAMを扱う上で肝となっているバンクの切り替えについて記述されていません。(見落としてるだけかもしれないけど)
今回はよく使われるデータ書き込みとバンク切り替えについてのみ解説したいと思います。

バンク切り替えについて



CartRAMは基本的に0x0E000000-0x0E00FFFFのアドレス空間を持っています。
しかし1MbitのFRAMの場合、このアドレス空間だけではメモリの全領域を参照させることができません。
ここで使用するのがバンク切り替えです。
メモリ内のアドレス0x00000-0x0FFFFをバンク0、アドレス0x10000-0x1FFFFをバンク1として扱うことで実質的に0x0E000000-0x0E01FFFFのアドレス空間を使用することができるようになります。
しかしこのバンク切り替えは使用するアドレスが0x0E00FFFFまでの範囲を超えていれば自動的に行われる訳ではなく、プログラムを組むユーザー側で適宜切り替える必要があります。
また、アドレス空間はあくまで0x0E000000-0x0E00FFFFの範囲なので、メモリ内アドレス0x10000以降を参照させる場合はバンク1に切り替えた後に0x10000を始点としたアドレス指定を行う必要があります。
(例:0x0E01C000を参照させたい場合はバンク1に切り替えた後に0x0E00C000を参照させる)

バンク切り替え処理は以下のコードの通りです。

/*バンク切り替えサンプルコード*/
.thumb
 
/*r0 = バンクID*/
 
/*コマンド操作にstrb命令を使用しているが実際にデータは書き込まれない*/
ldr r1, =0x0e005555
ldr r2, =0x0e002aaa
ldr r3, =0x0e000000
mov r4, #0xb0
strb r2, [r1] /*0x5555 <- 0xAA*/
strb r1, [r2] /*0x2AAA <- 0x55*/
strb r4, [r1] /*0x5555 <- 0xB0*/
strb r0, [r3] /*0x0000 <- バンクID*/


データ書き込みについて



次はFRAMへのデータ書き込みの方法について解説します。
前述のバンク切り替えと同じく、strb命令を使用したコマンド操作が必要なのでWorkRAMと同じように扱っても書き換えることができません。
また、1byte書き込む度に再度コマンド操作を挟む必要があります。
データの読み込みに関してはバンク合わせてから普通にldrbで読み込むだけです。

書き込み処理は以下のコードの通りです。

/*データ書き込みサンプルコード*/
.thumb
 
/*r0 = 任意のデータ(1byte)*/
/*r1 = 書き込み先アドレス*/
 
ldr r2, =0x0e005555
ldr r3, =0x0e002aaa
mov r4, #0xa0
strb r3, [r2] /*0x5555 <- 0xAA*/
strb r2, [r3] /*0x2AAA <- 0x55*/
strb r4, [r2] /*0x5555 <- 0xA0*/
 
/*データ書き込み*/
/*この書き込み処理以外はCartRAM上には反映されない*/
strb r0, [r1]