summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/save.s383
-rw-r--r--asmdiff.sh2
-rw-r--r--include/config.h21
-rw-r--r--include/gba/gba.h1
-rw-r--r--include/gba/isagbprint.h50
-rw-r--r--include/global.h1
-rw-r--r--src/libisagbprn.c177
-rw-r--r--src/save.c211
8 files changed, 460 insertions, 386 deletions
diff --git a/asm/save.s b/asm/save.s
index 2ebaaa4..6eaeedc 100644
--- a/asm/save.s
+++ b/asm/save.s
@@ -5,389 +5,6 @@
.text
- thumb_func_start sub_8011CA8
-sub_8011CA8:
- push {lr}
- adds r3, r0, 0
- adds r2, r1, 0
- ldr r0, =gUnknown_203B184
- ldr r0, [r0]
- ldr r0, =0xfff
- adds r1, r2, r0
- cmp r1, 0
- bge _08011CBE
- ldr r0, =0x1ffe
- adds r1, r2, r0
-_08011CBE:
- asrs r1, 12
- ldr r0, [r3]
- adds r0, r1
- str r0, [r3]
- pop {r0}
- bx r0
- .align 2, 0
- .pool
- thumb_func_end sub_8011CA8
-
- thumb_func_start WriteSaveSector
-WriteSaveSector:
- push {r4-r6,lr}
- adds r5, r1, 0
- adds r4, r2, 0
- ldr r6, [r0]
- adds r1, r4, 0
- bl sub_8011CA8
- adds r0, r5, 0
- adds r1, r4, 0
- bl CalculateChecksum
- ldr r0, _08011D04
- ldr r0, [r0]
- cmp r0, 0
- bne _08011D08
- adds r0, r6, 0
- adds r1, r5, 0
- adds r2, r4, 0
- bl WriteFlashData
- adds r1, r0, 0
- b _08011D28
- .align 2, 0
-_08011D04: .4byte gUnknown_203B184
-_08011D08:
- bl sub_800DAB8
- lsls r0, 24
- cmp r0, 0
- beq _08011D38
- lsls r0, r6, 16
- lsrs r0, 16
- adds r1, r5, 0
- adds r2, r4, 0
- bl sub_800DAB4
- lsls r0, 24
- movs r1, 0
- cmp r0, 0
- bne _08011D28
- movs r1, 0x3
-_08011D28:
- cmp r1, 0x4
- bne _08011D30
- movs r0, 0x1
- b _08011D3A
-_08011D30:
- cmp r1, 0
- bne _08011D38
- movs r0, 0
- b _08011D3A
-_08011D38:
- movs r0, 0x2
-_08011D3A:
- pop {r4-r6}
- pop {r1}
- bx r1
- thumb_func_end WriteSaveSector
-
- thumb_func_start ReadSaveSector
-ReadSaveSector:
- push {r4-r6,lr}
- adds r5, r1, 0
- adds r4, r2, 0
- ldr r6, [r0]
- adds r1, r4, 0
- bl sub_8011CA8
- ldr r0, _08011D64
- ldr r0, [r0]
- cmp r0, 0
- bne _08011D68
- adds r0, r6, 0
- adds r1, r5, 0
- adds r2, r4, 0
- bl ReadFlashData
- adds r1, r0, 0
- b _08011D86
- .align 2, 0
-_08011D64: .4byte gUnknown_203B184
-_08011D68:
- bl sub_800DAB8
- lsls r0, 24
- cmp r0, 0
- beq _08011D8A
- lsls r0, r6, 16
- lsrs r0, 16
- adds r1, r5, 0
- adds r2, r4, 0
- bl sub_800DAB0
- lsls r0, 24
- movs r1, 0
- cmp r0, 0
- beq _08011D8A
-_08011D86:
- cmp r1, 0
- beq _08011D8E
-_08011D8A:
- movs r0, 0x1
- b _08011DA2
-_08011D8E:
- adds r0, r5, 0
- adds r1, r4, 0
- bl ValidateChecksum
- lsls r0, 24
- cmp r0, 0
- bne _08011DA0
- movs r0, 0
- b _08011DA2
-_08011DA0:
- movs r0, 0x2
-_08011DA2:
- pop {r4-r6}
- pop {r1}
- bx r1
- thumb_func_end ReadSaveSector
-
- thumb_func_start sub_8011DA8
-sub_8011DA8:
- movs r0, 0x1
- bx lr
- thumb_func_end sub_8011DA8
-
- thumb_func_start sub_8011DAC
-sub_8011DAC:
- push {r4-r7,lr}
- mov r7, r8
- push {r7}
- adds r6, r0, 0
- ldr r0, _08011DE4
- mov r8, r0
- movs r1, 0x5
- bl MemoryAlloc
- adds r5, r0, 0
- movs r1, 0x89
- lsls r1, 3
- adds r4, r5, r1
- adds r0, r6, 0
- adds r1, r5, 0
- mov r2, r8
- bl ReadSaveSector
- adds r7, r0, 0
- cmp r7, 0
- beq _08011DE8
- adds r0, r6, 0
- adds r1, r5, 0
- mov r2, r8
- bl ReadSaveSector
- adds r7, r0, 0
- b _08011DF0
- .align 2, 0
-_08011DE4: .4byte 0x000057d4
-_08011DE8:
- adds r0, r6, 0
- mov r1, r8
- bl sub_8011CA8
-_08011DF0:
- cmp r7, 0
- beq _08011DF6
- b _08011F6E
-_08011DF6:
- ldr r2, _08011E38
- adds r0, r5, r2
- ldr r1, [r0]
- ldr r0, _08011E3C
- cmp r1, r0
- beq _08011E04
- movs r7, 0x4
-_08011E04:
- cmp r7, 0
- beq _08011E0A
- b _08011F6E
-_08011E0A:
- ldr r0, _08011E40
- ldr r1, [r0]
- cmp r1, 0
- bne _08011E48
- ldr r1, _08011E44
- adds r0, r5, r1
- ldr r0, [r0]
- bl sub_8011C28
- movs r2, 0x83
- lsls r2, 3
- adds r0, r5, r2
- ldr r0, [r0]
- bl sub_8011C40
- movs r1, 0x84
- lsls r1, 3
- adds r0, r5, r1
- ldr r0, [r0]
- bl SetRngState
- b _08011E60
- .align 2, 0
-_08011E38: .4byte 0x00000414
-_08011E3C: .4byte 0x05071412
-_08011E40: .4byte gUnknown_203B184
-_08011E44: .4byte 0x0000041c
-_08011E48:
- ldr r2, _08011E80
- adds r0, r5, r2
- ldr r0, [r0]
- str r0, [r1, 0x54]
- subs r2, 0x4
- adds r0, r5, r2
- ldr r0, [r0]
- str r0, [r1, 0x50]
- adds r2, 0x8
- adds r0, r5, r2
- ldr r0, [r0]
- str r0, [r1, 0x58]
-_08011E60:
- cmp r7, 0
- beq _08011E66
- b _08011F6E
-_08011E66:
- ldr r0, _08011E84
- ldr r0, [r0]
- cmp r0, 0
- bne _08011E88
- adds r0, r5, 0x4
- bl sub_8002718
- lsls r0, 24
- cmp r0, 0
- bne _08011E94
- movs r7, 0x4
- b _08011F6E
- .align 2, 0
-_08011E80: .4byte 0x0000041c
-_08011E84: .4byte gUnknown_203B184
-_08011E88:
- ldr r0, [r0, 0x4C]
- adds r1, r5, 0x4
- movs r2, 0x80
- lsls r2, 3
- bl MemoryCopy8
-_08011E94:
- cmp r7, 0
- bne _08011F6E
- ldr r6, _08011F80
- adds r0, r4, 0
- adds r1, r6, 0
- bl sub_808EE9C
- adds r1, r0, 0
- ldr r2, _08011F84
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011EB0
- movs r7, 0x3
-_08011EB0:
- adds r4, r6
- movs r6, 0x96
- lsls r6, 2
- adds r0, r4, 0
- adds r1, r6, 0
- bl sub_808F2B0
- adds r1, r0, 0
- movs r2, 0x85
- lsls r2, 3
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011ECE
- movs r7, 0x3
-_08011ECE:
- adds r4, r6
- movs r6, 0xEC
- lsls r6, 1
- adds r0, r4, 0
- adds r1, r6, 0
- bl sub_8091D14
- adds r1, r0, 0
- movs r2, 0x86
- lsls r2, 3
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011EEC
- movs r7, 0x3
-_08011EEC:
- adds r4, r6
- adds r0, r4, 0
- movs r1, 0x10
- bl sub_809222C
- adds r1, r0, 0
- ldr r2, _08011F88
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011F04
- movs r7, 0x3
-_08011F04:
- adds r4, 0x10
- adds r0, r4, 0
- movs r1, 0x8
- bl sub_80927F4
- adds r1, r0, 0
- movs r2, 0x87
- lsls r2, 3
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011F1E
- movs r7, 0x3
-_08011F1E:
- adds r4, 0x8
- movs r6, 0x80
- lsls r6, 1
- adds r0, r4, 0
- adds r1, r6, 0
- bl sub_8097D98
- adds r1, r0, 0
- ldr r2, _08011F8C
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011F3A
- movs r7, 0x3
-_08011F3A:
- adds r4, r6
- ldr r6, _08011F90
- adds r0, r4, 0
- adds r1, r6, 0
- bl sub_80954CC
- adds r1, r0, 0
- movs r2, 0x88
- lsls r2, 3
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011F56
- movs r7, 0x3
-_08011F56:
- adds r4, r6
- ldr r1, _08011F94
- adds r0, r4, 0
- bl sub_8096FA0
- adds r1, r0, 0
- ldr r2, _08011F98
- adds r0, r5, r2
- ldr r0, [r0]
- cmp r1, r0
- beq _08011F6E
- movs r7, 0x3
-_08011F6E:
- adds r0, r5, 0
- bl MemoryFree
- adds r0, r7, 0
- pop {r3}
- mov r8, r3
- pop {r4-r7}
- pop {r1}
- bx r1
- .align 2, 0
-_08011F80: .4byte 0x00004650
-_08011F84: .4byte 0x00000424
-_08011F88: .4byte 0x00000434
-_08011F8C: .4byte 0x0000043c
-_08011F90: .4byte 0x00000594
-_08011F94: .4byte 0x00000221
-_08011F98: .4byte 0x00000444
- thumb_func_end sub_8011DAC
-
thumb_func_start sub_8011F9C
sub_8011F9C:
push {lr}
diff --git a/asmdiff.sh b/asmdiff.sh
index a4afe79..7c20855 100644
--- a/asmdiff.sh
+++ b/asmdiff.sh
@@ -4,4 +4,4 @@ OBJDUMP="$DEVKITARM/bin/arm-none-eabi-objdump -D -bbinary -marmv4t -Mforce-thumb
OPTIONS="--start-address=$(($1)) --stop-address=$(($1 + $2))"
$OBJDUMP $OPTIONS baserom.gba > baserom.dump
$OBJDUMP $OPTIONS pmd_red.gba > pmd_red.dump
-diff -u baserom.dump pmd_red.dump | less \ No newline at end of file
+diff -u baserom.dump pmd_red.dump
diff --git a/include/config.h b/include/config.h
new file mode 100644
index 0000000..563cd91
--- /dev/null
+++ b/include/config.h
@@ -0,0 +1,21 @@
+#ifndef GUARD_CONFIG_H
+#define GUARD_CONFIG_H
+
+// In the Generation 3 games, Asserts were used in various debug builds.
+// Ruby/Sapphire and Emerald do not have these asserts while Fire Red
+// still has them in the ROM. This is because the developers forgot
+// to define NDEBUG before release, however this has been changed as
+// Ruby's actual debug build does not use the AGBPrint features.
+#define NDEBUG
+
+// To enable print debugging, comment out "#define NDEBUG". This allows
+// the various AGBPrint functions to be used. (See include/gba/isagbprint.h).
+// Some emulators support a debug console window: uncomment NoCashGBAPrint()
+// and NoCashGBAPrintf() in libisagbprn.c to use no$gba's own proprietary
+// printing system. Use NoCashGBAPrint() and NoCashGBAPrintf() like you
+// would normally use AGBPrint() and AGBPrintf().
+
+// NOTE: Don't try to enable assert right now as many pointers
+// still exist in defines and WILL likely result in a broken ROM.
+
+#endif // GUARD_CONFIG_H
diff --git a/include/gba/gba.h b/include/gba/gba.h
index 42ae3cd..3493440 100644
--- a/include/gba/gba.h
+++ b/include/gba/gba.h
@@ -7,5 +7,6 @@
#include "gba/multiboot.h"
#include "gba/syscall.h"
#include "gba/macro.h"
+#include "gba/isagbprint.h"
#endif // GUARD_GBA_GBA_H
diff --git a/include/gba/isagbprint.h b/include/gba/isagbprint.h
new file mode 100644
index 0000000..1be3852
--- /dev/null
+++ b/include/gba/isagbprint.h
@@ -0,0 +1,50 @@
+#ifndef GUARD_GBA_ISAGBPRINT_H
+#define GUARD_GBA_ISAGBPRINT_H
+
+#ifdef NDEBUG
+#define AGBPrintInit()
+#define AGBPutc(cChr)
+#define AGBPrint(pBuf)
+#define AGBPrintf(pBuf, ...)
+#define AGBPrintFlush1Block()
+#define AGBPrintFlush()
+#define AGBAssert(pFile, nLine, pExpression, nStopProgram)
+#else
+void AGBPrintInit(void);
+void AGBPutc(const char cChr);
+void AGBPrint(const char *pBuf);
+void AGBPrintf(const char *pBuf, ...);
+void AGBPrintFlush1Block(void);
+void AGBPrintFlush(void);
+void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram);
+#endif
+
+#undef AGB_ASSERT
+#ifdef NDEBUG
+#define AGB_ASSERT(exp)
+#else
+#define AGB_ASSERT(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 1);
+#endif
+
+#undef AGB_WARNING
+#ifdef NDEBUG
+#define AGB_WARNING(exp)
+#else
+#define AGB_WARNING(exp) (exp) ? ((void*)0) : AGBAssert(__FILE__, __LINE__, #exp, 0);
+#endif
+
+// for matching purposes
+
+#ifdef NDEBUG
+#define AGB_ASSERT_EX(exp, file, line)
+#else
+#define AGB_ASSERT_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 1);
+#endif
+
+#ifdef NDEBUG
+#define AGB_WARNING_EX(exp, file, line)
+#else
+#define AGB_WARNING_EX(exp, file, line) (exp) ? ((void*)0) : AGBAssert(file, line, #exp, 0);
+#endif
+
+#endif // GUARD_GBA_ISAGBPRINT_H
diff --git a/include/global.h b/include/global.h
index b5a4593..b991d34 100644
--- a/include/global.h
+++ b/include/global.h
@@ -2,6 +2,7 @@
#define GUARD_GLOBAL_H
#include <string.h>
+#include "config.h" // We need to define config before gba headers as print stuff needs the functions nulled before defines.
#include "gba/gba.h"
// IDE support
diff --git a/src/libisagbprn.c b/src/libisagbprn.c
new file mode 100644
index 0000000..e0e979e
--- /dev/null
+++ b/src/libisagbprn.c
@@ -0,0 +1,177 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include "gba/gba.h"
+#include "config.h"
+
+#define AGB_PRINT_FLUSH_ADDR 0x9FE209D
+#define AGB_PRINT_STRUCT_ADDR 0x9FE20F8
+#define AGB_PRINT_PROTECT_ADDR 0x9FE2FFE
+#define WSCNT_DATA (WAITCNT_PHI_OUT_16MHZ | WAITCNT_WS0_S_2 | WAITCNT_WS0_N_4)
+
+// originally for auto no$gba support, the string "no$gba" should be at this address,
+// the user needs to read this string out as the memory viewer won't show it.
+#define NOCASHGBAIDADDR 0x4FFFA00
+#define NOCASHGBAPRINTADDR1 0x4FFFA10 // automatically adds a newline after the string has finished
+#define NOCASHGBAPRINTADDR2 0x4FFFA14 // does not automatically add the newline. by default, NOCASHGBAPRINTADDR2 is used. this is used to keep strings consistent between no$gba and VBA-RR, but a user can choose to forgo this.
+
+struct AGBPrintStruct
+{
+ u16 m_nRequest;
+ u16 m_nBank;
+ u16 m_nGet;
+ u16 m_nPut;
+};
+
+typedef void (*LPFN_PRINT_FLUSH)(void);
+
+#ifndef NDEBUG
+
+void AGBPrintFlush1Block(void);
+
+void AGBPrintInit(void)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ u16 nOldWSCNT = *pWSCNT;
+ *pWSCNT = WSCNT_DATA;
+ *pProtect = 0x20;
+ pPrint->m_nRequest = pPrint->m_nGet = pPrint->m_nPut = 0;
+ pPrint->m_nBank = 0xFD;
+ *pProtect = 0;
+ *pWSCNT = nOldWSCNT;
+}
+
+static void AGBPutcInternal(const char cChr)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pPrintBuf = (u16 *)(0x8000000 + (pPrint->m_nBank << 16));
+ u16 *pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ u16 nData = pPrintBuf[pPrint->m_nPut / 2];
+ *pProtect = 0x20;
+ nData = (pPrint->m_nPut & 1) ? (nData & 0xFF) | (cChr << 8) : (nData & 0xFF00) | cChr;
+ pPrintBuf[pPrint->m_nPut / 2] = nData;
+ pPrint->m_nPut++;
+ *pProtect = 0;
+}
+
+void AGBPutc(const char cChr)
+{
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 nOldWSCNT = *pWSCNT;
+ volatile struct AGBPrintStruct *pPrint;
+ *pWSCNT = WSCNT_DATA;
+ AGBPutcInternal(cChr);
+ *pWSCNT = nOldWSCNT;
+ pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ if (pPrint->m_nPut == ((pPrint->m_nGet - 1) & 0xFFFF))
+ AGBPrintFlush1Block();
+}
+
+void AGBPrint(const char *pBuf)
+{
+ volatile struct AGBPrintStruct *pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ u16 *pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ u16 nOldWSCNT = *pWSCNT;
+ *pWSCNT = WSCNT_DATA;
+ while (*pBuf)
+ {
+ AGBPutc(*pBuf);
+ pBuf++;
+ }
+ *pWSCNT = nOldWSCNT;
+}
+
+void AGBPrintf(const char *pBuf, ...)
+{
+ char bufPrint[0x100];
+ va_list vArgv;
+ va_start(vArgv, pBuf);
+ vsprintf(bufPrint, pBuf, vArgv);
+ va_end(vArgv);
+ AGBPrint(bufPrint);
+}
+
+static void AGBPrintTransferDataInternal(u32 bAllData)
+{
+ LPFN_PRINT_FLUSH lpfnFuncFlush;
+ u16 *pIME;
+ u16 nIME;
+ u16 *pWSCNT;
+ u16 nOldWSCNT;
+ u16 *pProtect;
+ volatile struct AGBPrintStruct *pPrint;
+
+ pProtect = (u16 *)AGB_PRINT_PROTECT_ADDR;
+ pPrint = (struct AGBPrintStruct *)AGB_PRINT_STRUCT_ADDR;
+ lpfnFuncFlush = (LPFN_PRINT_FLUSH)AGB_PRINT_FLUSH_ADDR;
+ pIME = (u16 *)REG_ADDR_IME;
+ nIME = *pIME;
+ pWSCNT = (u16 *)REG_ADDR_WAITCNT;
+ nOldWSCNT = *pWSCNT;
+ *pIME = nIME & ~1;
+ *pWSCNT = WSCNT_DATA;
+
+ if (bAllData)
+ {
+ while (pPrint->m_nPut != pPrint->m_nGet)
+ {
+ *pProtect = 0x20;
+ lpfnFuncFlush();
+ *pProtect = 0;
+ }
+ }
+ else if (pPrint->m_nPut != pPrint->m_nGet)
+ {
+ *pProtect = 0x20;
+ lpfnFuncFlush();
+ *pProtect = 0;
+ }
+
+ *pWSCNT = nOldWSCNT;
+ *pIME = nIME;
+}
+
+void AGBPrintFlush1Block(void)
+{
+ AGBPrintTransferDataInternal(FALSE);
+}
+
+void AGBPrintFlush(void)
+{
+ AGBPrintTransferDataInternal(TRUE);
+}
+
+void AGBAssert(const char *pFile, int nLine, const char *pExpression, int nStopProgram)
+{
+ if (nStopProgram)
+ {
+ AGBPrintf("ASSERTION FAILED FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
+ AGBPrintFlush();
+ asm(".hword 0xEFFF");
+ }
+ else
+ {
+ AGBPrintf("WARING FILE=[%s] LINE=[%d] EXP=[%s] \n", pFile, nLine, pExpression);
+ }
+}
+
+// no$gba print functions, uncomment to use
+/*
+void NoCashGBAPrint(const char *pBuf)
+{
+ *(volatile u32*)NOCASHGBAPRINTADDR2 = (u32)pBuf;
+}
+
+void NoCashGBAPrintf(const char *pBuf, ...)
+{
+ char bufPrint[0x100];
+ va_list vArgv;
+ va_start(vArgv, pBuf);
+ vsprintf(bufPrint, pBuf, vArgv);
+ va_end(vArgv);
+ NoCashGBAPrint(bufPrint);
+}
+*/
+
+#endif
diff --git a/src/save.c b/src/save.c
index 5d39bfe..6478c12 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1,10 +1,55 @@
#include "global.h"
+#include "flash.h"
+#include "memory.h"
+struct UnkStruct_203B184 {
+ u8 fill000[0x4C];
+ u8 *unk04C;
+ u32 unk050;
+ u32 unk054;
+ u32 unk058;
+};
+
+struct UnkStruct_sub_8011DAC {
+ u8 fill000[0x4];
+ u8 unk004[0x400];
+ u8 fill404[0x10];
+ u32 unk414;
+ u32 unk418;
+ u32 unk41C;
+ u32 unk420;
+ u32 unk424;
+ u32 unk428;
+ u8 fill42C[0x4];
+ u32 unk430;
+ u32 unk434;
+ u32 unk438;
+ u32 unk43C;
+ u32 unk440;
+ u32 unk444;
+ u8 fill448[0x538C];
+};
+
+extern u32 gUnknown_202DE28;
extern u32 gUnknown_203B17C;
extern u32 gUnknown_203B180;
-extern u32 *gUnknown_203B184;
-extern u32 gUnknown_202DE28;
+extern volatile struct UnkStruct_203B184 *gUnknown_203B184;
+extern void* MemoryAlloc(u32 a, u32 b);
+extern void MemoryFree(void* a);
+extern void SetRngState(s32 state);
+extern bool8 sub_8002718(u8 *a);
+extern bool8 sub_800DAB0(u16, u8*, s32);
+extern bool8 sub_800DAB4(u16, u8*, s32);
+extern bool8 sub_800DAB8(void);
+extern u32 sub_808EE9C(void* a, s32 b);
+extern u32 sub_808F2B0(void* a, s32 b);
+extern u32 sub_8091D14(void* a, s32 b);
+extern u32 sub_809222C(void* a, s32 b);
+extern u32 sub_80927F4(void* a, s32 b);
+extern u32 sub_80954CC(void* a, s32 b);
+extern u32 sub_8096FA0(void* a, s32 b);
+extern u32 sub_8097D98(void* a, s32 b);
u32 sub_8011C1C(void)
{
@@ -62,3 +107,165 @@ bool8 ValidateChecksum(u8 *in, u32 size)
return TRUE;
return FALSE;
}
+
+void sub_8011CA8(u32 *out, s32 size)
+{
+ if (gUnknown_203B184 == NULL) {
+ AGB_WARNING("A warning most likely went here.");
+ *out += (size + 0xFFF) / 0x1000;
+ } else {
+ *out += (size + 0xFFF) / 0x1000;
+ }
+}
+
+u32 WriteSaveSector(s32 *a, u8 *src, s32 size)
+{
+ u32 r1;
+ s32 r6 = *a;
+ sub_8011CA8(a, size);
+ CalculateChecksum(src, size);
+ if (gUnknown_203B184 == NULL) {
+ r1 = WriteFlashData(r6, src, size);
+ }
+ else if (sub_800DAB8()) {
+ if (!sub_800DAB4(r6, src, size)) {
+ r1 = 3;
+ }
+ else {
+ r1 = 0;
+ }
+ }
+ else {
+ return 2;
+ }
+ if (r1 == 4) {
+ return 1;
+ }
+ if (r1) {
+ return 2;
+ }
+ return 0;
+}
+
+u32 ReadSaveSector(s32 *a, u8 *dest, s32 size)
+{
+ u32 r1;
+ s32 r6 = *a;
+ sub_8011CA8(a, size);
+ if (gUnknown_203B184 == NULL) {
+ r1 = ReadFlashData(r6, dest, size);
+ }
+ else if (sub_800DAB8()) {
+ if (!sub_800DAB0(r6, dest, size)) {
+ r1 = 1;
+ }
+ else {
+ r1 = 0;
+ }
+ }
+ else {
+ return 1;
+ }
+ if (r1) {
+ return 1;
+ }
+ if (ValidateChecksum(dest, size)) {
+ return 2;
+ }
+ return 0;
+}
+
+bool8 sub_8011DA8(void)
+{
+ return TRUE;
+}
+
+u32 sub_8011DAC(u32 *a)
+{
+ struct UnkStruct_sub_8011DAC *r5 = MemoryAlloc(sizeof(struct UnkStruct_sub_8011DAC), 5);
+ u8 *r4 = (u8*)r5->fill448;
+ u32 r7 = ReadSaveSector(a, (u8*)r5, sizeof(struct UnkStruct_sub_8011DAC));
+ u32 r1;
+ if (r7)
+ {
+ r7 = ReadSaveSector(a, (u8*)r5, sizeof(struct UnkStruct_sub_8011DAC));
+ }
+ else
+ {
+ sub_8011CA8(a, sizeof(struct UnkStruct_sub_8011DAC));
+ }
+ if (!r7)
+ {
+ if (r5->unk414 != 0x5071412) {
+ r7 = 4;
+ }
+ }
+ if (!r7)
+ {
+ if (gUnknown_203B184 == NULL) {
+ sub_8011C28(r5->unk41C);
+ sub_8011C40(r5->unk418);
+ SetRngState(r5->unk420);
+ }
+ else {
+ gUnknown_203B184->unk054 = r5->unk41C;
+ gUnknown_203B184->unk050 = r5->unk418;
+ gUnknown_203B184->unk058 = r5->unk420;
+ }
+ }
+ if (!r7)
+ {
+ if (gUnknown_203B184 == NULL) {
+ if (!sub_8002718(r5->unk004)) {
+ r7 = 4;
+ }
+ }
+ else {
+ MemoryCopy8(gUnknown_203B184->unk04C, r5->unk004, ARRAY_COUNT(r5->unk004));
+ }
+ }
+ if (!r7)
+ {
+ r1 = sub_808EE9C(r4, 0x4650);
+ if (r1 != r5->unk424) {
+ r7 = 3;
+ }
+ r4 += 0x4650;
+ r1 = sub_808F2B0(r4, 0x258);
+ if (r1 != r5->unk428) {
+ r7 = 3;
+ }
+ r4 += 0x258;
+ r1 = sub_8091D14(r4, 0x1D8);
+ if (r1 != r5->unk430) {
+ r7 = 3;
+ }
+ r4 += 0x1d8;
+ r1 = sub_809222C(r4, 0x10);
+ if (r1 != r5->unk434) {
+ r7 = 3;
+ }
+ r4 += 0x10;
+ r1 = sub_80927F4(r4, 0x8);
+ if (r1 != r5->unk438) {
+ r7 = 3;
+ }
+ r4 += 0x8;
+ r1 = sub_8097D98(r4, 0x100);
+ if (r1 != r5->unk43C) {
+ r7 = 3;
+ }
+ r4 += 0x100;
+ r1 = sub_80954CC(r4, 0x594);
+ if (r1 != r5->unk440) {
+ r7 = 3;
+ }
+ r4 += 0x594;
+ r1 = sub_8096FA0(r4, 0x221);
+ if (r1 != r5->unk444) {
+ r7 = 3;
+ }
+ }
+ MemoryFree(r5);
+ return r7;
+}