mirror of
https://github.com/rvtr/GodMode9i.git
synced 2025-06-18 10:55:31 -04:00
Fix GBA EEPROM saves (#114)
* Fix GBA EEPROM saves * Clean up dumping error messages
This commit is contained in:
parent
647c936a2e
commit
b579cedd29
9
arm7/include/gba.h
Normal file
9
arm7/include/gba.h
Normal file
@ -0,0 +1,9 @@
|
||||
#define GBA_H
|
||||
#ifdef GBA_H
|
||||
|
||||
#include <nds/ndstypes.h>
|
||||
|
||||
void readEeprom(u8 *dst, u32 src, u32 len);
|
||||
void writeEeprom(u32 dst, u8 *src, u32 len);
|
||||
|
||||
#endif // GBA_H
|
123
arm7/source/gba.c
Normal file
123
arm7/source/gba.c
Normal file
@ -0,0 +1,123 @@
|
||||
#include "gba.h"
|
||||
|
||||
#include <nds/dma.h>
|
||||
#include <nds/memory.h>
|
||||
#include <nds/fifocommon.h>
|
||||
#include <string.h>
|
||||
|
||||
#define EEPROM_ADDRESS (0x09FFFF00)
|
||||
#define REG_EEPROM *(vu16 *)(EEPROM_ADDRESS)
|
||||
#define DMA3_CR_H *(vu16 *)(0x040000DE)
|
||||
|
||||
void EEPROM_SendPacket(u16 *packet, int size)
|
||||
{
|
||||
REG_EXMEMSTAT = (REG_EXMEMSTAT & 0xFFE3) | 0x000C;
|
||||
DMA3_SRC = (u32)packet;
|
||||
DMA3_DEST = EEPROM_ADDRESS;
|
||||
DMA3_CR = 0x80000000 + size;
|
||||
while((DMA3_CR_H & 0x8000) != 0);
|
||||
}
|
||||
|
||||
void EEPROM_ReceivePacket(u16 *packet, int size)
|
||||
{
|
||||
REG_EXMEMSTAT = (REG_EXMEMSTAT & 0xFFE3) | 0x000C;
|
||||
DMA3_SRC = EEPROM_ADDRESS;
|
||||
DMA3_DEST = (u32)packet;
|
||||
DMA3_CR = 0x80000000 + size;
|
||||
while((DMA3_CR_H & 0x8000) != 0);
|
||||
}
|
||||
|
||||
void gbaEepromRead8Bytes(u8 *out, u16 addr, bool short_addr)
|
||||
{
|
||||
u16 packet[68];
|
||||
|
||||
memset(packet, 0, 68 * 2);
|
||||
|
||||
// Read request
|
||||
packet[0] = 1;
|
||||
packet[1] = 1;
|
||||
|
||||
// 6 or 14 bytes eeprom address (MSB first)
|
||||
for(int i = 2, shift = (short_addr ? 5 : 13); i < (short_addr ? 8 : 16); i++, shift--) {
|
||||
packet[i] = (addr >> shift) & 1;
|
||||
}
|
||||
|
||||
// End of request
|
||||
packet[short_addr ? 8 : 16] = 0;
|
||||
|
||||
// Do transfers
|
||||
EEPROM_SendPacket(packet, short_addr ? 9 : 17);
|
||||
memset(packet, 0, 68 * 2);
|
||||
EEPROM_ReceivePacket(packet, 68);
|
||||
|
||||
// Extract data
|
||||
u16 *in_pos = &packet[4];
|
||||
for(int byte = 7; byte >= 0; --byte) {
|
||||
u8 out_byte = 0;
|
||||
for(int bit = 7; bit >= 0; --bit) {
|
||||
// out_byte += (*in_pos++) << bit;
|
||||
out_byte += ((*in_pos++) & 1) << bit;
|
||||
}
|
||||
*out++ = out_byte;
|
||||
}
|
||||
}
|
||||
|
||||
void gbaEepromWrite8Bytes(u8 *in, u16 addr, bool short_addr)
|
||||
{
|
||||
u16 packet_length = short_addr ? 73 : 81;
|
||||
u16 packet[packet_length];
|
||||
|
||||
memset(packet, 0, packet_length * 2);
|
||||
|
||||
// Write request
|
||||
packet[0] = 1;
|
||||
packet[1] = 0;
|
||||
|
||||
// 6 or 14 bytes eeprom address (MSB first)
|
||||
for(int i = 2, shift = (short_addr ? 5 : 13); i < (short_addr ? 8 : 16); i++, shift--) {
|
||||
packet[i] = (addr >> shift) & 1;
|
||||
}
|
||||
|
||||
// Extract data
|
||||
u16 *out_pos = &packet[short_addr ? 8 : 16];
|
||||
for(int byte = 7; byte >= 0; --byte) {
|
||||
u8 in_byte = *in++;
|
||||
for(int bit = 7; bit >= 0; --bit) {
|
||||
*out_pos++ = (in_byte >> bit) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
// End of request
|
||||
packet[packet_length - 1] = 0;
|
||||
|
||||
// Do transfers
|
||||
EEPROM_SendPacket(packet, packet_length);
|
||||
|
||||
// Wait for EEPROM to finish (should timeout after 10 ms)
|
||||
while((REG_EEPROM & 1) == 0);
|
||||
}
|
||||
|
||||
void readEeprom(u8 *dst, u32 src, u32 len)
|
||||
{
|
||||
int start, end;
|
||||
start = src >> 3;
|
||||
end = (src + len) >> 3;
|
||||
u8 buffer[8];
|
||||
for (int j = start; j < end; j++) {
|
||||
gbaEepromRead8Bytes(buffer, j, len == 0x200);
|
||||
fifoSendDatamsg(FIFO_USER_02, 8, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void writeEeprom(u32 dst, u8 *src, u32 len)
|
||||
{
|
||||
int start, end;
|
||||
start = dst >> 3;
|
||||
end = (dst + len) >> 3;
|
||||
u8 *ptr = src;
|
||||
for (int j = start; j < end; j++, ptr += 8) {
|
||||
gbaEepromWrite8Bytes(ptr, j, len == 0x200);
|
||||
}
|
||||
|
||||
fifoSendValue32(FIFO_USER_02, 0x454E4F44 /* 'DONE' */);
|
||||
}
|
@ -30,6 +30,8 @@
|
||||
#include <nds.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gba.h"
|
||||
|
||||
void my_installSystemFIFO(void);
|
||||
void my_sdmmc_get_cid(int devicenumber, u32 *cid);
|
||||
|
||||
@ -177,6 +179,19 @@ int main() {
|
||||
}
|
||||
*(u8*)(0x2FFFD08) = ((*(vu32*)(0x400481C) & BIT(3)) || !(*(vu32*)(0x400481C) & BIT(5))); // Set if there's no SD inserted
|
||||
resyncClock();
|
||||
|
||||
// Dump EEPROM save
|
||||
if(fifoCheckAddress(FIFO_USER_01)) {
|
||||
switch(fifoGetValue32(FIFO_USER_01)) {
|
||||
case 0x44414552: // 'READ'
|
||||
readEeprom((u8 *)fifoGetAddress(FIFO_USER_01), fifoGetValue32(FIFO_USER_01), fifoGetValue32(FIFO_USER_01));
|
||||
break;
|
||||
case 0x54495257: // 'WRITE'
|
||||
writeEeprom(fifoGetValue32(FIFO_USER_01), (u8 *)fifoGetAddress(FIFO_USER_01), fifoGetValue32(FIFO_USER_01));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
return 0;
|
||||
|
@ -21,23 +21,10 @@ extern bool expansionPakFound;
|
||||
|
||||
static sNDSHeaderExt ndsCardHeader;
|
||||
|
||||
void dumpFailMsg(bool save) {
|
||||
void dumpFailMsg(const char *msg) {
|
||||
font->clear(false);
|
||||
font->printf(0, 0, false, Alignment::left, Palette::white, "Failed to dump the %s.", save ? "save" : "ROM");
|
||||
font->update(false);
|
||||
|
||||
for (int i = 0; i < 60*2; i++) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
}
|
||||
|
||||
void saveWriteFailMsg(bool gba) {
|
||||
char sizeError[256];
|
||||
snprintf(sizeError, sizeof(sizeError), "The size of this save doesn't match the size of the inserted game %s.\n\nWrite cancelled!", gba ? "pak" : "card");
|
||||
|
||||
font->clear(false);
|
||||
font->print(0, 0, false, sizeError, Alignment::left, Palette::red);
|
||||
font->print(0, font->calcHeight(sizeError) + 1, false, "(<A> OK)");
|
||||
font->print(0, 0, false, msg, Alignment::left, Palette::red);
|
||||
font->print(0, font->calcHeight(msg) + 1, false, "(<A> OK)");
|
||||
font->update(false);
|
||||
|
||||
u16 pressed;
|
||||
@ -216,7 +203,7 @@ void ndsCardSaveDump(const char* filename) {
|
||||
u32 saveSize = cardNandGetSaveSize();
|
||||
|
||||
if(saveSize == 0) {
|
||||
dumpFailMsg(true);
|
||||
dumpFailMsg("Failed to dump the save.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -240,14 +227,14 @@ void ndsCardSaveDump(const char* filename) {
|
||||
cardRead(cardNandRwStart + src + i, copyBuf + i, true);
|
||||
}
|
||||
if (fwrite(copyBuf, 1, (currentSize >= 0x8000 ? 0x8000 : currentSize), destinationFile) < 1) {
|
||||
dumpFailMsg(true);
|
||||
dumpFailMsg("Failed to dump the save.");
|
||||
break;
|
||||
}
|
||||
currentSize -= 0x8000;
|
||||
}
|
||||
fclose(destinationFile);
|
||||
} else {
|
||||
dumpFailMsg(true);
|
||||
dumpFailMsg("Failed to dump the save.");
|
||||
}
|
||||
} else { // SPI
|
||||
unsigned char *buffer;
|
||||
@ -311,11 +298,7 @@ void ndsCardSaveRestore(const char *filename) {
|
||||
u32 saveSize = cardNandGetSaveSize();
|
||||
|
||||
if(saveSize == 0) {
|
||||
font->print(0, 0, false, "Unable to restore the save.");
|
||||
font->update(false);
|
||||
for (int i = 0; i < 60 * 2; i++) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
dumpFailMsg("Unable to restore the save.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -327,7 +310,7 @@ void ndsCardSaveRestore(const char *filename) {
|
||||
if(length != saveSize) {
|
||||
fclose(in);
|
||||
|
||||
saveWriteFailMsg(false);
|
||||
dumpFailMsg("The size of this save doesn't match the size of the inserted game card.\n\nWrite cancelled!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -388,8 +371,7 @@ void ndsCardSaveRestore(const char *filename) {
|
||||
fseek(in, 0, SEEK_SET);
|
||||
if(length != (auxspi ? (int)(LEN * num_blocks) : size)) {
|
||||
fclose(in);
|
||||
|
||||
saveWriteFailMsg(false);
|
||||
dumpFailMsg("The size of this save doesn't match the size of the inserted game card.\n\nWrite cancelled!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -478,12 +460,7 @@ void ndsCardDump(void) {
|
||||
}
|
||||
|
||||
if (cardInit(&ndsCardHeader) != 0) {
|
||||
font->clear(false);
|
||||
font->print(0, 0, false, "Unable to dump the save.");
|
||||
font->update(false);
|
||||
for (int i = 0; i < 60 * 2; i++) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
dumpFailMsg("Unable to dump the save.");
|
||||
return;
|
||||
}
|
||||
char gameTitle[13] = {0};
|
||||
@ -736,14 +713,14 @@ void ndsCardDump(void) {
|
||||
cardRead (src+i, copyBuf+i, false);
|
||||
}
|
||||
if (fwrite(copyBuf, 1, (currentSize>=0x8000 ? 0x8000 : currentSize), destinationFile) < 1) {
|
||||
dumpFailMsg(false);
|
||||
dumpFailMsg("Failed to dump the ROM.");
|
||||
break;
|
||||
}
|
||||
currentSize -= 0x8000;
|
||||
}
|
||||
fclose(destinationFile);
|
||||
} else {
|
||||
dumpFailMsg(false);
|
||||
dumpFailMsg("Failed to dump the ROM.");
|
||||
}
|
||||
ndsCardSaveDump(destSavPath);
|
||||
//}
|
||||
@ -758,19 +735,6 @@ void gbaCartSaveDump(const char *filename) {
|
||||
font->update(false);
|
||||
|
||||
saveTypeGBA type = gbaGetSaveType();
|
||||
|
||||
if(type == SAVE_GBA_EEPROM_05 || type == SAVE_GBA_EEPROM_8) {
|
||||
font->clear(false);
|
||||
font->print(0, 0, false, "EEPROM saves are not currently supported!\n\nUse GBA Backup Tool to backup/restore this game's save.\nhttps://gamebrew.org/wiki/GBA_Backup_Tool\n\n(<A> OK)");
|
||||
font->update(false);
|
||||
|
||||
do {
|
||||
scanKeys();
|
||||
swiWaitForVBlank();
|
||||
} while(!(keysDown() & KEY_A));
|
||||
return;
|
||||
}
|
||||
|
||||
u32 size = gbaGetSaveSize(type);
|
||||
if(size == 0)
|
||||
return;
|
||||
@ -810,17 +774,8 @@ void gbaCartSaveRestore(const char *filename) {
|
||||
return;
|
||||
|
||||
FILE *sourceFile = fopen(filename, "rb");
|
||||
u8 *buffer = new u8[size];
|
||||
if(!buffer || !sourceFile) {
|
||||
if(buffer) delete[] buffer;
|
||||
if(sourceFile) fclose(sourceFile);
|
||||
|
||||
font->clear(false);
|
||||
font->print(0, 0, false, "Failed to open save.");
|
||||
font->update(false);
|
||||
|
||||
for (int i = 0; i < 60 * 2; i++)
|
||||
swiWaitForVBlank();
|
||||
if(!sourceFile) {
|
||||
dumpFailMsg("Failed to open save.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -828,23 +783,18 @@ void gbaCartSaveRestore(const char *filename) {
|
||||
size_t length = ftell(sourceFile);
|
||||
fseek(sourceFile, 0, SEEK_SET);
|
||||
if(length != size) {
|
||||
delete[] buffer;
|
||||
fclose(sourceFile);
|
||||
|
||||
saveWriteFailMsg(true);
|
||||
dumpFailMsg("The size of this save doesn't match the size of the inserted game pak.\n\nWrite cancelled!");
|
||||
return;
|
||||
}
|
||||
|
||||
u8 *buffer = new u8[size];
|
||||
if (fread(buffer, 1, size, sourceFile) != size) {
|
||||
delete[] buffer;
|
||||
fclose(sourceFile);
|
||||
|
||||
font->clear(false);
|
||||
font->print(0, 0, false, "Failed to read save.");
|
||||
font->update(false);
|
||||
|
||||
for (int i = 0; i < 60 * 2; i++)
|
||||
swiWaitForVBlank();
|
||||
dumpFailMsg("Failed to read save.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -993,7 +943,7 @@ void gbaCartDump(void) {
|
||||
font->update(false);
|
||||
|
||||
if (fwrite(GBAROM + src / sizeof(u16), 1, 0x8000, destinationFile) != 0x8000) {
|
||||
dumpFailMsg(false);
|
||||
dumpFailMsg("Failed to dump the ROM.");
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
@ -1028,14 +978,14 @@ void gbaCartDump(void) {
|
||||
writeChange(cmd);
|
||||
readChange();
|
||||
if (fwrite(GBAROM + (0x1000 >> 1), 0x1000, 1, destinationFile) < 1) {
|
||||
dumpFailMsg(false);
|
||||
dumpFailMsg("Failed to dump the ROM.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(destinationFile);
|
||||
} else {
|
||||
dumpFailMsg(false);
|
||||
dumpFailMsg("Failed to dump the ROM.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -41,11 +41,6 @@
|
||||
#include <dirent.h>
|
||||
|
||||
#include "gba.h"
|
||||
// #include "dsCard.h"
|
||||
|
||||
// #include "display.h"
|
||||
// #include "globals.h"
|
||||
// #include "strings.h"
|
||||
|
||||
inline u32 min(u32 i, u32 j) { return (i < j) ? i : j;}
|
||||
inline u32 max(u32 i, u32 j) { return (i > j) ? i : j;}
|
||||
@ -59,9 +54,6 @@ inline u32 max(u32 i, u32 j) { return (i > j) ? i : j;}
|
||||
|
||||
#define MAGIC_H1M_ 0x5f4d3148
|
||||
|
||||
#define EEPROM_ADDRESS (0x0DFFFF00)
|
||||
#define REG_EEPROM *(vu16 *)(EEPROM_ADDRESS)
|
||||
|
||||
|
||||
// -----------------------------------------------------------
|
||||
bool gbaIsGame()
|
||||
@ -77,94 +69,40 @@ bool gbaIsGame()
|
||||
return false;
|
||||
}
|
||||
|
||||
void EEPROM_SendPacket(u16 *packet, int size)
|
||||
{
|
||||
REG_EXMEMCNT = (REG_EXMEMCNT & 0xFFE3) | 0x000C;
|
||||
DMA3_SRC = (u32)packet;
|
||||
DMA3_DEST = EEPROM_ADDRESS;
|
||||
DMA3_CR = 0x80000000 + size;
|
||||
while((DMA3_CR & 0x80000000) != 0);
|
||||
}
|
||||
void readEeprom(u8 *dst, u32 src, u32 len) {
|
||||
// EEPROM reading needs to happen on ARM7
|
||||
sysSetCartOwner(BUS_OWNER_ARM7);
|
||||
fifoSendValue32(FIFO_USER_01, 0x44414552 /* 'READ' */);
|
||||
fifoSendAddress(FIFO_USER_01, dst);
|
||||
fifoSendValue32(FIFO_USER_01, src);
|
||||
fifoSendValue32(FIFO_USER_01, len);
|
||||
|
||||
void EEPROM_ReceivePacket(u16 *packet, int size)
|
||||
{
|
||||
REG_EXMEMCNT = (REG_EXMEMCNT & 0xFFE3) | 0x000C;
|
||||
DMA3_SRC = EEPROM_ADDRESS;
|
||||
DMA3_DEST = (u32)packet;
|
||||
DMA3_CR = 0x80000000 + size;
|
||||
while((DMA3_CR & 0x80000000) != 0);
|
||||
}
|
||||
|
||||
// local function
|
||||
void gbaEepromRead8Bytes(u8 *out, u16 addr, bool short_addr)
|
||||
{
|
||||
u16 packet[68];
|
||||
|
||||
memset(packet, 0, 68 * 2);
|
||||
|
||||
// Read request
|
||||
packet[0] = 1;
|
||||
packet[1] = 1;
|
||||
|
||||
// 6 or 14 bytes eeprom address (MSB first)
|
||||
for(int i = 2, shift = (short_addr ? 5 : 13); i < (short_addr ? 8 : 16); i++, shift--) {
|
||||
packet[i] = (addr >> shift) & 1;
|
||||
}
|
||||
|
||||
// End of request
|
||||
packet[short_addr ? 8 : 16] = 0;
|
||||
|
||||
// Do transfers
|
||||
EEPROM_SendPacket(packet, short_addr ? 9 : 17);
|
||||
memset(packet, 0, 68 * 2);
|
||||
EEPROM_ReceivePacket(packet, 68);
|
||||
|
||||
// Extract data
|
||||
u16 *in_pos = &packet[4];
|
||||
for(int byte = 7; byte >= 0; --byte) {
|
||||
u8 out_byte = 0;
|
||||
for(int bit = 7; bit >= 0; --bit) {
|
||||
// out_byte += (*in_pos++) << bit;
|
||||
out_byte += ((*in_pos++) & 1) << bit;
|
||||
}
|
||||
*out++ = out_byte;
|
||||
}
|
||||
}
|
||||
|
||||
// local function
|
||||
void gbaEepromWrite8Bytes(u8 *in, u16 addr, bool short_addr = false)
|
||||
{
|
||||
u16 packet_length = short_addr ? 73 : 81;
|
||||
u16 packet[packet_length];
|
||||
|
||||
memset( packet, 0, packet_length * 2);
|
||||
|
||||
// Write request
|
||||
packet[0] = 1;
|
||||
packet[1] = 0;
|
||||
|
||||
// 6 or 14 bytes eeprom address (MSB first)
|
||||
for(int i = 2, shift = (short_addr ? 5 : 13); i < (short_addr ? 8 : 16); i++, shift--) {
|
||||
packet[i] = (addr >> shift) & 1;
|
||||
}
|
||||
|
||||
// Extract data
|
||||
u16 *out_pos = &packet[short_addr ? 8 : 16];
|
||||
for(int byte = 7; byte >= 0; --byte) {
|
||||
u8 in_byte = *in++;
|
||||
for(int bit = 7; bit >= 0; --bit) {
|
||||
*out_pos++ = (in_byte >> bit) & 1;
|
||||
// Read the data from FIFO
|
||||
u8 *ptr = dst;
|
||||
while(ptr < dst + len) {
|
||||
if(fifoCheckDatamsg(FIFO_USER_02)) {
|
||||
fifoGetDatamsg(FIFO_USER_02, 8, ptr);
|
||||
ptr += 8;
|
||||
}
|
||||
}
|
||||
|
||||
// End of request
|
||||
packet[packet_length - 1] = 0;
|
||||
sysSetCartOwner(BUS_OWNER_ARM9);
|
||||
}
|
||||
|
||||
// Do transfers
|
||||
EEPROM_SendPacket(packet, packet_length);
|
||||
void writeEeprom(u32 dst, u8 *src, u32 len) {
|
||||
// EEPROM writing needs to happen on ARM7
|
||||
sysSetCartOwner(BUS_OWNER_ARM7);
|
||||
fifoSendValue32(FIFO_USER_01, 0x54495257 /* 'WRIT' */);
|
||||
fifoSendValue32(FIFO_USER_01, dst);
|
||||
fifoSendAddress(FIFO_USER_01, src);
|
||||
fifoSendValue32(FIFO_USER_01, len);
|
||||
|
||||
// Wait for EEPROM to finish (should timeout after 10 ms)
|
||||
while((REG_EEPROM & 1) == 0);
|
||||
// Wait for it to finish
|
||||
while(!(fifoCheckValue32(FIFO_USER_02) && fifoGetValue32(FIFO_USER_02) == 0x454E4F44 /* 'DONE' */)) {
|
||||
swiWaitForVBlank();
|
||||
}
|
||||
|
||||
sysSetCartOwner(BUS_OWNER_ARM9);
|
||||
}
|
||||
|
||||
saveTypeGBA gbaGetSaveType() {
|
||||
@ -173,19 +111,17 @@ saveTypeGBA gbaGetSaveType() {
|
||||
|
||||
for (int i = 0; i < (0x02000000 >> 2); i++, data++) {
|
||||
if (*data == MAGIC_EEPR) {
|
||||
u8 *buf = new u8[0x2000];
|
||||
u8 *ptr = buf;
|
||||
for (int j = 0; j < 0x400; j++, ptr += 8) {
|
||||
gbaEepromRead8Bytes(ptr, j, false);
|
||||
for(int sleep=0;sleep<512000;sleep++);
|
||||
}
|
||||
u8 *buffer = new u8[0x2000];
|
||||
readEeprom(buffer, 0, 0x2000);
|
||||
|
||||
// Check if first 0x800 bytes are duplicates of the first 8
|
||||
for(int j = 8; j < 0x800; j += 8) {
|
||||
if(memcmp(buf, buf + j, 8) != 0) {
|
||||
delete[] buf;
|
||||
if(memcmp(buffer, buffer + j, 8) != 0) {
|
||||
delete[] buffer;
|
||||
return SAVE_GBA_EEPROM_8;
|
||||
}
|
||||
}
|
||||
delete[] buf;
|
||||
delete[] buffer;
|
||||
return SAVE_GBA_EEPROM_05;
|
||||
} else if (*data == MAGIC_SRAM) {
|
||||
// *always* 32 kB
|
||||
@ -236,21 +172,11 @@ uint32 gbaGetSaveSize(saveTypeGBA type)
|
||||
bool gbaReadSave(u8 *dst, u32 src, u32 len, saveTypeGBA type)
|
||||
{
|
||||
int nbanks = 2; // for type 4,5
|
||||
bool eeprom_long = true;
|
||||
|
||||
switch (type) {
|
||||
case SAVE_GBA_EEPROM_05: {
|
||||
eeprom_long = false;
|
||||
}
|
||||
case SAVE_GBA_EEPROM_05:
|
||||
case SAVE_GBA_EEPROM_8: {
|
||||
int start, end;
|
||||
start = src >> 3;
|
||||
end = (src + len) >> 3;
|
||||
u8 *ptr = dst;
|
||||
for (int j = start; j < end; j++, ptr += 8) {
|
||||
gbaEepromRead8Bytes(ptr, j, !eeprom_long);
|
||||
for(int sleep=0;sleep<512000;sleep++);
|
||||
}
|
||||
readEeprom(dst, src, len);
|
||||
break;
|
||||
}
|
||||
case SAVE_GBA_SRAM_32: {
|
||||
@ -327,22 +253,11 @@ bool gbaIsAtmel()
|
||||
bool gbaWriteSave(u32 dst, u8 *src, u32 len, saveTypeGBA type)
|
||||
{
|
||||
int nbanks = 2; // for type 4,5
|
||||
bool eeprom_long = true;
|
||||
|
||||
switch (type) {
|
||||
case SAVE_GBA_EEPROM_05: {
|
||||
eeprom_long = false;
|
||||
}
|
||||
case SAVE_GBA_EEPROM_05:
|
||||
case SAVE_GBA_EEPROM_8: {
|
||||
/*
|
||||
int start, end;
|
||||
start = dst >> 3;
|
||||
end = (dst + len) >> 3;
|
||||
u8 *ptr = src;
|
||||
for (int j = start; j < end; j++, ptr+=8) {
|
||||
gbaEepromWrite8Bytes(ptr, j, eeprom_long);
|
||||
}
|
||||
*/
|
||||
writeEeprom(dst, src, len);
|
||||
break;
|
||||
}
|
||||
case SAVE_GBA_SRAM_32: {
|
||||
@ -432,7 +347,7 @@ bool gbaFormatSave(saveTypeGBA type)
|
||||
switch (type) {
|
||||
case SAVE_GBA_EEPROM_05:
|
||||
case SAVE_GBA_EEPROM_8:
|
||||
// TODO: eeprom is not supported yet
|
||||
// EEPROM doesn't need erasing
|
||||
break;
|
||||
case SAVE_GBA_SRAM_32:
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* savegame_manager: a tool to backup and restore savegames from Nintendo
|
||||
* DS cartridges. Nintendo DS and all derivative names are trademarks
|
||||
* by Nintendo. EZFlash 3-in-1 is a trademark by EZFlash.
|
||||
* by Nintendo.
|
||||
*
|
||||
* gba.h: header file for gba.cpp
|
||||
*
|
||||
@ -46,4 +46,4 @@ bool gbaWriteSave(u32 dst, u8 *src, u32 len, saveTypeGBA type);
|
||||
bool gbaFormatSave(saveTypeGBA type);
|
||||
|
||||
|
||||
#endif // __SLOT2_H__
|
||||
#endif // __GBA_H__
|
Loading…
Reference in New Issue
Block a user