Merge pull request #7 from Kermalis/master

Some save.c functions + add libisagbprn
This commit is contained in:
PikalaxALT
2019-08-14 11:14:16 -04:00
committed by GitHub
8 changed files with 460 additions and 386 deletions

View File

@@ -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}

View File

@@ -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
diff -u baserom.dump pmd_red.dump

21
include/config.h Normal file
View File

@@ -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

View File

@@ -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

50
include/gba/isagbprint.h Normal file
View File

@@ -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

View File

@@ -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

177
src/libisagbprn.c Normal file
View File

@@ -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

View File

@@ -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;
}