From c7188a70d8b0f1b7a8309d3af4d63719255eafb6 Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Sat, 10 Aug 2019 22:06:31 -0400 Subject: save.c - sub_8011CA8() to ReadSaveSector() --- src/save.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/save.c b/src/save.c index 5d39bfe..037938a 100644 --- a/src/save.c +++ b/src/save.c @@ -2,9 +2,14 @@ extern u32 gUnknown_203B17C; extern u32 gUnknown_203B180; -extern u32 *gUnknown_203B184; +extern vu32 gUnknown_203B184; extern u32 gUnknown_202DE28; +extern s32 ReadFlashData(s32 sector, u8 *src, s32 size); +extern s32 WriteFlashData(s32 sector, u8 *src, s32 size); +extern bool8 sub_800DAB0(u16, u8*, s32); +extern bool8 sub_800DAB4(u16, u8*, s32); +extern bool8 sub_800DAB8(void); u32 sub_8011C1C(void) { @@ -62,3 +67,63 @@ bool8 ValidateChecksum(u8 *in, u32 size) return TRUE; return FALSE; } + +void sub_8011CA8(u32 *out, s32 b) +{ + gUnknown_203B184; // Needed to match + *out += (b + 0xFFF) / 0x1000; +} + +u32 WriteSaveSector(u32 *a, u8 *b, s32 size, u32 d) +{ + u32 r6 = *a; + u32 num; + sub_8011CA8(a, size); + CalculateChecksum(b, size); + if (!gUnknown_203B184) { + num = WriteFlashData(r6, b, size); + } + else if (sub_800DAB8()) { + num = sub_800DAB4(r6, b, size) ? 0 : 3; + } + else { + return 2; + } + if (num == 4) { + return 1; + } + else if (num) { + return 2; + } + else { + return 0; + } +} + +u32 ReadSaveSector(u32 *a, u8 *b, s32 size, u32 d) +{ + u32 r6 = *a; + u32 num; + sub_8011CA8(a, size); + if (!gUnknown_203B184) { + num = ReadFlashData(r6, b, size); + } + else if (sub_800DAB8()) { + if (!sub_800DAB0(r6, b, size)) { + num = 1; + } + else { + num = 0; + } + } + else { + return 1; + } + if (num) { + return 1; + } + if (ValidateChecksum(b, size)) { + return 2; + } + return 0; +} -- cgit v1.2.3 From b99e74849dfb574b0be222a56726c57d07125937 Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Mon, 12 Aug 2019 16:21:57 -0400 Subject: save.c - sub_8011DA8() and sub_8011DAC() --- src/save.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 169 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/save.c b/src/save.c index 037938a..f8da6ce 100644 --- a/src/save.c +++ b/src/save.c @@ -1,15 +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 vu32 gUnknown_203B184; -extern u32 gUnknown_202DE28; +extern volatile struct UnkStruct_203B184 *gUnknown_203B184; -extern s32 ReadFlashData(s32 sector, u8 *src, s32 size); -extern s32 WriteFlashData(s32 sector, u8 *src, s32 size); +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) { @@ -68,62 +108,164 @@ bool8 ValidateChecksum(u8 *in, u32 size) return FALSE; } -void sub_8011CA8(u32 *out, s32 b) +void sub_8011CA8(u32 *out, s32 size) { - gUnknown_203B184; // Needed to match - *out += (b + 0xFFF) / 0x1000; + // Needed to match + if (gUnknown_203B184) { + size++; + size--; + } + *out += (size + 0xFFF) / 0x1000; } -u32 WriteSaveSector(u32 *a, u8 *b, s32 size, u32 d) +u32 WriteSaveSector(s32 *a, u8 *src, s32 size) { - u32 r6 = *a; - u32 num; + u32 r1; + s32 r6 = *a; sub_8011CA8(a, size); - CalculateChecksum(b, size); + CalculateChecksum(src, size); if (!gUnknown_203B184) { - num = WriteFlashData(r6, b, size); + r1 = WriteFlashData(r6, src, size); } else if (sub_800DAB8()) { - num = sub_800DAB4(r6, b, size) ? 0 : 3; + if (!sub_800DAB4(r6, src, size)) { + r1 = 3; + } + else { + r1 = 0; + } } else { return 2; } - if (num == 4) { + if (r1 == 4) { return 1; } - else if (num) { + if (r1) { return 2; } - else { - return 0; - } + return 0; } -u32 ReadSaveSector(u32 *a, u8 *b, s32 size, u32 d) +u32 ReadSaveSector(s32 *a, u8 *dest, s32 size) { - u32 r6 = *a; - u32 num; + u32 r1; + s32 r6 = *a; sub_8011CA8(a, size); if (!gUnknown_203B184) { - num = ReadFlashData(r6, b, size); + r1 = ReadFlashData(r6, dest, size); } else if (sub_800DAB8()) { - if (!sub_800DAB0(r6, b, size)) { - num = 1; + if (!sub_800DAB0(r6, dest, size)) { + r1 = 1; } else { - num = 0; + r1 = 0; } } else { return 1; } - if (num) { + if (r1) { return 1; } - if (ValidateChecksum(b, size)) { + 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) { + 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) { + 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; +} -- cgit v1.2.3 From fbd4bbc146d4ed35e2d016b5845408a1f3e2d99a Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Tue, 13 Aug 2019 13:00:33 -0400 Subject: Add libisagbprn --- src/libisagbprn.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/save.c | 18 +++--- 2 files changed, 186 insertions(+), 9 deletions(-) create mode 100644 src/libisagbprn.c (limited to 'src') 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 +#include +#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 f8da6ce..6478c12 100644 --- a/src/save.c +++ b/src/save.c @@ -110,12 +110,12 @@ bool8 ValidateChecksum(u8 *in, u32 size) void sub_8011CA8(u32 *out, s32 size) { - // Needed to match - if (gUnknown_203B184) { - size++; - size--; + if (gUnknown_203B184 == NULL) { + AGB_WARNING("A warning most likely went here."); + *out += (size + 0xFFF) / 0x1000; + } else { + *out += (size + 0xFFF) / 0x1000; } - *out += (size + 0xFFF) / 0x1000; } u32 WriteSaveSector(s32 *a, u8 *src, s32 size) @@ -124,7 +124,7 @@ u32 WriteSaveSector(s32 *a, u8 *src, s32 size) s32 r6 = *a; sub_8011CA8(a, size); CalculateChecksum(src, size); - if (!gUnknown_203B184) { + if (gUnknown_203B184 == NULL) { r1 = WriteFlashData(r6, src, size); } else if (sub_800DAB8()) { @@ -152,7 +152,7 @@ u32 ReadSaveSector(s32 *a, u8 *dest, s32 size) u32 r1; s32 r6 = *a; sub_8011CA8(a, size); - if (!gUnknown_203B184) { + if (gUnknown_203B184 == NULL) { r1 = ReadFlashData(r6, dest, size); } else if (sub_800DAB8()) { @@ -202,7 +202,7 @@ u32 sub_8011DAC(u32 *a) } if (!r7) { - if (!gUnknown_203B184) { + if (gUnknown_203B184 == NULL) { sub_8011C28(r5->unk41C); sub_8011C40(r5->unk418); SetRngState(r5->unk420); @@ -215,7 +215,7 @@ u32 sub_8011DAC(u32 *a) } if (!r7) { - if (!gUnknown_203B184) { + if (gUnknown_203B184 == NULL) { if (!sub_8002718(r5->unk004)) { r7 = 4; } -- cgit v1.2.3