diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/agb_sram.c | 89 | ||||
-rwxr-xr-x | src/titlescreen.c | 5 |
2 files changed, 92 insertions, 2 deletions
diff --git a/src/agb_sram.c b/src/agb_sram.c new file mode 100644 index 0000000..e58d5fa --- /dev/null +++ b/src/agb_sram.c @@ -0,0 +1,89 @@ +#include "global.h" +#include "agb_sram.h" + +static u16 verifySramFast_Work[80]; // buffer to hold code of VerifySramFast_Core +static u16 readSramFast_Work[64]; // buffer to hold code of ReadSramFast_Core + +u32 (*VerifySramFast)(const u8 *src, u8 *dest, u32 size); // pointer to verifySramFast_Work +void (*ReadSramFast)(const u8 *src, u8 *dest, u32 size); // pointer to readSramFast_Work + +void ReadSramFast_Core(const u8 *src, u8 *dest, u32 size) +{ + REG_WAITCNT = (REG_WAITCNT & ~3) | 3; + while (--size != -1) + *dest++ = *src++; +} + +void WriteSramFast(const u8 *src, u8 *dest, u32 size) +{ + REG_WAITCNT = (REG_WAITCNT & ~3) | 3; + while (--size != -1) + *dest++ = *src++; +} + +u32 VerifySramFast_Core(const u8 *src, u8 *dest, u32 size) +{ + REG_WAITCNT = (REG_WAITCNT & ~3) | 3; + while (--size != -1) + { + if (*dest++ != *src++) + return (u32)(dest - 1); + } + return 0; +} + +void SetSramFastFunc(void) +{ + u16 *src; + u16 *dest; + u16 size; + + src = (u16 *)ReadSramFast_Core; + // clear the least significant bit so that we get the actual start address of the function + src = (u16 *)((uintptr_t)src ^ 1); // NOTE: In Fire Emblem 8, this is '& ~1' instead of '^ 1'. + dest = readSramFast_Work; + // get the size of the function by subtracting the address of the next function + size = ((uintptr_t)WriteSramFast - (uintptr_t)ReadSramFast_Core) / 2; + // copy the function into the WRAM buffer + while (size != 0) + { + *dest++ = *src++; + size--; + } + // add 1 to the address of the buffer so that we stay in THUMB mode when bx-ing to the address + ReadSramFast = (void *)((uintptr_t)readSramFast_Work + 1); + + src = (u16 *)VerifySramFast_Core; + // clear the least significant bit so that we get the actual start address of the function + src = (u16 *)((uintptr_t)src ^ 1); // NOTE: In Fire Emblem 8, this is '& ~1' instead of '^ 1'. + dest = verifySramFast_Work; + // get the size of the function by subtracting the address of the next function + size = ((uintptr_t)SetSramFastFunc - (uintptr_t)VerifySramFast_Core) / 2; + // copy the function into the WRAM buffer + while (size != 0) + { + *dest++ = *src++; + size--; + } + // add 1 to the address of the buffer so that we stay in THUMB mode when bx-ing to the address + VerifySramFast = (void *)((uintptr_t)verifySramFast_Work + 1); + + REG_WAITCNT = (REG_WAITCNT & ~3) | 3; +} + +u32 WriteAndVerifySramFast(const u8 *src, u8 *dest, u32 size) +{ + u8 i; + u32 errorAddr; + + // try writing and verifying the data 3 times + for (i = 0; i < 3; i++) + { + WriteSramFast(src, dest, size); + errorAddr = VerifySramFast(src, dest, size); + if (errorAddr == 0) + break; + } + + return errorAddr; +} diff --git a/src/titlescreen.c b/src/titlescreen.c index a4e75e7..6a2bcac 100755 --- a/src/titlescreen.c +++ b/src/titlescreen.c @@ -1,6 +1,7 @@ #include "global.h" -#include "titlescreen.h" +#include "agb_sram.h" #include "m4a.h" +#include "titlescreen.h" #include "main.h" static void sub_114FC(void); @@ -852,5 +853,5 @@ void sub_11B74(void) sub_52C64(); sub_52B30(); gMain.unk40 = 0; - sub_55654(&gMain.unk40, 0x0E000544 /* Possibly SRAM address */, 4); + WriteAndVerifySramFast((const u8 *)&gMain.unk40, (void *)0x0E000544, 4); } |