#author("2023-05-15T11:49:11+09:00;2023-04-17T09:41:30+09:00","","")
#freeze
#author("2023-05-25T13:31:05+09:00","","")
* SRAM [#l2b2fce9]
GBAには電源を切ってもデータが残る領域としてCart RAMがあります。カードリッジを分解して覗いてみると本体チップの横にある小さなチップがそれに当たります。折角の機会ですから型番を検索して仕様を調べてみるのもいいかもしれません。この部品にはSRAM(32KB)、EEPROM(512B or 8KB)、Flash ROM(64KB)などの種類があります。特に扱いやすいのはSRAMで、自作ゲームを作られている方はだいたい使用しています。ここではSRAMの使い方のみを説明します。
GBAには電源を切ってもデータが残る領域としてCart RAMがあります。カードリッジを分解して覗いてみると、本体チップの横にある小さなチップがそれに当たります。折角の機会ですからチップの型番を検索して仕様を調べてみるのもいいかもしれません。この部品にはSRAM(32KB)、EEPROM(512B or 8KB)、Flash ROM(64KB)などの種類があります。特に扱いやすいのはSRAMで、自作ゲームを作られている方はだいたい使用しています。ここではSRAMの使い方のみ説明します。

** 仕様方法 [#d53787a2]
SRAMは32KBのサイズを持っていてアドレスは0x0E000000~0xE007FFFまでとなっています。読み書きにはu8*ポインタを使い、レジスタの設定などの前準備はまったく不要です。ただし実機でテストしたい場合、マジコンの種類によってはCart RAMの形式を指定する必要があるかもしれません。以下にサンプルコードを用意しましたので参考にしていただければと思います。
** 使用方法 [#d53787a2]
SRAMは32KBのサイズを持っていてアドレスは0x0E000000~0xE007FFFまでとなっています。読み書きはu8*(ポインタ)を使い、レジスタの設定などの前準備はまったく不要です。ただし実機でテストしたい場合、マジコンの種類によってはCart RAMの形式を指定する必要があるかもしれません。以下にサンプルコードを用意しましたので参考にしてください。

 #include "lib/gba.h"
 
 #define ADR_SRAM     (u8*)0xe000000
 
 //---------------------------------------------------------------------------
 u8 SRAMRead8(u32 offset)
 {
 	u8* sram = (u8*)ADR_SRAM + offset;
 	return (u8)sram[0];
 }
 //---------------------------------------------------------------------------
 u16 SRAMRead16(u32 offset)
 {
 	u16 ret;
 
 	ret  = SRAMRead8(offset++);
 	ret |= SRAMRead8(offset) << 8;
 
 	return ret;
 }
 //---------------------------------------------------------------------------
 u32 SRAMRead32(u32 offset)
 {
 	u32 ret;
 
 	ret  = SRAMRead8(offset++);
 	ret |= SRAMRead8(offset++) <<  8;
 	ret |= SRAMRead8(offset++) << 16;
 	ret |= SRAMRead8(offset)   << 24;
 
 	return ret;
 }
 //---------------------------------------------------------------------------
 void SRAMWrite8(u32 offset, u8 data)
 {
 	u8* sram = (u8*)ADR_SRAM + offset;
 	*sram = (u8)(data & 0xff);
 }
 //---------------------------------------------------------------------------
 void SRAMWrite16(u32 offset, u16 data)
 {
 	SRAMWrite8(offset++, (u8)((data   ) & 0xff));
 	SRAMWrite8(offset++, (u8)((data>>8) & 0xff));
 }
 //---------------------------------------------------------------------------
 void SRAMWrite32(u32 offset, u32 data)
 {
 	SRAMWrite8(offset++, (u8)((data    ) & 0xff));
 	SRAMWrite8(offset++, (u8)((data>>8 ) & 0xff));
 	SRAMWrite8(offset++, (u8)((data>>16) & 0xff));
 	SRAMWrite8(offset++, (u8)((data>>24) & 0xff));
 }
 //---------------------------------------------------------------------------
 u8* SRAMGetPointer()
 {
 	return ADR_SRAM;
 }
 //---------------------------------------------------------------------------
 void WaitForVsync(void)
 {
 	while (*(volatile u16*)0x4000006 >= 160) {};
 	while (*(volatile u16*)0x4000006 <  160) {};
 }
 //---------------------------------------------------------------------------
 int main(void)
 {
 	// エミュレータのTools->Memory viewerで書き込まれた値を確認してください
 	// SRAMのアドレス:E000000
 	SRAMWrite8(0x00, 1);
 	SRAMWrite16(0x04, 2);
 	SRAMWrite32(0x08, 0xdeadbeef);
 
 	// エミュレータのTools->Loggingで読み込まれた値を確認してください
 	TRACE("0x%x\n", SRAMRead8(0x00));
 	TRACE("0x%x\n", SRAMRead16(0x04));
 	TRACE("0x%x\n", SRAMRead32(0x08));
 
 	for(;;)
 	{
 		WaitForVsync();
 	}
 }

関数にも記載されていますが、''SRAMは8bitづつしかアクセスできない''のでそのことは忘れないでください。

** 履歴 [#p2587320]
- 2023/04/14
- 2007/09/26


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