Using the above code will do nothing but freeze the system when running a retail cart. Also, if you startup the system from GBA mode, I don't think you are able to access the ARM9/DS slot anyways.
Look on GBATEK for the EEPROM/save area... that is what you will need to write/read to/from to do what are you looking to do. It's a completely different protocol...
DS Cartridge Backup
SPI Bus Backup Memory
Type Total Size Page Size Chip/Example Game/Example
EEPROM 0.5K bytes 16 bytes ST M95040-W (eg. Metroid Demo)
EEPROM 8K bytes 32 bytes ST M95640-W (eg. Super Mario DS)
EEPROM 64K bytes 128 bytes ST M95512-W (eg. Downhill Jam)
FLASH 256K bytes 256 bytes ST M45PE20 (eg. Skateland)
FLASH 512K bytes 256 bytes ST M25PE40? (eg. which/any games?)
FRAM 8K bytes No limit ? (eg. which/any games?)
FRAM 32K bytes No limit Ramtron FM25L256? (eg. which/any games?)
Type Max Writes per Page Data Retention
EEPROM 100,000 40 years
FLASH 100,000 20 years
FRAM No limit 10 years
SPI Bus Backup Memory is accessed via Ports 40001A0h and 40001A2h, see
DS Cartridge I/O Ports
For all EEPROM and FRAM types:
06h WREN Write Enable Cmd, no parameters
04h WRDI Write Disable Cmd, no parameters
05h RDSR Read Status Register Cmd, read repeated status value(s)
01h WRSR Write Status Register Cmd, write one-byte value
9Fh RDID Read JEDEC ID (not supported on EEPROM/FLASH, returns FFh-bytes)
For 0.5K EEPROM (8+1bit Address):
03h RDLO Read from Memory 000h-0FFh Cmd, addr lsb, read byte(s)
0Bh RDHI Read from Memory 100h-1FFh Cmd, addr lsb, read byte(s)
02h WRLO Write to Memory 000h-0FFh Cmd, addr lsb, write 1..MAX byte(s)
0Ah WRHI Write to Memory 100h-1FFh Cmd, addr lsb, write 1..MAX byte(s)
For 8K..64K EEPROM and for FRAM (16bit Address):
03h RD Read from Memory Cmd, addr msb,lsb, read byte(s)
02h WR Write to Memory Cmd, addr msb,lsb, write 1..MAX byte(s)
Note: MAX = Page Size (see above chip list) (no limit for FRAM).
For FLASH backup, commands should be same as for Firmware FLASH memory:
DS Firmware Serial Flash Memory
0 WIP Write in Progress (1=Busy) (Read only) (always 0 for FRAM chips)
1 WEL Write Enable Latch (1=Enable) (Read only, except by WREN,WRDI)
2-3 WP Write Protect (0=None, 1=Upper quarter, 2=Upper Half, 3=All memory)
For 0.5K EEPROM:
4-7 ONEs Not used (all four bits are always set to "1" each)
For 8K..64K EEPROM and for FRAM:
4-6 ZERO Not used (all three bits are always set to "0" each)
7 SRWD Status Register Write Disable (0=Normal, 1=Lock) (Only if /W=LOW)
WEL gets reset on Power-up, WRDI, WRSR, WRITE/LO/HI, and on /W=LOW.
The WRSR command allows to change ONLY the two WP bits, and the SRWD bit (if any), these bits are non-volatile (remain intact during power-down), respectively, the WIP bit must be checked to sense WRSR completion.
Detection (by examining hardware responses)
The overall memory type and bus-width can be detected by RDSR/RDID commands:
RDSR RDID Type (bus-width)
FFh, FFh,FFh,FFh None (none)
F0h, FFh,FFh,FFh EEPROM (with 8+1bit address bus)
00h, FFh,FFh,FFh EEPROM/FRAM (with 16bit address bus)
00h, xxh,xxh,xxh FLASH (usually with 24bit address bus)
And, the RD commands can be used to detect the memory size/mirrors (though that won't work if the memory is empty).
Pin-Outs for EEPROM and FRAM chips
Pin Name Expl.
1 /S Chip Select
2 Q Data Out
3 /W Write-Protect (not used in NDS, wired to VCC)
4 VSS Ground
5 D Data In
6 C Clock
7 /HOLD Transfer-pause (not used in NDS, wired to VCC)
8 VCC Supply 2.5 to 5.5V for M95xx0-W
FRAM (Ferroelectric Nonvolatile RAM) is fully backwards compatible with normal EEPROMs, but comes up with faster write/erase time (no delays), and with lower power consumption, and unlimited number of write/erase cycles. Unlike as for normal RAM, as far as I understand, the data remains intact without needing any battery.
I think it will be fairly straightforward after you find out the size of the save area...