summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/arm9.lsf1
-rw-r--r--arm9/asm/save.s2478
-rw-r--r--arm9/lib/include/CARD_backup.h34
-rw-r--r--arm9/lib/include/CARD_common.h45
-rw-r--r--arm9/lib/include/MATH_crc.h7
-rw-r--r--arm9/lib/include/MI_memory.h4
-rw-r--r--arm9/src/main.c5
-rw-r--r--arm9/src/save.c918
-rw-r--r--arm9/src/save_arrays.c120
-rw-r--r--include/player_data.h2
-rw-r--r--include/save_block_2.h128
11 files changed, 1249 insertions, 2493 deletions
diff --git a/arm9/arm9.lsf b/arm9/arm9.lsf
index a90100e4..41b1dce3 100644
--- a/arm9/arm9.lsf
+++ b/arm9/arm9.lsf
@@ -83,6 +83,7 @@ Static arm9
Object unk_02022450.o
Object unk_02022504.o
Object save.o
+ Object save_arrays.o
Object unk_0202376C.o
Object player_data.o
Object unk_02023AC4.o
diff --git a/arm9/asm/save.s b/arm9/asm/save.s
deleted file mode 100644
index a29733dc..00000000
--- a/arm9/asm/save.s
+++ /dev/null
@@ -1,2478 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .section .rodata
-
- .global UNK_020EE6D8
-UNK_020EE6D8: ; 0x020EE6D8
- .word 2
-
- .global UNK_020EE6DC
-UNK_020EE6DC: ; 0x020EE6DC
- .word 36
-
- .global UNK_020EE6E0
-UNK_020EE6E0: ; 0x020EE6E0
- .word 0x00, 0x20, FUN_0202B034, FUN_0202B03C
- .word 0x01, 0x23, FUN_0202AC20, FUN_0202AC28
-
- .global UNK_020EE700
-UNK_020EE700: ; 0x020EE700
- .word 0x00, 0x00, FUN_0202376C, FUN_02023770
- .word 0x01, 0x00, Sav2_PlayerData_sizeof, Sav2_PlayerData_init
- .word 0x02, 0x00, SavArray_Party_sizeof, SavArray_Party_init
- .word 0x03, 0x00, Sav2_Bag_sizeof, Sav2_Bag_init
- .word 0x04, 0x00, SavArray_Flags_sizeof, SavArray_Flags_init
- .word 0x05, 0x00, FUN_0204BE14, FUN_0204BE18
- .word 0x06, 0x00, FUN_02034D7C, FUN_02034D98
- .word 0x07, 0x00, FUN_02023D64, FUN_02024378
- .word 0x08, 0x00, FUN_02023C40, FUN_02023C48
- .word 0x09, 0x00, FUN_020254B8, FUN_020254CC
- .word 0x0A, 0x00, FUN_02024E64, FUN_02024E6C
- .word 0x0B, 0x00, FUN_02034D80, FUN_02034D88
- .word 0x0C, 0x00, FUN_02025954, FUN_0202597C
- .word 0x0D, 0x00, FUN_02023AC8, FUN_02023AD8
- .word 0x0E, 0x00, FUN_02026FD8, FUN_02026F60
- .word 0x0F, 0x00, FUN_02025844, FUN_0202584C
- .word 0x10, 0x00, FUN_02028054, FUN_0202805C
- .word 0x11, 0x00, FUN_020286F8, FUN_02028724
- .word 0x12, 0x00, FUN_02028980, FUN_02028994
- .word 0x13, 0x00, FUN_02029A84, FUN_02029A8C
- .word 0x14, 0x00, FUN_02029FB0, FUN_02029FB8
- .word 0x15, 0x00, FUN_02029C58, FUN_02029C60
- .word 0x16, 0x00, FUN_02029EC4, FUN_02029ECC
- .word 0x17, 0x00, FUN_0202A89C, FUN_0202A8A4
- .word 0x18, 0x00, FUN_0202A8F4, FUN_0202A8F8
- .word 0x19, 0x00, FUN_0202A924, FUN_0202A92C
- .word 0x1A, 0x00, FUN_0202ABC8, FUN_0202ABCC
- .word 0x1B, 0x00, FUN_0202B374, FUN_0202B37C
- .word 0x1C, 0x00, FUN_0202B8B0, FUN_0202B8B8
- .word 0x1D, 0x00, FUN_020281E0, FUN_020281E8
- .word 0x1E, 0x00, FUN_02029AE0, FUN_02029AE8
- .word 0x1F, 0x00, FUN_0202AC20, FUN_0202AC28
- .word 0x20, 0x00, FUN_0202BE98, FUN_0202BEA0
- .word 0x21, 0x00, FUN_0202C0E0, FUN_0202C0E4
- .word 0x22, 0x00, FUN_02013B28, FUN_02013B2C
- .word 0x23, 0x01, PCStorage_sizeof, PCStorage_init
-
- .section .bss
-
- .global UNK_021C59C8
-UNK_021C59C8: ; 0x021C59C8
- .space 0x8
-
- .text
-
- thumb_func_start SaveBlock2_new
-SaveBlock2_new: ; 0x0202254C
- push {r4, lr}
- ldr r1, _020225E0 ; =0x000204A8
- mov r0, #0x1
- bl AllocFromHeap
- add r4, r0, #0x0
- ldr r2, _020225E0 ; =0x000204A8
- mov r0, #0x0
- add r1, r4, #0x0
- bl MIi_CpuClearFast
- ldr r0, _020225E4 ; =UNK_021C59C8
- str r4, [r0, #0x0]
- bl SaveDetectFlash
- str r0, [r4, #0x0]
- mov r0, #0x0
- str r0, [r4, #0x4]
- mov r0, #0x1
- str r0, [r4, #0x8]
- str r0, [r4, #0xc]
- add r0, r4, #0x0
- ldr r1, _020225E8 ; =0x00001021
- add r0, #0x14
- bl MATHi_CRC16InitTable
- ldr r0, _020225EC ; =0x00020224
- add r0, r4, r0
- bl SaveBlock2_InitSubstructs
- ldr r0, _020225F0 ; =0x00020464
- ldr r1, _020225EC ; =0x00020224
- add r0, r4, r0
- add r1, r4, r1
- bl FUN_02023160
- ldr r1, _020225F4 ; =0x00020218
- mov r0, #0x0
- add r1, r4, r1
- mov r2, #0x8
- bl MIi_CpuClearFast
- add r0, r4, #0x0
- bl FUN_02022AD8
- str r0, [r4, #0x10]
- cmp r0, #0x3
- bhi _020225DA
- add r0, r0, r0
- add r0, pc
- ldrh r0, [r0, #0x6]
- lsl r0, r0, #0x10
- asr r0, r0, #0x10
- add pc, r0
-_020225B8: ; jump table (using 16-bit offset)
- .short _020225D4 - _020225B8 - 2; case 0
- .short _020225C0 - _020225B8 - 2; case 1
- .short _020225C4 - _020225B8 - 2; case 2
- .short _020225D4 - _020225B8 - 2; case 3
-_020225C0:
- mov r0, #0x0
- str r0, [r4, #0xc]
-_020225C4:
- add r0, r4, #0x0
- bl FUN_02022D08
- mov r0, #0x1
- str r0, [r4, #0x4]
- mov r0, #0x0
- str r0, [r4, #0x8]
- b _020225DA
-_020225D4:
- add r0, r4, #0x0
- bl Sav2_InitDynamicRegion
-_020225DA:
- add r0, r4, #0x0
- pop {r4, pc}
- nop
-_020225E0: .word 0x000204A8
-_020225E4: .word UNK_021C59C8
-_020225E8: .word 0x00001021
-_020225EC: .word 0x00020224
-_020225F0: .word 0x00020464
-_020225F4: .word 0x00020218
-
- thumb_func_start FUN_020225F8
-FUN_020225F8: ; 0x020225F8
- push {r3, lr}
- ldr r0, _0202260C ; =UNK_021C59C8
- ldr r0, [r0, #0x0]
- cmp r0, #0x0
- bne _02022606
- bl ErrorHandling
-_02022606:
- ldr r0, _0202260C ; =UNK_021C59C8
- ldr r0, [r0, #0x0]
- pop {r3, pc}
- .balign 4
-_0202260C: .word UNK_021C59C8
-
- thumb_func_start SavArray_get
-SavArray_get: ; 0x02022610
- push {r3-r5, lr}
- add r4, r1, #0x0
- add r5, r0, #0x0
- cmp r4, #0x24
- blt _0202261E
- bl ErrorHandling
-_0202261E:
- mov r0, #0x85
- lsl r0, r0, #0x2
- add r2, r5, r0
- lsl r0, r4, #0x4
- add r1, r5, r0
- ldr r0, _02022630 ; =0x0002022C
- ldr r0, [r1, r0]
- add r0, r2, r0
- pop {r3-r5, pc}
- .balign 4
-_02022630: .word 0x0002022C
-
- thumb_func_start FUN_02022634
-FUN_02022634: ; 0x02022634
- ldr r3, _02022638 ; =SavArray_get
- bx r3
- .balign 4
-_02022638: .word SavArray_get
-
- thumb_func_start FUN_0202263C
-FUN_0202263C: ; 0x0202263C
- push {r3-r7, lr}
- mov r1, #0x1
- str r0, [sp, #0x0]
- mov r0, #0x3
- lsl r1, r1, #0xc
- bl AllocFromHeapAtEnd
- add r6, r0, #0x0
- mov r0, #0x1
- bl FUN_02016444
- ldr r1, _020226F4 ; =0x00020220
- ldr r0, [sp, #0x0]
- ldrb r0, [r0, r1]
- cmp r0, #0x0
- bne _02022660
- mov r2, #0x1
- b _02022662
-_02022660:
- mov r2, #0x0
-_02022662:
- ldr r0, [sp, #0x0]
- mov r1, #0x0
- bl FlashClobberChunkFooter
- ldr r1, _020226F8 ; =0x00020221
- ldr r0, [sp, #0x0]
- ldrb r0, [r0, r1]
- cmp r0, #0x0
- bne _02022678
- mov r2, #0x1
- b _0202267A
-_02022678:
- mov r2, #0x0
-_0202267A:
- ldr r0, [sp, #0x0]
- mov r1, #0x1
- bl FlashClobberChunkFooter
- ldr r0, [sp, #0x0]
- ldr r3, _020226F4 ; =0x00020220
- add r2, r0, #0x0
- ldrb r2, [r2, r3]
- mov r1, #0x0
- bl FlashClobberChunkFooter
- ldr r0, [sp, #0x0]
- ldr r3, _020226F8 ; =0x00020221
- add r2, r0, #0x0
- ldrb r2, [r2, r3]
- mov r1, #0x1
- bl FlashClobberChunkFooter
- mov r0, #0x0
- mov r2, #0x1
- mvn r0, r0
- add r1, r6, #0x0
- lsl r2, r2, #0xc
- bl MIi_CpuClearFast
- mov r4, #0x0
- mov r7, #0x1
- add r5, r4, #0x0
- lsl r7, r7, #0xc
-_020226B4:
- add r0, r5, #0x0
- add r1, r6, #0x0
- add r2, r7, #0x0
- bl FlashWriteChunk
- add r0, r4, #0x0
- add r0, #0x40
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- add r2, r7, #0x0
- bl FlashWriteChunk
- mov r0, #0x1
- lsl r0, r0, #0xc
- add r4, r4, #0x1
- add r5, r5, r0
- cmp r4, #0x40
- blt _020226B4
- add r0, r6, #0x0
- bl FreeToHeap
- ldr r0, [sp, #0x0]
- bl Sav2_InitDynamicRegion
- ldr r0, [sp, #0x0]
- mov r1, #0x0
- str r1, [r0, #0x4]
- mov r0, #0x1
- bl FUN_02016454
- mov r0, #0x1
- pop {r3-r7, pc}
- .balign 4
-_020226F4: .word 0x00020220
-_020226F8: .word 0x00020221
-
- thumb_func_start FUN_020226FC
-FUN_020226FC: ; 0x020226FC
- push {r4, lr}
- add r4, r0, #0x0
- ldr r1, [r4, #0x0]
- cmp r1, #0x0
- bne _0202270A
- mov r0, #0x0
- pop {r4, pc}
-_0202270A:
- bl FUN_02022D08
- cmp r0, #0x0
- beq _0202271C
- mov r0, #0x1
- str r0, [r4, #0x4]
- mov r1, #0x0
- str r1, [r4, #0x8]
- pop {r4, pc}
-_0202271C:
- mov r0, #0x0
- pop {r4, pc}
-
- thumb_func_start FUN_02022720
-FUN_02022720: ; 0x02022720
- push {r4, lr}
- add r4, r0, #0x0
- ldr r0, [r4, #0x0]
- cmp r0, #0x0
- bne _0202272E
- mov r0, #0x3
- pop {r4, pc}
-_0202272E:
- ldr r0, [r4, #0x8]
- cmp r0, #0x0
- beq _02022784
- mov r0, #0x1
- bl FUN_02016444
- ldr r0, _02022798 ; =0x00020220
- ldrb r0, [r4, r0]
- cmp r0, #0x0
- bne _02022746
- mov r2, #0x1
- b _02022748
-_02022746:
- mov r2, #0x0
-_02022748:
- add r0, r4, #0x0
- mov r1, #0x0
- bl FlashClobberChunkFooter
- ldr r0, _0202279C ; =0x00020221
- ldrb r0, [r4, r0]
- cmp r0, #0x0
- bne _0202275C
- mov r2, #0x1
- b _0202275E
-_0202275C:
- mov r2, #0x0
-_0202275E:
- add r0, r4, #0x0
- mov r1, #0x1
- bl FlashClobberChunkFooter
- ldr r2, _02022798 ; =0x00020220
- add r0, r4, #0x0
- ldrb r2, [r4, r2]
- mov r1, #0x0
- bl FlashClobberChunkFooter
- ldr r2, _0202279C ; =0x00020221
- add r0, r4, #0x0
- ldrb r2, [r4, r2]
- mov r1, #0x1
- bl FlashClobberChunkFooter
- mov r0, #0x1
- bl FUN_02016454
-_02022784:
- add r0, r4, #0x0
- bl FUN_02023044
- cmp r0, #0x2
- bne _02022796
- mov r1, #0x1
- str r1, [r4, #0x4]
- mov r1, #0x0
- str r1, [r4, #0x8]
-_02022796:
- pop {r4, pc}
- .balign 4
-_02022798: .word 0x00020220
-_0202279C: .word 0x00020221
-
- thumb_func_start FUN_020227A0
-FUN_020227A0: ; 0x020227A0
- push {r3-r5, lr}
- add r4, r1, #0x0
- add r5, r0, #0x0
- cmp r4, #0x2
- blt _020227AE
- bl ErrorHandling
-_020227AE:
- ldr r0, [r5, #0x8]
- cmp r0, #0x0
- beq _020227B8
- bl ErrorHandling
-_020227B8:
- ldr r0, [r5, #0x4]
- cmp r0, #0x1
- beq _020227C2
- bl ErrorHandling
-_020227C2:
- add r0, r5, #0x0
- add r1, r4, #0x0
- bl FUN_02022840
-_020227CA:
- add r0, r5, #0x0
- bl FUN_02022854
- cmp r0, #0x0
- beq _020227CA
- cmp r0, #0x1
- beq _020227CA
- pop {r3-r5, pc}
- .balign 4
-
- thumb_func_start Sav2_InitDynamicRegion
-Sav2_InitDynamicRegion: ; 0x020227DC
- add r2, r0, #0x0
- mov r0, #0x1
- str r0, [r2, #0x8]
- str r0, [r2, #0xc]
- mov r0, #0x85
- ldr r1, _020227F4 ; =0x00020224
- lsl r0, r0, #0x2
- ldr r3, _020227F8 ; =Sav2_InitDynamicRegion_Internal
- add r0, r2, r0
- add r1, r2, r1
- bx r3
- nop
-_020227F4: .word 0x00020224
-_020227F8: .word Sav2_InitDynamicRegion_Internal
-
- thumb_func_start FUN_020227FC
-FUN_020227FC: ; 0x020227FC
- ldr r0, [r0, #0x0]
- bx lr
-
- thumb_func_start FUN_02022800
-FUN_02022800: ; 0x02022800
- ldr r0, [r0, #0x10]
- bx lr
-
- thumb_func_start FUN_02022804
-FUN_02022804: ; 0x02022804
- ldr r0, [r0, #0x4]
- bx lr
-
- thumb_func_start FUN_02022808
-FUN_02022808: ; 0x02022808
- ldr r0, [r0, #0x8]
- bx lr
-
- thumb_func_start FUN_0202280C
-FUN_0202280C: ; 0x0202280C
- push {r4, lr}
- add r4, r0, #0x0
- bl FUN_02022808
- cmp r0, #0x0
- beq _02022826
- add r0, r4, #0x0
- bl FUN_02022804
- cmp r0, #0x0
- beq _02022826
- mov r0, #0x1
- pop {r4, pc}
-_02022826:
- mov r0, #0x0
- pop {r4, pc}
- .balign 4
-
- thumb_func_start SaveGetDirtyBit
-SaveGetDirtyBit: ; 0x0202282C
- ldr r0, [r0, #0xc]
- bx lr
-
- thumb_func_start SaveSetDirtyBit
-SaveSetDirtyBit: ; 0x02022830
- ldr r0, _0202283C ; =UNK_021C59C8
- mov r1, #0x1
- ldr r0, [r0, #0x0]
- str r1, [r0, #0xc]
- bx lr
- nop
-_0202283C: .word UNK_021C59C8
-
- thumb_func_start FUN_02022840
-FUN_02022840: ; 0x02022840
- add r2, r1, #0x0
- ldr r1, _0202284C ; =0x0002047C
- ldr r3, _02022850 ; =FUN_02022DFC
- add r1, r0, r1
- bx r3
- nop
-_0202284C: .word 0x0002047C
-_02022850: .word FUN_02022DFC
-
- thumb_func_start FUN_02022854
-FUN_02022854: ; 0x02022854
- push {r3-r5, lr}
- ldr r1, _02022878 ; =0x0002047C
- add r5, r0, #0x0
- add r1, r5, r1
- bl FUN_02022E78
- add r4, r0, #0x0
- beq _02022874
- cmp r4, #0x1
- beq _02022874
- ldr r1, _02022878 ; =0x0002047C
- add r0, r5, #0x0
- add r1, r5, r1
- add r2, r4, #0x0
- bl FUN_02022F80
-_02022874:
- add r0, r4, #0x0
- pop {r3-r5, pc}
- .balign 4
-_02022878: .word 0x0002047C
-
- thumb_func_start FUN_0202287C
-FUN_0202287C: ; 0x0202287C
- ldr r1, _02022884 ; =0x0002047C
- ldr r3, _02022888 ; =FUN_02022FF0
- add r1, r0, r1
- bx r3
- .balign 4
-_02022884: .word 0x0002047C
-_02022888: .word FUN_02022FF0
-
- thumb_func_start FUN_0202288C
-FUN_0202288C: ; 0x0202288C
- mov r1, #0x0
- str r1, [r0, #0x0]
- str r1, [r0, #0x4]
- str r1, [r0, #0x8]
- bx lr
- .balign 4
-
- thumb_func_start FUN_02022898
-FUN_02022898: ; 0x02022898
- ldr r3, _020228A0 ; =MATH_CalcCRC16CCITT
- add r0, #0x14
- sub r2, #0x14
- bx r3
- .balign 4
-_020228A0: .word MATH_CalcCRC16CCITT
-
- thumb_func_start GetChunkOffsetFromCurrentSaveSlot
-GetChunkOffsetFromCurrentSaveSlot: ; 0x020228A4
- cmp r0, #0x0
- bne _020228AC
- mov r2, #0x0
- b _020228B0
-_020228AC:
- mov r2, #0x1
- lsl r2, r2, #0x12
-_020228B0:
- ldr r0, [r1, #0x4]
- add r0, r2, r0
- bx lr
- .balign 4
-
- thumb_func_start FUN_020228B8
-FUN_020228B8: ; 0x020228B8
- push {r3-r5, lr}
- ldr r3, _020228DC ; =0x00020464
- add r3, r0, r3
- mov r0, #0xc
- mul r0, r2
- add r5, r3, r0
- ldr r0, [r5, #0x4]
- add r4, r1, r0
- ldr r0, [r5, #0x8]
- cmp r0, #0x0
- bne _020228D2
- bl ErrorHandling
-_020228D2:
- ldr r0, [r5, #0x8]
- add r0, r4, r0
- sub r0, #0x14
- pop {r3-r5, pc}
- nop
-_020228DC: .word 0x00020464
-
- thumb_func_start FUN_020228E0
-FUN_020228E0: ; 0x020228E0
- push {r3-r7, lr}
- ldr r4, _02022934 ; =0x00020464
- add r3, r0, #0x0
- add r3, r3, r4
- add r5, r2, #0x0
- mov r4, #0xc
- mul r4, r5
- str r0, [sp, #0x0]
- add r7, r1, #0x0
- add r6, r3, r4
- bl FUN_020228B8
- add r4, r0, #0x0
- ldr r2, [r6, #0x8]
- ldr r0, [r4, #0x8]
- ldr r1, [r6, #0x4]
- cmp r0, r2
- beq _02022908
- mov r0, #0x0
- pop {r3-r7, pc}
-_02022908:
- ldr r3, [r4, #0xc]
- ldr r0, _02022938 ; =0x20060623
- cmp r3, r0
- beq _02022914
- mov r0, #0x0
- pop {r3-r7, pc}
-_02022914:
- ldrb r0, [r4, #0x10]
- cmp r0, r5
- beq _0202291E
- mov r0, #0x0
- pop {r3-r7, pc}
-_0202291E:
- ldr r0, [sp, #0x0]
- add r1, r7, r1
- bl FUN_02022898
- ldrh r1, [r4, #0x12]
- cmp r1, r0
- bne _02022930
- mov r0, #0x1
- pop {r3-r7, pc}
-_02022930:
- mov r0, #0x0
- pop {r3-r7, pc}
- .balign 4
-_02022934: .word 0x00020464
-_02022938: .word 0x20060623
-
- thumb_func_start FUN_0202293C
-FUN_0202293C: ; 0x0202293C
- push {r3-r7, lr}
- add r7, r2, #0x0
- add r6, r1, #0x0
- add r5, r0, #0x0
- str r3, [sp, #0x0]
- add r0, r6, #0x0
- add r1, r7, #0x0
- add r2, r3, #0x0
- bl FUN_020228B8
- add r4, r0, #0x0
- ldr r2, [sp, #0x0]
- add r0, r6, #0x0
- add r1, r7, #0x0
- bl FUN_020228E0
- str r0, [r5, #0x0]
- ldr r0, [r4, #0x0]
- str r0, [r5, #0x4]
- ldr r0, [r4, #0x4]
- str r0, [r5, #0x8]
- pop {r3-r7, pc}
-
- thumb_func_start FUN_02022968
-FUN_02022968: ; 0x02022968
- push {r3-r7, lr}
- ldr r3, _020229AC ; =0x00020464
- add r5, r0, #0x0
- add r7, r2, #0x0
- mov r4, #0xc
- add r3, r5, r3
- mul r4, r7
- str r1, [sp, #0x0]
- add r6, r3, r4
- bl FUN_020228B8
- ldr r2, _020229B0 ; =0x00020214
- add r4, r0, #0x0
- ldr r0, [r5, r2]
- ldr r1, [r6, #0x4]
- add r2, r2, #0x4
- str r0, [r4, #0x0]
- lsl r0, r7, #0x2
- add r0, r5, r0
- ldr r0, [r0, r2]
- ldr r2, [sp, #0x0]
- str r0, [r4, #0x4]
- ldr r0, [r6, #0x8]
- add r1, r2, r1
- str r0, [r4, #0x8]
- ldr r0, _020229B4 ; =0x20060623
- str r0, [r4, #0xc]
- strb r7, [r4, #0x10]
- ldr r2, [r6, #0x8]
- add r0, r5, #0x0
- bl FUN_02022898
- strh r0, [r4, #0x12]
- pop {r3-r7, pc}
- .balign 4
-_020229AC: .word 0x00020464
-_020229B0: .word 0x00020214
-_020229B4: .word 0x20060623
-
- thumb_func_start FUN_020229B8
-FUN_020229B8: ; 0x020229B8
- mov r2, #0x0
- mvn r2, r2
- cmp r0, r2
- bne _020229C8
- cmp r1, #0x0
- bne _020229C8
- add r0, r2, #0x0
- bx lr
-_020229C8:
- cmp r0, #0x0
- bne _020229D8
- mov r2, #0x0
- mvn r2, r2
- cmp r1, r2
- bne _020229D8
- mov r0, #0x1
- bx lr
-_020229D8:
- cmp r0, r1
- bls _020229E0
- mov r0, #0x1
- bx lr
-_020229E0:
- cmp r0, r1
- bhs _020229E8
- mov r0, #0x1
- b _020229EA
-_020229E8:
- mov r0, #0x0
-_020229EA:
- neg r0, r0
- bx lr
- .balign 4
-
- thumb_func_start FUN_020229F0
-FUN_020229F0: ; 0x020229F0
- push {r3-r7, lr}
- add r7, r0, #0x0
- add r6, r1, #0x0
- ldr r0, [r7, #0x4]
- ldr r1, [r6, #0x4]
- add r5, r2, #0x0
- add r4, r3, #0x0
- bl FUN_020229B8
- str r0, [sp, #0x0]
- ldr r0, [r7, #0x8]
- ldr r1, [r6, #0x8]
- bl FUN_020229B8
- ldr r2, [r7, #0x0]
- cmp r2, #0x0
- beq _02022A6A
- ldr r1, [r6, #0x0]
- cmp r1, #0x0
- beq _02022A6A
- ldr r1, [sp, #0x0]
- cmp r1, #0x0
- ble _02022A30
- cmp r0, #0x0
- bgt _02022A26
- bl ErrorHandling
-_02022A26:
- mov r0, #0x0
- str r0, [r5, #0x0]
- mov r0, #0x1
- str r0, [r4, #0x0]
- b _02022A66
-_02022A30:
- bge _02022A44
- cmp r0, #0x0
- blt _02022A3A
- bl ErrorHandling
-_02022A3A:
- mov r0, #0x1
- str r0, [r5, #0x0]
- mov r0, #0x0
- str r0, [r4, #0x0]
- b _02022A66
-_02022A44:
- cmp r0, #0x0
- ble _02022A52
- mov r0, #0x0
- str r0, [r5, #0x0]
- mov r0, #0x1
- str r0, [r4, #0x0]
- b _02022A66
-_02022A52:
- bge _02022A5E
- mov r0, #0x1
- str r0, [r5, #0x0]
- mov r0, #0x0
- str r0, [r4, #0x0]
- b _02022A66
-_02022A5E:
- mov r0, #0x0
- str r0, [r5, #0x0]
- mov r0, #0x1
- str r0, [r4, #0x0]
-_02022A66:
- mov r0, #0x2
- pop {r3-r7, pc}
-_02022A6A:
- cmp r2, #0x0
- beq _02022A80
- ldr r0, [r6, #0x0]
- cmp r0, #0x0
- bne _02022A80
- mov r0, #0x0
- str r0, [r5, #0x0]
- mov r0, #0x2
- str r0, [r4, #0x0]
- mov r0, #0x1
- pop {r3-r7, pc}
-_02022A80:
- cmp r2, #0x0
- bne _02022A94
- ldr r0, [r6, #0x0]
- cmp r0, #0x0
- beq _02022A94
- mov r0, #0x1
- str r0, [r5, #0x0]
- mov r1, #0x2
- str r1, [r4, #0x0]
- pop {r3-r7, pc}
-_02022A94:
- mov r0, #0x2
- str r0, [r5, #0x0]
- str r0, [r4, #0x0]
- mov r0, #0x0
- pop {r3-r7, pc}
- .balign 4
-
- thumb_func_start FUN_02022AA0
-FUN_02022AA0: ; 0x02022AA0
- push {r3-r6}
- mov r4, #0xc
- add r5, r3, #0x0
- mul r5, r4
- add r6, r1, r5
- ldr r5, [r6, #0x4]
- ldr r1, _02022AD4 ; =0x00020214
- str r5, [r0, r1]
- ldr r6, [r6, #0x8]
- add r5, r1, #0x4
- str r6, [r0, r5]
- ldr r5, [sp, #0x10]
- mul r4, r5
- add r2, r2, r4
- ldr r4, [r2, #0x8]
- add r2, r1, #0x0
- add r2, #0x8
- str r4, [r0, r2]
- add r2, r1, #0x0
- add r2, #0xc
- strb r3, [r0, r2]
- add r1, #0xd
- strb r5, [r0, r1]
- pop {r3-r6}
- bx lr
- nop
-_02022AD4: .word 0x00020214
-
- thumb_func_start FUN_02022AD8
-FUN_02022AD8: ; 0x02022AD8
- push {r3-r6, lr}
- sub sp, #0x44
- mov r1, #0x2
- add r5, r0, #0x0
- mov r0, #0x3
- lsl r1, r1, #0x10
- bl AllocFromHeapAtEnd
- mov r1, #0x2
- add r6, r0, #0x0
- mov r0, #0x3
- lsl r1, r1, #0x10
- bl AllocFromHeapAtEnd
- mov r2, #0x2
- add r4, r0, #0x0
- mov r0, #0x0
- add r1, r6, #0x0
- lsl r2, r2, #0x10
- bl FlashLoadChunk
- cmp r0, #0x0
- add r0, sp, #0x2c
- beq _02022B20
- add r1, r5, #0x0
- add r2, r6, #0x0
- mov r3, #0x0
- bl FUN_0202293C
- add r0, sp, #0x14
- add r1, r5, #0x0
- add r2, r6, #0x0
- mov r3, #0x1
- bl FUN_0202293C
- b _02022B2A
-_02022B20:
- bl FUN_0202288C
- add r0, sp, #0x14
- bl FUN_0202288C
-_02022B2A:
- mov r0, #0x1
- lsl r0, r0, #0x12
- add r1, r4, #0x0
- lsr r2, r0, #0x1
- bl FlashLoadChunk
- cmp r0, #0x0
- add r0, sp, #0x38
- beq _02022B54
- add r1, r5, #0x0
- add r2, r4, #0x0
- mov r3, #0x0
- bl FUN_0202293C
- add r0, sp, #0x20
- add r1, r5, #0x0
- add r2, r4, #0x0
- mov r3, #0x1
- bl FUN_0202293C
- b _02022B5E
-_02022B54:
- bl FUN_0202288C
- add r0, sp, #0x20
- bl FUN_0202288C
-_02022B5E:
- add r0, r6, #0x0
- bl FreeToHeap
- add r0, r4, #0x0
- bl FreeToHeap
- add r0, sp, #0x2c
- add r1, sp, #0x38
- add r2, sp, #0x10
- add r3, sp, #0x8
- bl FUN_020229F0
- add r4, r0, #0x0
- add r0, sp, #0x14
- add r1, sp, #0x20
- add r2, sp, #0xc
- add r3, sp, #0x4
- bl FUN_020229F0
- cmp r4, #0x0
- bne _02022B92
- cmp r0, #0x0
- bne _02022B92
- add sp, #0x44
- mov r0, #0x0
- pop {r3-r6, pc}
-_02022B92:
- cmp r4, #0x0
- beq _02022B9A
- cmp r0, #0x0
- bne _02022BA0
-_02022B9A:
- add sp, #0x44
- mov r0, #0x3
- pop {r3-r6, pc}
-_02022BA0:
- cmp r4, #0x2
- bne _02022BE4
- cmp r0, #0x2
- bne _02022BE4
- ldr r3, [sp, #0x10]
- ldr r1, [sp, #0xc]
- mov r2, #0xc
- add r4, r3, #0x0
- mul r4, r2
- add r0, sp, #0x30
- ldr r0, [r0, r4]
- add r4, r1, #0x0
- mul r4, r2
- add r2, sp, #0x18
- ldr r2, [r2, r4]
- cmp r0, r2
- str r1, [sp, #0x0]
- add r1, sp, #0x2c
- bne _02022BD4
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x1
- pop {r3-r6, pc}
-_02022BD4:
- ldr r3, [sp, #0x8]
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x2
- pop {r3-r6, pc}
-_02022BE4:
- cmp r4, #0x1
- bne _02022C3A
- cmp r0, #0x2
- bne _02022C3A
- ldr r3, [sp, #0x10]
- ldr r0, [sp, #0xc]
- mov r4, #0xc
- add r2, r3, #0x0
- add r6, r0, #0x0
- mul r2, r4
- add r1, sp, #0x30
- ldr r2, [r1, r2]
- mul r6, r4
- add r1, sp, #0x18
- ldr r6, [r1, r6]
- cmp r2, r6
- bne _02022C18
- str r0, [sp, #0x0]
- add r0, r5, #0x0
- add r1, sp, #0x2c
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x2
- pop {r3-r6, pc}
-_02022C18:
- ldr r0, [sp, #0x4]
- mul r4, r0
- ldr r1, [r1, r4]
- cmp r2, r1
- bne _02022C34
- str r0, [sp, #0x0]
- add r0, r5, #0x0
- add r1, sp, #0x2c
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x2
- pop {r3-r6, pc}
-_02022C34:
- add sp, #0x44
- mov r0, #0x3
- pop {r3-r6, pc}
-_02022C3A:
- cmp r4, #0x2
- bne _02022C7E
- cmp r0, #0x1
- bne _02022C7E
- ldr r3, [sp, #0x10]
- ldr r1, [sp, #0xc]
- mov r2, #0xc
- add r4, r3, #0x0
- mul r4, r2
- add r0, sp, #0x30
- ldr r0, [r0, r4]
- add r4, r1, #0x0
- mul r4, r2
- add r2, sp, #0x18
- ldr r2, [r2, r4]
- cmp r0, r2
- str r1, [sp, #0x0]
- add r1, sp, #0x2c
- bne _02022C6E
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x1
- pop {r3-r6, pc}
-_02022C6E:
- ldr r3, [sp, #0x8]
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x2
- pop {r3-r6, pc}
-_02022C7E:
- cmp r4, #0x1
- bne _02022CBC
- cmp r0, #0x1
- bne _02022CBC
- ldr r0, [sp, #0xc]
- ldr r2, [sp, #0x10]
- cmp r2, r0
- bne _02022CBC
- add r3, r2, #0x0
- mov r1, #0xc
- mul r3, r1
- add r2, sp, #0x30
- mul r1, r0
- add r0, sp, #0x18
- ldr r2, [r2, r3]
- ldr r0, [r0, r1]
- cmp r2, r0
- beq _02022CA6
- bl ErrorHandling
-_02022CA6:
- ldr r0, [sp, #0xc]
- add r1, sp, #0x2c
- str r0, [sp, #0x0]
- ldr r3, [sp, #0x10]
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- add sp, #0x44
- mov r0, #0x1
- pop {r3-r6, pc}
-_02022CBC:
- ldr r1, [sp, #0x10]
- mov r0, #0xc
- add r2, r1, #0x0
- mul r2, r0
- add r1, sp, #0x30
- ldr r3, [r1, r2]
- ldr r1, [sp, #0xc]
- add r2, r1, #0x0
- mul r2, r0
- add r0, sp, #0x18
- ldr r0, [r0, r2]
- cmp r3, r0
- beq _02022CDA
- bl ErrorHandling
-_02022CDA:
- ldr r0, [sp, #0xc]
- add r1, sp, #0x2c
- str r0, [sp, #0x0]
- ldr r3, [sp, #0x10]
- add r0, r5, #0x0
- add r2, sp, #0x14
- bl FUN_02022AA0
- mov r0, #0x2
- add sp, #0x44
- pop {r3-r6, pc}
-
- thumb_func_start FUN_02022CF0
-FUN_02022CF0: ; 0x02022CF0
- push {r3-r5, lr}
- add r5, r1, #0x0
- add r4, r2, #0x0
- bl GetChunkOffsetFromCurrentSaveSlot
- ldr r1, [r5, #0x4]
- ldr r2, [r5, #0x8]
- add r1, r4, r1
- bl FlashLoadChunk
- pop {r3-r5, pc}
- .balign 4
-
- thumb_func_start FUN_02022D08
-FUN_02022D08: ; 0x02022D08
- ; BOOL FUN_02022D08(struct SaveBlock2 * sav2) {
- push {r3-r7, lr}
- add r5, r0, #0x0
- ldr r0, _02022D4C ; =0x00020464 ; unk_20464
- mov r7, #0x85 ; dynamic_region
- mov r4, #0x0
- add r6, r5, r0
- lsl r7, r7, #0x2 ; dynamic_region
-_02022D16: ; for (int i = 0; i < 2; i++) {
- ldr r0, _02022D50 ; =0x00020220 ; unk_20220
- add r1, r5, r4
- ldrb r0, [r1, r0]
- add r1, r6, #0x0
- add r2, r5, r7
- bl FUN_02022CF0 ; if (!FUN_02022CF0(sav2->unk_20220[i], &sav2->unk_20464[i], sav2->dynamic_region)) return FALSE;
- cmp r0, #0x0
- bne _02022D2C
- mov r0, #0x0
- pop {r3-r7, pc}
-_02022D2C:
- add r0, r5, #0x0
- add r1, r5, r7
- add r2, r4, #0x0
- bl FUN_020228E0 ; if (!FUN_020228E0(sav2, sav2->dynamic_region, i)) return FALSE;
- cmp r0, #0x0
- bne _02022D3E
- mov r0, #0x0
- pop {r3-r7, pc}
-_02022D3E:
- add r4, r4, #0x1
- add r6, #0xc
- cmp r4, #0x2
- blt _02022D16 ; }
- mov r0, #0x1 ; return TRUE; }
- pop {r3-r7, pc}
- nop
-_02022D4C: .word 0x00020464
-_02022D50: .word 0x00020220
-
- thumb_func_start FUN_02022D54
-FUN_02022D54: ; 0x02022D54
- push {r4-r6, lr}
- add r3, r1, #0x0
- ldr r1, _02022D90 ; =0x00020464
- add r5, r0, #0x0
- add r6, r2, #0x0
- add r2, r5, r1
- mov r1, #0xc
- mul r1, r3
- add r4, r2, r1
- mov r1, #0x85
- lsl r1, r1, #0x2
- add r1, r5, r1
- add r2, r3, #0x0
- bl FUN_02022968
- add r0, r6, #0x0
- add r1, r4, #0x0
- bl GetChunkOffsetFromCurrentSaveSlot
- mov r1, #0x85
- lsl r1, r1, #0x2
- add r2, r5, r1
- ldr r1, [r4, #0x4]
- add r1, r2, r1
- ldr r2, [r4, #0x8]
- sub r2, #0x14
- bl FlashWriteChunkInternal
- pop {r4-r6, pc}
- nop
-_02022D90: .word 0x00020464
-
- thumb_func_start FUN_02022D94
-FUN_02022D94: ; 0x02022D94
- push {r4-r6, lr}
- add r6, r0, #0x0
- ldr r0, _02022DC4 ; =0x00020464
- add r3, r6, r0
- mov r0, #0xc
- mul r0, r1
- add r4, r3, r0
- add r0, r2, #0x0
- add r1, r4, #0x0
- ldr r5, [r4, #0x8]
- bl GetChunkOffsetFromCurrentSaveSlot
- mov r1, #0x2
- lsl r1, r1, #0x8
- add r2, r6, r1
- ldr r1, [r4, #0x4]
- add r0, r5, r0
- add r1, r2, r1
- sub r0, #0x14
- add r1, r1, r5
- mov r2, #0x14
- bl FlashWriteChunkInternal
- pop {r4-r6, pc}
- .balign 4
-_02022DC4: .word 0x00020464
-
- thumb_func_start FUN_02022DC8
-FUN_02022DC8: ; 0x02022DC8
- push {r4-r6, lr}
- add r6, r0, #0x0
- ldr r0, _02022DF8 ; =0x00020464
- add r3, r6, r0
- mov r0, #0xc
- mul r0, r1
- add r4, r3, r0
- add r0, r2, #0x0
- add r1, r4, #0x0
- ldr r5, [r4, #0x8]
- bl GetChunkOffsetFromCurrentSaveSlot
- mov r1, #0x82
- lsl r1, r1, #0x2
- add r2, r6, r1
- ldr r1, [r4, #0x4]
- add r0, r5, r0
- add r1, r2, r1
- sub r0, #0xc
- add r1, r1, r5
- mov r2, #0x8
- bl FlashWriteChunkInternal
- pop {r4-r6, pc}
- .balign 4
-_02022DF8: .word 0x00020464
-
- thumb_func_start FUN_02022DFC
-FUN_02022DFC: ; 0x02022DFC
- push {r3-r7, lr}
- ldr r7, _02022E70 ; =0x00020218
- add r4, r1, #0x0
- mov r12, r2
- mov r1, #0x0
- add r2, r0, #0x0
- add r3, r4, #0x0
- add r6, r7, #0x0
-_02022E0C:
- ldr r5, _02022E70 ; =0x00020218
- add r1, r1, #0x1
- ldr r5, [r2, r5]
- str r5, [r3, #0x1c]
- ldr r5, [r2, r7]
- add r3, r3, #0x4
- add r5, r5, #0x1
- str r5, [r2, r6]
- add r2, r2, #0x4
- cmp r1, #0x2
- blt _02022E0C
- mov r1, #0x0
- str r1, [r4, #0x14]
- mov r2, r12
- str r1, [r4, #0x0]
- cmp r2, #0x2
- bne _02022E58
- ldr r2, [r0, #0xc]
- cmp r2, #0x0
- beq _02022E4E
- mov r2, #0x1
- str r2, [r4, #0x0]
- ldr r2, _02022E74 ; =0x00020214
- ldr r3, [r0, r2]
- str r3, [r4, #0x18]
- ldr r3, [r0, r2]
- add r3, r3, #0x1
- str r3, [r0, r2]
- str r1, [r4, #0x4]
- str r1, [r4, #0x8]
- mov r0, #0x2
- str r0, [r4, #0xc]
- b _02022E66
-_02022E4E:
- str r1, [r4, #0x4]
- str r1, [r4, #0x8]
- mov r0, #0x1
- str r0, [r4, #0xc]
- b _02022E66
-_02022E58:
- mov r0, r12
- str r0, [r4, #0x4]
- mov r0, r12
- str r0, [r4, #0x8]
- mov r0, r12
- add r0, r0, #0x1
- str r0, [r4, #0xc]
-_02022E66:
- mov r0, #0x1
- bl FUN_02016444
- pop {r3-r7, pc}
- nop
-_02022E70: .word 0x00020218
-_02022E74: .word 0x00020214
-
- thumb_func_start FUN_02022E78
-FUN_02022E78: ; 0x02022E78
- push {r3-r5, lr}
- add r4, r1, #0x0
- add r5, r0, #0x0
- ldr r0, [r4, #0x14]
- cmp r0, #0x5
- bhi _02022F78
- add r0, r0, r0
- add r0, pc
- ldrh r0, [r0, #0x6]
- lsl r0, r0, #0x10
- asr r0, r0, #0x10
- add pc, r0
-_02022E90: ; jump table (using 16-bit offset)
- .short _02022E9C - _02022E90 - 2; case 0
- .short _02022EC0 - _02022E90 - 2; case 1
- .short _02022EDC - _02022E90 - 2; case 2
- .short _02022F00 - _02022E90 - 2; case 3
- .short _02022F2A - _02022E90 - 2; case 4
- .short _02022F4E - _02022E90 - 2; case 5
-_02022E9C:
- ldr r1, [r4, #0x8]
- ldr r0, _02022F7C ; =0x00020220
- add r2, r5, r1
- ldrb r0, [r2, r0]
- cmp r0, #0x0
- bne _02022EAC
- mov r2, #0x1
- b _02022EAE
-_02022EAC:
- mov r2, #0x0
-_02022EAE:
- lsl r2, r2, #0x18
- add r0, r5, #0x0
- lsr r2, r2, #0x18
- bl FUN_02022D54
- str r0, [r4, #0x10]
- ldr r0, [r4, #0x14]
- add r0, r0, #0x1
- str r0, [r4, #0x14]
-_02022EC0:
- ldr r0, [r4, #0x10]
- add r1, sp, #0x0
- bl WaitFlashWrite
- cmp r0, #0x0
- beq _02022F78
- ldr r0, [sp, #0x0]
- cmp r0, #0x0
- bne _02022ED6
- mov r0, #0x3
- pop {r3-r5, pc}
-_02022ED6:
- ldr r0, [r4, #0x14]
- add r0, r0, #0x1
- str r0, [r4, #0x14]
-_02022EDC:
- ldr r1, [r4, #0x8]
- ldr r0, _02022F7C ; =0x00020220
- add r2, r5, r1
- ldrb r0, [r2, r0]
- cmp r0, #0x0
- bne _02022EEC
- mov r2, #0x1
- b _02022EEE
-_02022EEC:
- mov r2, #0x0
-_02022EEE:
- lsl r2, r2, #0x18
- add r0, r5, #0x0
- lsr r2, r2, #0x18
- bl FUN_02022DC8
- str r0, [r4, #0x10]
- ldr r0, [r4, #0x14]
- add r0, r0, #0x1
- str r0, [r4, #0x14]
-_02022F00:
- ldr r0, [r4, #0x10]
- add r1, sp, #0x0
- bl WaitFlashWrite
- cmp r0, #0x0
- beq _02022F78
- ldr r0, [sp, #0x0]
- cmp r0, #0x0
- bne _02022F16
- mov r0, #0x3
- pop {r3-r5, pc}
-_02022F16:
- ldr r0, [r4, #0x14]
- add r0, r0, #0x1
- str r0, [r4, #0x14]
- ldr r0, [r4, #0x8]
- add r1, r0, #0x1
- ldr r0, [r4, #0xc]
- cmp r1, r0
- bne _02022F2A
- mov r0, #0x1
- pop {r3-r5, pc}
-_02022F2A:
- ldr r1, [r4, #0x8]
- ldr r0, _02022F7C ; =0x00020220
- add r2, r5, r1
- ldrb r0, [r2, r0]
- cmp r0, #0x0
- bne _02022F3A
- mov r2, #0x1
- b _02022F3C
-_02022F3A:
- mov r2, #0x0
-_02022F3C:
- lsl r2, r2, #0x18
- add r0, r5, #0x0
- lsr r2, r2, #0x18
- bl FUN_02022D94
- str r0, [r4, #0x10]
- ldr r0, [r4, #0x14]
- add r0, r0, #0x1
- str r0, [r4, #0x14]
-_02022F4E:
- ldr r0, [r4, #0x10]
- add r1, sp, #0x0
- bl WaitFlashWrite
- cmp r0, #0x0
- beq _02022F78
- ldr r0, [sp, #0x0]
- cmp r0, #0x0
- bne _02022F64
- mov r0, #0x3
- pop {r3-r5, pc}
-_02022F64:
- ldr r0, [r4, #0x8]
- add r1, r0, #0x1
- str r1, [r4, #0x8]
- ldr r0, [r4, #0xc]
- cmp r1, r0
- bne _02022F74
- mov r0, #0x2
- pop {r3-r5, pc}
-_02022F74:
- mov r0, #0x0
- str r0, [r4, #0x14]
-_02022F78:
- mov r0, #0x0
- pop {r3-r5, pc}
- .balign 4
-_02022F7C: .word 0x00020220
-
- thumb_func_start FUN_02022F80
-FUN_02022F80: ; 0x02022F80
- push {r3-r7, lr}
- add r3, r0, #0x0
- add r0, r1, #0x0
- cmp r2, #0x3
- bne _02022FAA
- ldr r1, [r0, #0x0]
- cmp r1, #0x0
- beq _02022F96
- ldr r2, [r0, #0x18]
- ldr r1, _02022FE4 ; =0x00020214
- str r2, [r3, r1]
-_02022F96:
- ldr r1, _02022FE8 ; =0x00020218
- mov r4, #0x0
-_02022F9A:
- ldr r2, [r0, #0x1c]
- add r4, r4, #0x1
- str r2, [r3, r1]
- add r0, r0, #0x4
- add r3, r3, #0x4
- cmp r4, #0x2
- blt _02022F9A
- b _02022FDA
-_02022FAA:
- ldr r6, [r0, #0x4]
- ldr r1, [r0, #0xc]
- cmp r6, r1
- bge _02022FD0
- ldr r1, _02022FEC ; =0x00020220
- mov r7, #0x1
- add r2, r1, #0x0
-_02022FB8:
- add r5, r3, r6
- ldrb r4, [r5, r2]
- cmp r4, #0x0
- bne _02022FC4
- add r4, r7, #0x0
- b _02022FC6
-_02022FC4:
- mov r4, #0x0
-_02022FC6:
- strb r4, [r5, r1]
- ldr r4, [r0, #0xc]
- add r6, r6, #0x1
- cmp r6, r4
- blt _02022FB8
-_02022FD0:
- mov r0, #0x1
- str r0, [r3, #0x4]
- mov r0, #0x0
- str r0, [r3, #0x8]
- str r0, [r3, #0xc]
-_02022FDA:
- mov r0, #0x1
- bl FUN_02016454
- pop {r3-r7, pc}
- nop
-_02022FE4: .word 0x00020214
-_02022FE8: .word 0x00020218
-_02022FEC: .word 0x00020220
-
- thumb_func_start FUN_02022FF0
-FUN_02022FF0: ; 0x02022FF0
- push {r3-r5, lr}
- add r4, r1, #0x0
- ldr r1, [r4, #0x0]
- cmp r1, #0x0
- beq _02023000
- ldr r2, [r4, #0x18]
- ldr r1, _0202303C ; =0x00020214
- str r2, [r0, r1]
-_02023000:
- ldr r1, _02023040 ; =0x00020218
- mov r3, #0x0
- add r5, r4, #0x0
-_02023006:
- ldr r2, [r5, #0x1c]
- add r3, r3, #0x1
- str r2, [r0, r1]
- add r5, r5, #0x4
- add r0, r0, #0x4
- cmp r3, #0x2
- blt _02023006
- bl CARD_TryWaitBackupAsync
- cmp r0, #0x0
- bne _02023034
- bl CARD_CancelBackupAsync
- ldr r0, [r4, #0x10]
- lsl r0, r0, #0x10
- lsr r0, r0, #0x10
- bl CARD_UnlockBackup
- ldr r0, [r4, #0x10]
- lsl r0, r0, #0x10
- lsr r0, r0, #0x10
- bl OS_ReleaseLockID
-_02023034:
- mov r0, #0x1
- bl FUN_02016454
- pop {r3-r5, pc}
- .balign 4
-_0202303C: .word 0x00020214
-_02023040: .word 0x00020218
-
- thumb_func_start FUN_02023044
-FUN_02023044: ; 0x02023044
- push {r3-r6, lr}
- sub sp, #0x24
- add r1, sp, #0x0
- mov r2, #0x2
- add r5, r0, #0x0
- bl FUN_02022DFC
- add r6, sp, #0x0
-_02023054:
- add r0, r5, #0x0
- add r1, r6, #0x0
- bl FUN_02022E78
- add r4, r0, #0x0
- beq _02023054
- cmp r4, #0x1
- beq _02023054
- add r0, r5, #0x0
- add r1, sp, #0x0
- add r2, r4, #0x0
- bl FUN_02022F80
- add r0, r4, #0x0
- add sp, #0x24
- pop {r3-r6, pc}
-
- thumb_func_start FlashClobberChunkFooter
-FlashClobberChunkFooter: ; 0x02023074
- push {r4-r5, lr}
- sub sp, #0x14
- add r4, r2, #0x0
- ldr r2, _020230A8 ; =0x00020464
- add r2, r0, r2
- mov r0, #0xc
- mul r0, r1
- add r5, r2, r0
- add r0, sp, #0x0
- mov r1, #0xff
- mov r2, #0x14
- bl MI_CpuFill8
- add r0, r4, #0x0
- add r1, r5, #0x0
- bl GetChunkOffsetFromCurrentSaveSlot
- ldr r1, [r5, #0x8]
- mov r2, #0x14
- add r0, r1, r0
- sub r0, #0x14
- add r1, sp, #0x0
- bl FlashWriteChunk
- add sp, #0x14
- pop {r4-r5, pc}
- .balign 4
-_020230A8: .word 0x00020464
-
- thumb_func_start SavArray_sizeof
-SavArray_sizeof: ; 0x020230AC
- push {r3-r5, lr}
- add r5, r0, #0x0
- ldr r0, _020230DC ; =UNK_020EE6DC
- ldr r4, _020230E0 ; =UNK_020EE700
- ldr r0, [r0, #0x0]
- cmp r5, r0
- blt _020230BE
- bl ErrorHandling
-_020230BE:
- lsl r0, r5, #0x4
- add r0, r4, r0
- ldr r0, [r0, #0x8]
- blx r0
- lsr r3, r0, #0x1f
- lsl r2, r0, #0x1e
- sub r2, r2, r3
- mov r1, #0x1e
- ror r2, r1
- add r2, r3, r2
- mov r1, #0x4
- sub r1, r1, r2
- add r0, r0, r1
- pop {r3-r5, pc}
- nop
-_020230DC: .word UNK_020EE6DC
-_020230E0: .word UNK_020EE700
-
- thumb_func_start SaveBlock2_InitSubstructs
-SaveBlock2_InitSubstructs: ; 0x020230E4
- push {r3-r7, lr}
- sub sp, #0x8
- add r5, r0, #0x0
- ldr r0, _02023158 ; =UNK_020EE6DC
- ldr r4, _0202315C ; =UNK_020EE700
- ldr r0, [r0, #0x0]
- mov r7, #0x0
- str r0, [sp, #0x0]
- cmp r0, #0x24
- beq _020230FC
- bl ErrorHandling
-_020230FC:
- ldr r0, [sp, #0x0]
- mov r6, #0x0
- cmp r0, #0x0
- ble _02023148
- sub r0, r0, #0x1
- str r0, [sp, #0x4]
-_02023108:
- ldr r0, [r4, #0x0]
- cmp r6, r0
- beq _02023112
- bl ErrorHandling
-_02023112:
- ldr r0, [r4, #0x0]
- str r0, [r5, #0x0]
- add r0, r6, #0x0
- bl SavArray_sizeof
- str r0, [r5, #0x4]
- str r7, [r5, #0x8]
- mov r0, #0x0
- strh r0, [r5, #0xc]
- ldr r0, [r4, #0x4]
- strh r0, [r5, #0xe]
- ldr r0, [r5, #0x4]
- add r7, r7, r0
- ldr r0, [sp, #0x4]
- cmp r6, r0
- beq _0202313A
- ldr r1, [r4, #0x4]
- ldr r0, [r4, #0x14]
- cmp r1, r0
- beq _0202313C
-_0202313A:
- add r7, #0x14
-_0202313C:
- ldr r0, [sp, #0x0]
- add r6, r6, #0x1
- add r4, #0x10
- add r5, #0x10
- cmp r6, r0
- blt _02023108
-_02023148:
- mov r0, #0x2
- lsl r0, r0, #0x10
- cmp r7, r0
- ble _02023154
- bl ErrorHandling
-_02023154:
- add sp, #0x8
- pop {r3-r7, pc}
- .balign 4
-_02023158: .word UNK_020EE6DC
-_0202315C: .word UNK_020EE700
-
- thumb_func_start FUN_02023160
-FUN_02023160: ; 0x02023160
- push {r3-r7, lr}
- sub sp, #0x8
- str r0, [sp, #0x0]
- mov r0, #0x0
- str r0, [sp, #0x4]
- mov r12, r0
- add r3, r0, #0x0
- add r6, r0, #0x0
- ldr r0, _020231EC ; =UNK_020EE6DC
- ldr r4, [sp, #0x0]
- ldr r7, [r0, #0x0]
- add r5, r1, #0x0
-_02023178:
- add r2, r4, #0x0
- strb r6, [r4, #0x0]
- mov r0, #0x0
- str r0, [r4, #0x8]
- add r2, #0x8
- b _02023190
-_02023184:
- ldr r0, [r5, #0x4]
- ldr r1, [r2, #0x0]
- add r5, #0x10
- add r0, r1, r0
- str r0, [r2, #0x0]
- add r3, r3, #0x1
-_02023190:
- ldrh r0, [r5, #0xe]
- cmp r6, r0
- bne _0202319A
- cmp r3, r7
- blt _02023184
-_0202319A:
- ldr r0, [r4, #0x8]
- add r6, r6, #0x1
- add r0, #0x14
- str r0, [r4, #0x8]
- ldr r0, [sp, #0x4]
- strb r0, [r4, #0x1]
- mov r0, r12
- str r0, [r4, #0x4]
- ldr r1, [r4, #0x8]
- ldr r0, _020231F0 ; =0x00000FFF
- add r0, r1, r0
- lsr r0, r0, #0xc
- strb r0, [r4, #0x2]
- ldrb r1, [r4, #0x2]
- ldr r0, [sp, #0x4]
- add r0, r0, r1
- str r0, [sp, #0x4]
- ldr r0, [r4, #0x8]
- mov r1, r12
- add r0, r1, r0
- add r4, #0xc
- mov r12, r0
- cmp r6, #0x2
- blt _02023178
- ldr r0, [sp, #0x0]
- ldrb r1, [r0, #0xd]
- ldrb r0, [r0, #0xe]
- add r1, r1, r0
- ldr r0, [sp, #0x4]
- cmp r0, r1
- beq _020231DC
- bl ErrorHandling
-_020231DC:
- ldr r0, [sp, #0x4]
- cmp r0, #0x20
- ble _020231E6
- bl ErrorHandling
-_020231E6:
- add sp, #0x8
- pop {r3-r7, pc}
- nop
-_020231EC: .word UNK_020EE6DC
-_020231F0: .word 0x00000FFF
-
- thumb_func_start Sav2_InitDynamicRegion_Internal
-Sav2_InitDynamicRegion_Internal: ; 0x020231F4
- ; r0: &sav2->dynamic_region
- ; r1: &sav2->arraySpecs
- push {r3-r7, lr}
- sub sp, #0x8
- add r6, r0, #0x0
- mov r2, #0x2
- add r5, r1, #0x0
- mov r0, #0x0
- add r1, r6, #0x0
- lsl r2, r2, #0x10
- ldr r4, _02023240 ; =UNK_020EE700
- bl MIi_CpuClearFast
- ldr r0, _02023244 ; =UNK_020EE6DC
- mov r7, #0x0
- ldr r0, [r0, #0x0]
- str r0, [sp, #0x0]
- cmp r0, #0x0
- ble _0202323A
-_02023216:
- ldr r0, [r5, #0x8]
- ldr r2, [r5, #0x4]
- str r0, [sp, #0x4]
- ldr r1, [sp, #0x4]
- mov r0, #0x0
- add r1, r6, r1
- bl MIi_CpuClearFast
- ldr r0, [sp, #0x4]
- ldr r1, [r4, #0xc]
- add r0, r6, r0
- blx r1
- ldr r0, [sp, #0x0]
- add r7, r7, #0x1
- add r5, #0x10
- add r4, #0x10
- cmp r7, r0
- blt _02023216
-_0202323A:
- add sp, #0x8
- pop {r3-r7, pc}
- nop
-_02023240: .word UNK_020EE700
-_02023244: .word UNK_020EE6DC
-
- thumb_func_start CreateChunkFooter
-CreateChunkFooter: ; 0x02023248
- ; void CreateChunkFooter(struct SaveBlock2 * sav2, void * data, u16 id, u32 size)
- push {r3-r5, lr}
- ldr r5, _0202326C ; =0x20060623
- add r4, r1, r3
- str r5, [r1, r3]
- ldr r5, _02023270 ; =0x000204A4
- ldr r5, [r0, r5]
- add r0, #0x14
- add r5, r5, #0x1
- str r5, [r4, #0x4]
- str r3, [r4, #0x8]
- add r3, #0xe
- strh r2, [r4, #0xc]
- add r2, r3, #0x0
- bl MATH_CalcCRC16CCITT
- strh r0, [r4, #0xe]
- pop {r3-r5, pc}
- nop
-_0202326C: .word 0x20060623
-_02023270: .word 0x000204A4
-
- thumb_func_start ValidateChunk
-ValidateChunk: ; 0x02023274
- push {r4-r6, lr}
- ldr r6, [r1, r3]
- ldr r5, _020232B0 ; =0x20060623
- add r4, r1, r3
- cmp r6, r5
- beq _02023284
- mov r0, #0x0
- pop {r4-r6, pc}
-_02023284:
- ldr r5, [r4, #0x8]
- cmp r5, r3
- beq _0202328E
- mov r0, #0x0
- pop {r4-r6, pc}
-_0202328E:
- ldrh r5, [r4, #0xc]
- cmp r5, r2
- beq _02023298
- mov r0, #0x0
- pop {r4-r6, pc}
-_02023298:
- add r3, #0xe
- add r0, #0x14
- add r2, r3, #0x0
- bl MATH_CalcCRC16CCITT
- ldrh r1, [r4, #0xe]
- cmp r1, r0
- bne _020232AC
- mov r0, #0x1
- pop {r4-r6, pc}
-_020232AC:
- mov r0, #0x0
- pop {r4-r6, pc}
- .balign 4
-_020232B0: .word 0x20060623
-
- thumb_func_start FUN_020232B4
-FUN_020232B4: ; 0x020232B4
- add r0, r0, r1
- ldr r0, [r0, #0x4]
- bx lr
- .balign 4
-
- thumb_func_start WriteSaveFileToFlash
-WriteSaveFileToFlash: ; 0x020232BC
- push {r3-r7, lr}
- sub sp, #0x8
- add r7, r0, #0x0
- mov r0, #0x1
- add r5, r1, #0x0
- add r6, r2, #0x0
- bl FUN_02016444
- ldr r0, _020233FC ; =UNK_020EE6D8
- ldr r0, [r0, #0x0]
- cmp r5, r0
- blt _020232D8
- bl ErrorHandling
-_020232D8:
- ldr r1, _02023400 ; =UNK_020EE6E0
- lsl r0, r5, #0x4
- add r4, r1, r0
- ldr r0, [r1, r0]
- cmp r0, r5
- beq _020232E8
- bl ErrorHandling
-_020232E8:
- ldr r0, [r4, #0x8]
- blx r0
- str r0, [sp, #0x4]
- add r0, #0x10
- str r0, [sp, #0x4]
- ldr r0, _02023404 ; =0x000204A0
- ldr r0, [r7, r0]
- cmp r0, #0x1
- ldr r0, [r4, #0x8]
- bne _0202336E
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl CreateChunkFooter
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x4]
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashWriteChunk
- str r0, [sp, #0x0]
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl ValidateChunk
- cmp r0, #0x1
- beq _02023330
- bl ErrorHandling
-_02023330:
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl CreateChunkFooter
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x4]
- add r0, #0x40
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashWriteChunk
- ldr r1, [sp, #0x0]
- orr r0, r1
- str r0, [sp, #0x0]
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl ValidateChunk
- cmp r0, #0x1
- beq _020233DE
- bl ErrorHandling
- b _020233DE
-_0202336E:
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl CreateChunkFooter
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x4]
- add r0, #0x40
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashWriteChunk
- str r0, [sp, #0x0]
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl ValidateChunk
- cmp r0, #0x1
- beq _020233A4
- bl ErrorHandling
-_020233A4:
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl CreateChunkFooter
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x4]
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashWriteChunk
- ldr r1, [sp, #0x0]
- orr r0, r1
- str r0, [sp, #0x0]
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r7, #0x0
- add r1, r6, #0x0
- add r2, r5, #0x0
- bl ValidateChunk
- cmp r0, #0x1
- beq _020233DE
- bl ErrorHandling
-_020233DE:
- ldr r0, [sp, #0x0]
- cmp r0, #0x1
- bne _020233F0
- mov r0, #0x1
- bl FUN_02016454
- add sp, #0x8
- mov r0, #0x2
- pop {r3-r7, pc}
-_020233F0:
- mov r0, #0x1
- bl FUN_02016454
- mov r0, #0x3
- add sp, #0x8
- pop {r3-r7, pc}
- .balign 4
-_020233FC: .word UNK_020EE6D8
-_02023400: .word UNK_020EE6E0
-_02023404: .word 0x000204A0
-
- thumb_func_start ReadSaveFileFromFlash
-ReadSaveFileFromFlash: ; 0x02023408
- push {r4-r7, lr}
- sub sp, #0x14
- add r5, r0, #0x0
- ldr r0, _02023564 ; =UNK_020EE6D8
- add r7, r2, #0x0
- ldr r0, [r0, #0x0]
- add r6, r1, #0x0
- str r3, [sp, #0x0]
- cmp r7, r0
- blt _02023420
- bl ErrorHandling
-_02023420:
- ldr r1, _02023568 ; =UNK_020EE6E0
- lsl r0, r7, #0x4
- add r4, r1, r0
- ldr r0, [r1, r0]
- cmp r0, r7
- beq _02023430
- bl ErrorHandling
-_02023430:
- ldr r0, [r4, #0x8]
- blx r0
- str r0, [sp, #0x10]
- add r0, #0x10
- str r0, [sp, #0x10]
- ldr r1, [sp, #0x10]
- add r0, r6, #0x0
- bl AllocFromHeap
- add r6, r0, #0x0
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x10]
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashLoadChunk
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r5, #0x0
- add r1, r6, #0x0
- add r2, r7, #0x0
- bl ValidateChunk
- str r0, [sp, #0xc]
- ldr r0, [r4, #0x8]
- blx r0
- add r1, r0, #0x0
- add r0, r6, #0x0
- bl FUN_020232B4
- str r0, [sp, #0x8]
- ldr r0, [r4, #0x4]
- ldr r2, [sp, #0x10]
- add r0, #0x40
- lsl r0, r0, #0xc
- add r1, r6, #0x0
- bl FlashLoadChunk
- ldr r0, [r4, #0x8]
- blx r0
- add r3, r0, #0x0
- add r0, r5, #0x0
- add r1, r6, #0x0
- add r2, r7, #0x0
- bl ValidateChunk
- add r7, r0, #0x0
- ldr r0, [r4, #0x8]
- blx r0
- add r1, r0, #0x0
- add r0, r6, #0x0
- bl FUN_020232B4
- str r0, [sp, #0x4]
- ldr r0, [sp, #0x0]
- mov r1, #0x1
- str r1, [r0, #0x0]
- ldr r0, [sp, #0xc]
- cmp r0, #0x1
- bne _020234CC
- cmp r7, #0x0
- bne _020234CC
- ldr r0, _0202356C ; =0x000204A0
- mov r1, #0x0
- str r1, [r5, r0]
- add r1, r0, #0x4
- ldr r0, [sp, #0x8]
- ldr r2, [sp, #0x10]
- str r0, [r5, r1]
- ldr r0, [r4, #0x4]
- add r1, r6, #0x0
- lsl r0, r0, #0xc
- bl FlashLoadChunk
- add sp, #0x14
- add r0, r6, #0x0
- pop {r4-r7, pc}
-_020234CC:
- ldr r0, [sp, #0xc]
- cmp r0, #0x0
- bne _020234F6
- cmp r7, #0x1
- bne _020234F6
- ldr r0, _0202356C ; =0x000204A0
- mov r1, #0x1
- str r1, [r5, r0]
- add r1, r0, #0x4
- ldr r0, [sp, #0x4]
- ldr r2, [sp, #0x10]
- str r0, [r5, r1]
- ldr r0, [r4, #0x4]
- add r1, r6, #0x0
- add r0, #0x40
- lsl r0, r0, #0xc
- bl FlashLoadChunk
- add sp, #0x14
- add r0, r6, #0x0
- pop {r4-r7, pc}
-_020234F6:
- ldr r0, [sp, #0xc]
- cmp r0, #0x1
- bne _0202354C
- cmp r7, #0x1
- bne _0202354C
- ldr r0, [sp, #0x8]
- ldr r1, [sp, #0x4]
- bl FUN_020229B8
- mov r1, #0x0
- mvn r1, r1
- cmp r0, r1
- ldr r0, _0202356C ; =0x000204A0
- beq _0202352E
- mov r1, #0x0
- str r1, [r5, r0]
- add r1, r0, #0x4
- ldr r0, [sp, #0x8]
- ldr r2, [sp, #0x10]
- str r0, [r5, r1]
- ldr r0, [r4, #0x4]
- add r1, r6, #0x0
- lsl r0, r0, #0xc
- bl FlashLoadChunk
- add sp, #0x14
- add r0, r6, #0x0
- pop {r4-r7, pc}
-_0202352E:
- mov r1, #0x1
- str r1, [r5, r0]
- add r1, r0, #0x4
- ldr r0, [sp, #0x4]
- ldr r2, [sp, #0x10]
- str r0, [r5, r1]
- ldr r0, [r4, #0x4]
- add r1, r6, #0x0
- add r0, #0x40
- lsl r0, r0, #0xc
- bl FlashLoadChunk
- add sp, #0x14
- add r0, r6, #0x0
- pop {r4-r7, pc}
-_0202354C:
- ldr r0, [sp, #0x0]
- mov r1, #0x2
- str r1, [r0, #0x0]
- ldr r0, _0202356C ; =0x000204A0
- mov r1, #0x0
- str r1, [r5, r0]
- add r0, r0, #0x4
- str r1, [r5, r0]
- add r0, r6, #0x0
- add sp, #0x14
- pop {r4-r7, pc}
- nop
-_02023564: .word UNK_020EE6D8
-_02023568: .word UNK_020EE6E0
-_0202356C: .word 0x000204A0
-
- thumb_func_start SaveDetectFlash
-SaveDetectFlash: ; 0x02023570
- push {r3-r5, lr}
- bl OS_GetLockID
- add r4, r0, #0x0
- mov r0, #0x2
- mvn r0, r0
- cmp r4, r0
- bne _02023584
- bl ErrorHandling
-_02023584:
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl CARD_LockBackup
- ldr r0, _020235C8 ; =0x00001302
- bl CARD_IdentifyBackup
- cmp r0, #0x0
- beq _0202359A
- ldr r5, _020235C8 ; =0x00001302
- b _020235AA
-_0202359A:
- ldr r0, _020235CC ; =0x00001202
- bl CARD_IdentifyBackup
- cmp r0, #0x0
- beq _020235A8
- ldr r5, _020235CC ; =0x00001202
- b _020235AA
-_020235A8:
- mov r5, #0x0
-_020235AA:
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl CARD_UnlockBackup
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl OS_ReleaseLockID
- cmp r5, #0x0
- beq _020235C2
- mov r0, #0x1
- pop {r3-r5, pc}
-_020235C2:
- mov r0, #0x0
- pop {r3-r5, pc}
- nop
-_020235C8: .word 0x00001302
-_020235CC: .word 0x00001202
-
- thumb_func_start FlashWriteChunk
-FlashWriteChunk: ; 0x020235D0
- push {r3-r5, lr}
- bl FlashWriteChunkInternal
- add r5, r0, #0x0
- add r4, sp, #0x0
-_020235DA:
- add r0, r5, #0x0
- add r1, r4, #0x0
- bl WaitFlashWrite
- cmp r0, #0x0
- beq _020235DA
- ldr r0, [sp, #0x0]
- pop {r3-r5, pc}
- .balign 4
-
- thumb_func_start FlashLoadChunk
-FlashLoadChunk: ; 0x020235EC
- push {r4-r7, lr}
- sub sp, #0x14
- add r5, r0, #0x0
- add r6, r1, #0x0
- add r7, r2, #0x0
- bl OS_GetLockID
- add r4, r0, #0x0
- mov r0, #0x2
- mvn r0, r0
- cmp r4, r0
- bne _02023608
- bl ErrorHandling
-_02023608:
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl CARD_LockBackup
- mov r3, #0x0
- str r3, [sp, #0x0]
- mov r1, #0x1
- str r1, [sp, #0x4]
- mov r0, #0x6 ; CARD_REQ_READ_BACKUP
- str r0, [sp, #0x8]
- str r1, [sp, #0xc]
- add r0, r5, #0x0
- add r1, r6, #0x0
- add r2, r7, #0x0
- str r3, [sp, #0x10]
- bl CARDi_RequestStreamCommand
- bl CARD_WaitBackupAsync
- add r5, r0, #0x0
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl CARD_UnlockBackup
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl OS_ReleaseLockID
- cmp r5, #0x0
- bne _02023652
- ldr r0, _02023658 ; =UNK_021C59C8
- ldr r0, [r0, #0x0]
- bl FreeToHeap
- mov r0, #0x1
- bl FUN_02089D90
-_02023652:
- add r0, r5, #0x0
- add sp, #0x14
- pop {r4-r7, pc}
- .balign 4
-_02023658: .word UNK_021C59C8
-
- thumb_func_start FlashWriteCommandCallback
-FlashWriteCommandCallback: ; 0x0202365C
- ldr r0, _02023664 ; =UNK_021C59C8
- mov r1, #0x1
- str r1, [r0, #0x4]
- bx lr
- .balign 4
-_02023664: .word UNK_021C59C8
-
- thumb_func_start FlashWriteChunkInternal
-FlashWriteChunkInternal: ; 0x02023668
- push {r3-r7, lr}
- sub sp, #0x18
- add r5, r0, #0x0
- add r6, r1, #0x0
- add r7, r2, #0x0
- bl OS_GetLockID
- add r4, r0, #0x0
- mov r0, #0x2
- mvn r0, r0
- cmp r4, r0
- bne _02023684
- bl ErrorHandling
-_02023684:
- lsl r0, r4, #0x10
- lsr r0, r0, #0x10
- bl CARD_LockBackup
- mov r0, #0x0
- str r0, [sp, #0x0]
- str r0, [sp, #0x4]
- mov r1, #0x6 ; CARD_REQ_READ_BACKUP
- str r1, [sp, #0x8]
- mov r1, #0x1
- str r1, [sp, #0xc]
- add r1, sp, #0x14
- mov r2, #0x4
- add r3, r0, #0x0
- str r0, [sp, #0x10]
- bl CARDi_RequestStreamCommand
- cmp r0, #0x0
- bne _020236B2
- add r0, r4, #0x0
- mov r1, #0x1
- bl SaveErrorHandling
-_020236B2:
- ldr r0, _020236DC ; =UNK_021C59C8
- mov r1, #0x0
- str r1, [r0, #0x4]
- str r1, [sp, #0x0]
- mov r0, #0x1
- str r0, [sp, #0x4]
- mov r0, #0x7 ; CARD_REQ_WRITE_BACKUP
- str r0, [sp, #0x8]
- mov r0, #0xa
- str r0, [sp, #0xc]
- mov r0, #0x2
- str r0, [sp, #0x10]
- ldr r3, _020236E0 ; =FlashWriteCommandCallback
- add r0, r6, #0x0
- add r1, r5, #0x0
- add r2, r7, #0x0
- bl CARDi_RequestStreamCommand
- add r0, r4, #0x0
- add sp, #0x18
- pop {r3-r7, pc}
- .balign 4
-_020236DC: .word UNK_021C59C8
-_020236E0: .word FlashWriteCommandCallback
-
- thumb_func_start WaitFlashWrite
-WaitFlashWrite: ; 0x020236E4
- push {r3-r5, lr}
- add r5, r0, #0x0
- ldr r0, _0202373C ; =UNK_021C59C8
- add r4, r1, #0x0
- ldr r0, [r0, #0x4]
- cmp r0, #0x1
- bne _02023738
- lsl r0, r5, #0x10
- lsr r0, r0, #0x10
- bl CARD_UnlockBackup
- lsl r0, r5, #0x10
- lsr r0, r0, #0x10
- bl OS_ReleaseLockID
- bl CARD_GetResultCode
- cmp r0, #0x0
- beq _02023714
- cmp r0, #0x4
- beq _0202371E
- cmp r0, #0x6
- beq _02023728
- b _0202371A
-_02023714:
- mov r0, #0x1
- str r0, [r4, #0x0]
- b _02023734
-_0202371A:
- bl ErrorHandling
-_0202371E:
- mov r1, #0x0
- add r0, r5, #0x0
- str r1, [r4, #0x0]
- bl SaveErrorHandling
-_02023728:
- mov r0, #0x0
- str r0, [r4, #0x0]
- add r0, r5, #0x0
- mov r1, #0x1
- bl SaveErrorHandling
-_02023734:
- mov r0, #0x1
- pop {r3-r5, pc}
-_02023738:
- mov r0, #0x0
- pop {r3-r5, pc}
- .balign 4
-_0202373C: .word UNK_021C59C8
-
- thumb_func_start SaveErrorHandling
-SaveErrorHandling: ; 0x02023740
- push {r3-r5, lr}
- add r5, r0, #0x0
- lsl r0, r5, #0x10
- lsr r0, r0, #0x10
- add r4, r1, #0x0
- bl CARD_UnlockBackup
- lsl r0, r5, #0x10
- lsr r0, r0, #0x10
- bl OS_ReleaseLockID
- ldr r0, _02023768 ; =UNK_021C59C8
- ldr r0, [r0, #0x0]
- bl FreeToHeap
- mov r0, #0x1
- add r1, r4, #0x0
- bl FUN_0208A0B8
- pop {r3-r5, pc}
- .balign 4
-_02023768: .word UNK_021C59C8
diff --git a/arm9/lib/include/CARD_backup.h b/arm9/lib/include/CARD_backup.h
index d2cbc231..7cb5f820 100644
--- a/arm9/lib/include/CARD_backup.h
+++ b/arm9/lib/include/CARD_backup.h
@@ -2,7 +2,41 @@
#define NITRO_CARD_BACKUP_H_
#include "nitro/types.h"
+#include "MI_dma.h"
+#include "CARD_common.h"
BOOL CARD_TryWaitBackupAsync(void);
+BOOL CARD_WaitBackupAsync(void);
+void CARD_CancelBackupAsync(void);
+void CARD_UnlockBackup(u16 lock_id);
+void CARD_LockBackup(u16 lock_id);
+BOOL CARD_IdentifyBackup(u16 lock_id);
+
+BOOL CARDi_RequestStreamCommand(
+ u32 src,
+ u32 dst,
+ u32 len,
+ MIDmaCallback callback,
+ void * arg,
+ BOOL is_async,
+ CARDRequest req_type,
+ int req_retry,
+ CARDRequestMode req_mode
+);
+
+static inline BOOL CARDi_ReadBackup(u32 src, void * dst, u32 len, MIDmaCallback callback, void * arg, BOOL is_async)
+{
+ return CARDi_RequestStreamCommand((u32)src, (u32)dst, len, callback, arg, is_async, CARD_REQ_READ_BACKUP, 1, CARD_REQUEST_MODE_RECV);
+}
+
+static inline BOOL CARDi_WriteBackup(u32 dst, void * src, u32 len, MIDmaCallback callback, void * arg, BOOL is_async)
+{
+ return CARDi_RequestStreamCommand((u32)src, (u32)dst, len, callback, arg, is_async, CARD_REQ_WRITE_BACKUP, CARD_RETRY_COUNT_MAX, CARD_REQUEST_MODE_SEND);
+}
+
+static inline BOOL CARDi_WriteAndVerifyBackup(u32 dst, void * src, u32 len, MIDmaCallback callback, void * arg, BOOL is_async)
+{
+ return CARDi_RequestStreamCommand((u32)src, (u32)dst, len, callback, arg, is_async, CARD_REQ_WRITE_BACKUP, CARD_RETRY_COUNT_MAX, CARD_REQUEST_MODE_SEND_VERIFY);
+}
#endif //NITRO_CARD_BACKUP_H_
diff --git a/arm9/lib/include/CARD_common.h b/arm9/lib/include/CARD_common.h
index 1396de12..9cedac4f 100644
--- a/arm9/lib/include/CARD_common.h
+++ b/arm9/lib/include/CARD_common.h
@@ -1,6 +1,51 @@
#ifndef NITRO_CARD_COMMON_H_
#define NITRO_CARD_COMMON_H_
+typedef enum
+{
+ CARD_RESULT_SUCCESS = 0,
+ CARD_RESULT_FAILURE,
+ CARD_RESULT_INVALID_PARAM,
+ CARD_RESULT_UNSUPPORTED,
+ CARD_RESULT_TIMEOUT,
+ CARD_RESULT_ERROR,
+ CARD_RESULT_NO_RESPONSE,
+ CARD_RESULT_CANCELED
+}
+CARDResult;
+
+typedef enum
+{
+ CARD_REQ_INIT = 0, /* initialize (setting from ARM9)*/
+ CARD_REQ_ACK, /* request done (acknowledge from ARM7)*/
+ CARD_REQ_IDENTIFY, /* CARD_IdentifyBackup*/
+ CARD_REQ_READ_ID, /* CARD_ReadRomID (TEG && ARM9)*/
+ CARD_REQ_READ_ROM, /* CARD_ReadRom (TEG && ARM9)*/
+ CARD_REQ_WRITE_ROM, /* (reserved)*/
+ CARD_REQ_READ_BACKUP, /* CARD_ReadBackup*/
+ CARD_REQ_WRITE_BACKUP, /* CARD_WriteBackup*/
+ CARD_REQ_PROGRAM_BACKUP, /* CARD_ProgramBackup*/
+ CARD_REQ_VERIFY_BACKUP, /* CARD_VerifyBackup*/
+ CARD_REQ_ERASE_PAGE_BACKUP, /* CARD_EraseBackupPage*/
+ CARD_REQ_ERASE_SECTOR_BACKUP, /* CARD_EraseBackupSector*/
+ CARD_REQ_ERASE_CHIP_BACKUP, /* CARD_EraseBackupChip*/
+ CARD_REQ_MAX
+}
+CARDRequest;
+
+typedef enum
+{
+ CARD_REQUEST_MODE_RECV, /* Data reception*/
+ CARD_REQUEST_MODE_SEND, /* Send data (Including single verify)*/
+ CARD_REQUEST_MODE_SEND_VERIFY, /* Send data + verify*/
+ CARD_REQUEST_MODE_SPECIAL /* special operations like sector deletion*/
+}
+CARDRequestMode;
+
+CARDResult CARD_GetResultCode(void);
+
+#define CARD_RETRY_COUNT_MAX 10
+
void CARD_Init(void);
#endif //NITRO_CARD_COMMON_H_
diff --git a/arm9/lib/include/MATH_crc.h b/arm9/lib/include/MATH_crc.h
index f15a2e32..4f06fa75 100644
--- a/arm9/lib/include/MATH_crc.h
+++ b/arm9/lib/include/MATH_crc.h
@@ -7,6 +7,8 @@ typedef u8 MATHCRC8Context;
typedef u16 MATHCRC16Context;
typedef u32 MATHCRC32Context;
+#define MATH_CRC16_CCITT_POLY 0x1021
+
struct MATHCRC8Table {
u8 table[256];
};
@@ -35,4 +37,9 @@ void MATHi_CRC16InitTable(struct MATHCRC16Table *table, u16 poly);
void MATHi_CRC8Update(const struct MATHCRC8Table *table, MATHCRC8Context *context, const void *input, u32 length);
void MATHi_CRC8InitTable(struct MATHCRC8Table *table, u8 poly);
+static inline void MATH_CRC16InitTable(struct MATHCRC16Table * table)
+{
+ MATHi_CRC16InitTable(table, MATH_CRC16_CCITT_POLY);
+}
+
#endif
diff --git a/arm9/lib/include/MI_memory.h b/arm9/lib/include/MI_memory.h
index d79e9dcb..981fdc81 100644
--- a/arm9/lib/include/MI_memory.h
+++ b/arm9/lib/include/MI_memory.h
@@ -5,6 +5,10 @@
void MI_CpuFill8(void *dest, u8 data, u32 size);
void MI_CpuCopy8(void const *src, void *dest, u32 size);
+void MIi_CpuClearFast(u32 data, void *destp, u32 size);
+static inline void MI_CpuClearFast(void *destp, u32 size) {
+ MIi_CpuClearFast(0, destp, size);
+}
static inline void MI_CpuClear8(void *dest, u32 size) {
MI_CpuFill8(dest, 0, size);
}
diff --git a/arm9/src/main.c b/arm9/src/main.c
index 3f967380..06673b65 100644
--- a/arm9/src/main.c
+++ b/arm9/src/main.c
@@ -219,8 +219,6 @@ THUMB_FUNC void FUN_02000EE8(void)
extern void FUN_0200E3A0(PMLCDTarget, int);
extern BOOL FUN_02032DAC(void);
-extern void FUN_020225F8(void);
-extern void FUN_0202287C(void);
// No Return
THUMB_FUNC void DoSoftReset(u32 parameter)
@@ -229,8 +227,7 @@ THUMB_FUNC void DoSoftReset(u32 parameter)
FUN_0200E3A0(PM_LCD_BOTTOM, 0x7FFF);
if (FUN_02032DAC())
{
- FUN_020225F8();
- FUN_0202287C();
+ FUN_0202287C(FUN_020225F8());
}
do
{
diff --git a/arm9/src/save.c b/arm9/src/save.c
new file mode 100644
index 00000000..700029c7
--- /dev/null
+++ b/arm9/src/save.c
@@ -0,0 +1,918 @@
+#include "global.h"
+#include "MI_memory.h"
+#include "save_block_2.h"
+#include "heap.h"
+#include "CARD_backup.h"
+
+#pragma thumb on
+
+// TODO: Migrate to headers
+
+// unk_02015EA0.s
+extern void FUN_02016444(u8 mask);
+extern void FUN_02016454(u8 mask);
+
+// unk_02089D90.s
+extern void FUN_02089D90(int);
+
+// unk_02089F24.s
+extern void FUN_0208A0B8(int, int);
+
+struct {
+ struct SaveBlock2 * ptr;
+ BOOL iswritten;
+} UNK_021C59C8;
+
+struct SaveBlock2 * SaveBlock2_new(void)
+{
+ struct SaveBlock2 * sav2 = AllocFromHeap(1, sizeof(struct SaveBlock2));
+ MI_CpuClearFast(sav2, sizeof(struct SaveBlock2));
+ UNK_021C59C8.ptr = sav2;
+ sav2->flashOkay = SaveDetectFlash();
+ sav2->unk_00004 = 0;
+ sav2->unk_00008 = 1;
+ sav2->largeSectorChanged = 1;
+ MATH_CRC16InitTable(&sav2->crcTable);
+ SaveBlock2_InitSubstructs(sav2->arrayHeaders);
+ FUN_02023160(sav2->saveSlotSpecs, sav2->arrayHeaders);
+ MI_CpuClearFast(sav2->unk_20218, 8);
+ switch (sav2->unk_00010 = FUN_02022AD8(sav2))
+ {
+ case 1:
+ sav2->largeSectorChanged = 0;
+ // fallthrough
+ case 2:
+ Sav2_LoadDynamicRegion(sav2);
+ sav2->unk_00004 = 1;
+ sav2->unk_00008 = 0;
+ break;
+ case 0:
+ case 3:
+ Sav2_InitDynamicRegion(sav2);
+ break;
+ }
+ return sav2;
+}
+
+struct SaveBlock2 * FUN_020225F8(void)
+{
+ GF_ASSERT(UNK_021C59C8.ptr != NULL);
+ return UNK_021C59C8.ptr;
+}
+
+void * SavArray_get(struct SaveBlock2 * sav2, int idx)
+{
+ GF_ASSERT(idx < 36);
+ return (void *)(sav2->dynamic_region + sav2->arrayHeaders[idx].offset);
+}
+
+void * FUN_02022634(struct SaveBlock2 * sav2, int idx)
+{
+ return SavArray_get(sav2, idx);
+}
+
+// Sets bits at 0x021C491
+// Clears bits at 0x021C491
+
+BOOL FUN_0202263C(struct SaveBlock2 * sav2)
+{
+ u8 * r6 = AllocFromHeapAtEnd(3, 0x1000);
+ FUN_02016444(1);
+ FlashClobberChunkFooter(sav2, 0, (u32)(sav2->unk_20220[0] == 0 ? 1 : 0));
+ FlashClobberChunkFooter(sav2, 1, (u32)(sav2->unk_20220[1] == 0 ? 1 : 0));
+ FlashClobberChunkFooter(sav2, 0, (u32)(sav2->unk_20220[0]));
+ FlashClobberChunkFooter(sav2, 1, (u32)(sav2->unk_20220[1]));
+ MIi_CpuClearFast(-1u, r6, 0x1000);
+ for (int i = 0; i < 64; i++)
+ {
+ FlashWriteChunk((u32)(0x1000 * i), r6, 0x1000);
+ FlashWriteChunk((u32)(0x1000 * (i + 0x40)), r6, 0x1000);
+ }
+ FreeToHeap(r6);
+ Sav2_InitDynamicRegion(sav2);
+ sav2->unk_00004 = 0;
+ FUN_02016454(1);
+ return TRUE;
+}
+
+BOOL FUN_020226FC(struct SaveBlock2 * sav2)
+{
+ if (sav2->flashOkay == 0)
+ return FALSE;
+ if (Sav2_LoadDynamicRegion(sav2))
+ {
+ sav2->unk_00004 = 1;
+ sav2->unk_00008 = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int FUN_02022720(struct SaveBlock2 * sav2)
+{
+ if (sav2->flashOkay == 0)
+ return 3;
+ if (sav2->unk_00008)
+ {
+ FUN_02016444(1);
+ FlashClobberChunkFooter(sav2, 0, (u32)(sav2->unk_20220[0] == 0 ? 1 : 0));
+ FlashClobberChunkFooter(sav2, 1, (u32)(sav2->unk_20220[1] == 0 ? 1 : 0));
+ FlashClobberChunkFooter(sav2, 0, (u32)(sav2->unk_20220[0]));
+ FlashClobberChunkFooter(sav2, 1, (u32)(sav2->unk_20220[1]));
+ FUN_02016454(1);
+ }
+ int ret = FUN_02023044(sav2);
+ if (ret == 2)
+ {
+ sav2->unk_00004 = 1;
+ sav2->unk_00008 = 0;
+ }
+ return ret;
+}
+
+void FUN_020227A0(struct SaveBlock2 * sav2, int a1)
+{
+ GF_ASSERT(a1 < 2);
+ GF_ASSERT(sav2->unk_00008 == 0);
+ GF_ASSERT(sav2->unk_00004 == 1);
+ FUN_02022840(sav2, a1);
+ int res;
+ do
+ {
+ res = FUN_02022854(sav2);
+ } while (res == 0 || res == 1);
+}
+
+void Sav2_InitDynamicRegion(struct SaveBlock2 * sav2)
+{
+ sav2->unk_00008 = 1;
+ sav2->largeSectorChanged = 1;
+ Sav2_InitDynamicRegion_Internal(sav2->dynamic_region, sav2->arrayHeaders);
+}
+
+int FUN_020227FC(struct SaveBlock2 * sav2)
+{
+ return sav2->flashOkay;
+}
+
+int FUN_02022800(struct SaveBlock2 * sav2)
+{
+ return sav2->unk_00010;
+}
+
+int FUN_02022804(struct SaveBlock2 * sav2)
+{
+ return sav2->unk_00004;
+}
+
+int FUN_02022808(struct SaveBlock2 * sav2)
+{
+ return sav2->unk_00008;
+}
+
+BOOL FUN_0202280C(struct SaveBlock2 * sav2)
+{
+ return (FUN_02022808(sav2) != 0 && FUN_02022804(sav2) != 0);
+}
+
+int SaveGetDirtyBit(struct SaveBlock2 * sav2)
+{
+ return sav2->largeSectorChanged;
+}
+
+void SaveSetDirtyBit(void)
+{
+ UNK_021C59C8.ptr->largeSectorChanged = 1;
+}
+
+void FUN_02022840(struct SaveBlock2 * sav2, int a1)
+{
+ FUN_02022DFC(sav2, &sav2->unk_2047C, a1);
+}
+
+int FUN_02022854(struct SaveBlock2 * sav2)
+{
+ int r4 = FUN_02022E78(sav2, &sav2->unk_2047C);
+ if (r4 != 0 && r4 != 1)
+ {
+ FUN_02022F80(sav2, &sav2->unk_2047C, r4);
+ }
+ return r4;
+}
+
+void FUN_0202287C(struct SaveBlock2 * sav2)
+{
+ FUN_02022FF0(sav2, &sav2->unk_2047C);
+}
+
+void FUN_0202288C(struct UnkStruct_0202288C * header)
+{
+ header->unk_0 = 0;
+ header->offset = 0;
+ header->size = 0;
+}
+
+u16 FUN_02022898(struct SaveBlock2 * sav2, void * data, u32 size)
+{
+ return MATH_CalcCRC16CCITT(&sav2->crcTable, data, size - 20);
+}
+
+u32 GetChunkOffsetFromCurrentSaveSlot(u32 slot, struct SaveBlock2_Sub_20464 * header)
+{
+ u32 offset;
+ if (slot == 0)
+ offset = 0;
+ else
+ offset = 0x40000;
+ return offset + header->offset;
+}
+
+struct SaveChunkFooter * FUN_020228B8(struct SaveBlock2 * sav2, u8 * offset, int idx)
+{
+ u8 * r4;
+ struct SaveBlock2_Sub_20464 * sub20464;
+
+ sub20464 = &sav2->saveSlotSpecs[idx];
+ r4 = offset + sub20464->offset;
+ GF_ASSERT(sub20464->size != 0);
+ return (struct SaveChunkFooter *)(r4 + sub20464->size - 20);
+}
+
+BOOL FUN_020228E0(struct SaveBlock2 * sav2, void * data, int idx)
+{
+ struct SaveChunkFooter * r4;
+ struct SaveBlock2_Sub_20464 * sub20464;
+
+ sub20464 = &sav2->saveSlotSpecs[idx];
+ r4 = FUN_020228B8(sav2, data, idx);
+ u32 size = sub20464->size;
+ u32 offset = sub20464->offset;
+ if (r4->size != size)
+ return FALSE;
+ if (r4->magic != 0x20060623)
+ return FALSE;
+ if (r4->unk_10 != idx)
+ return FALSE;
+ return r4->crc == FUN_02022898(sav2, (u8 *)data + offset, size);
+}
+
+void FUN_0202293C(struct UnkStruct_0202288C * r5, struct SaveBlock2 * sav2, void * data, int idx)
+{
+ struct SaveChunkFooter * r4;
+ r4 = FUN_020228B8(sav2, data, idx);
+ r5->unk_0 = FUN_020228E0(sav2, data, idx);
+ r5->offset = r4->unk_0;
+ r5->size = r4->offset;
+}
+
+void FUN_02022968(struct SaveBlock2 * sav2, void * data, int idx)
+{
+ struct SaveChunkFooter * r4;
+ struct SaveBlock2_Sub_20464 * sub20464;
+
+ sub20464 = &sav2->saveSlotSpecs[idx];
+ r4 = FUN_020228B8(sav2, data, idx);
+ data = (void *)((u8 *)data + sub20464->offset);
+ r4->unk_0 = sav2->unk_20214;
+ r4->offset = sav2->unk_20218[idx];
+ r4->size = sub20464->size;
+ r4->magic = 0x20060623;
+ r4->unk_10 = (u8)idx;
+ r4->crc = FUN_02022898(sav2, data, sub20464->size);
+}
+
+int FUN_020229B8(u32 x, u32 y)
+{
+ if (x == -1u && y == 0)
+ return -1;
+ if (x == 0 && y == -1u)
+ return 1;
+ if (x > y)
+ return 1;
+ return -(x < y);
+}
+
+int FUN_020229F0(struct UnkStruct_0202288C * r7, struct UnkStruct_0202288C * r6, u32 * r5, u32 * r4)
+{
+ int sp0 = FUN_020229B8(r7->offset, r6->offset);
+ int r0 = FUN_020229B8(r7->size, r6->size);
+ if (r7->unk_0 != 0 && r6->unk_0 != 0)
+ {
+ if (sp0 > 0)
+ {
+ GF_ASSERT(r0 > 0);
+ *r5 = 0;
+ *r4 = 1;
+ }
+ else if (sp0 < 0)
+ {
+ GF_ASSERT(r0 < 0);
+ *r5 = 1;
+ *r4 = 0;
+ }
+ else if (r0 > 0)
+ {
+ *r5 = 0;
+ *r4 = 1;
+ }
+ else if (r0 < 0)
+ {
+ *r5 = 1;
+ *r4 = 0;
+ }
+ else
+ {
+ *r5 = 0;
+ *r4 = 1;
+ }
+ return 2;
+ }
+ else if (r7->unk_0 != 0 && r6->unk_0 == 0)
+ {
+ *r5 = 0;
+ *r4 = 2;
+ return 1;
+ }
+ else if (r7->unk_0 == 0 && r6->unk_0 != 0)
+ {
+ *r5 = 1;
+ *r4 = 2;
+ return 1;
+ }
+ else
+ {
+ *r5 = 2;
+ *r4 = 2;
+ return 0;
+ }
+}
+
+void FUN_02022AA0(struct SaveBlock2 * sav2, struct UnkStruct_0202288C * a1, struct UnkStruct_0202288C * a2, u32 a3, u32 a4)
+{
+ sav2->unk_20214 = a1[a3].offset;
+ sav2->unk_20218[0] = a1[a3].size;
+ sav2->unk_20218[1] = a2[a4].size;
+ sav2->unk_20220[0] = (u8)a3;
+ sav2->unk_20220[1] = (u8)a4;
+}
+
+int FUN_02022AD8(struct SaveBlock2 * sav2)
+{
+ struct UnkStruct_0202288C sp2C[2];
+ struct UnkStruct_0202288C sp14[2];
+ u32 sp10;
+ u32 spC;
+ u32 sp8;
+ u32 sp4;
+ {
+ u8 *r6 = AllocFromHeapAtEnd(3, 0x20000);
+ u8 *r4 = AllocFromHeapAtEnd(3, 0x20000);
+ if (FlashLoadChunk(0, r6, 0x20000))
+ {
+ FUN_0202293C(&sp2C[0], sav2, r6, 0);
+ FUN_0202293C(&sp14[0], sav2, r6, 1);
+ }
+ else
+ {
+ FUN_0202288C(&sp2C[0]);
+ FUN_0202288C(&sp14[0]);
+ }
+ if (FlashLoadChunk(0x40000, r4, 0x20000))
+ {
+ FUN_0202293C(&sp2C[1], sav2, r4, 0);
+ FUN_0202293C(&sp14[1], sav2, r4, 1);
+ }
+ else
+ {
+ FUN_0202288C(&sp2C[1]);
+ FUN_0202288C(&sp14[1]);
+ }
+ FreeToHeap(r6);
+ FreeToHeap(r4);
+ }
+ {
+ int r4, r0;
+ r4 = FUN_020229F0(&sp2C[0], &sp2C[1], &sp10, &sp8);
+ r0 = FUN_020229F0(&sp14[0], &sp14[1], &spC, &sp4);
+ if (r4 == 0 && r0 == 0)
+ return 0;
+ else if (r4 == 0 || r0 == 0)
+ return 3;
+ else if (r4 == 2 && r0 == 2)
+ {
+ if (sp2C[sp10].offset == sp14[spC].offset)
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, spC);
+ return 1;
+ }
+ else
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp8, spC);
+ return 2;
+ }
+ }
+ else if (r4 == 1 && r0 == 2)
+ {
+ if (sp2C[sp10].offset == sp14[spC].offset)
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, spC);
+ return 2;
+ }
+ else if (sp2C[sp10].offset == sp14[sp4].offset)
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, sp4);
+ return 2;
+ }
+ else
+ {
+ return 3;
+ }
+ }
+ else if (r4 == 2 && r0 == 1)
+ {
+ if (sp2C[sp10].offset == sp14[spC].offset)
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, spC);
+ return 1;
+ }
+ else
+ {
+ FUN_02022AA0(sav2, sp2C, sp14, sp8, spC);
+ return 2;
+ }
+ }
+ else if (r4 == 1 && r0 == 1 && sp10 == spC)
+ {
+ GF_ASSERT(sp2C[sp10].offset == sp14[spC].offset);
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, spC);
+ return 1;
+ }
+ else
+ {
+ GF_ASSERT(sp2C[sp10].offset == sp14[spC].offset);
+ FUN_02022AA0(sav2, sp2C, sp14, sp10, spC);
+ return 2;
+ }
+ }
+}
+
+BOOL FlashLoadChunkIntoDynamicRegionFromHeader(u32 slot, struct SaveBlock2_Sub_20464 * header, u8 * dest)
+{
+ return FlashLoadChunk(GetChunkOffsetFromCurrentSaveSlot(slot, header), dest + header->offset, header->size);
+}
+
+BOOL Sav2_LoadDynamicRegion(struct SaveBlock2 * sav2)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ if (!FlashLoadChunkIntoDynamicRegionFromHeader(sav2->unk_20220[i], &sav2->saveSlotSpecs[i], sav2->dynamic_region)) return FALSE;
+ if (!FUN_020228E0(sav2, sav2->dynamic_region, i)) return FALSE;
+ }
+ return TRUE;
+}
+
+int FUN_02022D54(struct SaveBlock2 * sav2, int chunk, u8 slot)
+{
+ struct SaveBlock2_Sub_20464 * header = &sav2->saveSlotSpecs[chunk];
+ FUN_02022968(sav2, sav2->dynamic_region, chunk);
+ return FlashWriteChunkInternal(GetChunkOffsetFromCurrentSaveSlot(slot, header), sav2->dynamic_region + header->offset, header->size - 20);
+}
+
+int FUN_02022D94(struct SaveBlock2 * sav2, int chunk, u8 slot)
+{
+ struct SaveBlock2_Sub_20464 * header = &sav2->saveSlotSpecs[chunk];
+ u32 size = header->size;
+ return FlashWriteChunkInternal(GetChunkOffsetFromCurrentSaveSlot(slot, header) + size - 20, sav2->dynamic_region + header->offset + size - 20, 20);
+}
+
+int FUN_02022DC8(struct SaveBlock2 * sav2, int chunk, u8 slot)
+{
+ struct SaveBlock2_Sub_20464 * header = &sav2->saveSlotSpecs[chunk];
+ u32 size = header->size;
+ return FlashWriteChunkInternal(GetChunkOffsetFromCurrentSaveSlot(slot, header) + size - 12, sav2->dynamic_region + header->offset + size - 12, 8);
+}
+
+void FUN_02022DFC(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1, int a2)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ a1->unk_1C[i] = sav2->unk_20218[i];
+ sav2->unk_20218[i]++;
+ }
+ a1->unk_14 = 0;
+ a1->unk_0 = 0;
+ if (a2 == 2)
+ {
+ if (sav2->largeSectorChanged)
+ {
+ a1->unk_0 = 1;
+ a1->unk_18 = sav2->unk_20214;
+ sav2->unk_20214++;
+ a1->unk_4 = 0;
+ a1->unk_8 = 0;
+ a1->unk_C = 2;
+ }
+ else
+ {
+ a1->unk_4 = 0;
+ a1->unk_8 = 0;
+ a1->unk_C = 1;
+ }
+ }
+ else
+ {
+ a1->unk_4 = a2;
+ a1->unk_8 = a2;
+ a1->unk_C = a2 + 1;
+ }
+ FUN_02016444(1);
+}
+
+int FUN_02022E78(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1)
+{
+ BOOL sp0;
+ switch (a1->unk_14)
+ {
+ case 0:
+ a1->unk_10 = FUN_02022D54(sav2, a1->unk_8, (u8)(sav2->unk_20220[a1->unk_8] == 0));
+ a1->unk_14++;
+ // fallthrough
+ case 1:
+ if (!WaitFlashWrite(a1->unk_10, &sp0))
+ break;
+ if (sp0 == 0)
+ return 3;
+ a1->unk_14++;
+ // fallthrough
+ case 2:
+ a1->unk_10 = FUN_02022DC8(sav2, a1->unk_8, (u8)(sav2->unk_20220[a1->unk_8] == 0));
+ a1->unk_14++;
+ // fallthrough
+ case 3:
+ if (!WaitFlashWrite(a1->unk_10, &sp0))
+ break;
+ if (sp0 == 0)
+ return 3;
+ a1->unk_14++;
+ if (a1->unk_8 + 1 == a1->unk_C)
+ return 1;
+ // fallthrough
+ case 4:
+ a1->unk_10 = FUN_02022D94(sav2, a1->unk_8, (u8)(sav2->unk_20220[a1->unk_8] == 0));
+ a1->unk_14++;
+ // fallthrough
+ case 5:
+ if (!WaitFlashWrite(a1->unk_10, &sp0))
+ break;
+ if (sp0 == 0)
+ return 3;
+ a1->unk_8++;
+ if (a1->unk_8 == a1->unk_C)
+ return 2;
+ a1->unk_14 = 0;
+ break;
+ }
+ return 0;
+}
+
+void FUN_02022F80(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1, int a2)
+{
+ int i;
+ if (a2 == 3)
+ {
+ if (a1->unk_0)
+ {
+ sav2->unk_20214 = a1->unk_18;
+ }
+ for (i = 0; i < 2; i++)
+ {
+ sav2->unk_20218[i] = a1->unk_1C[i];
+ }
+ }
+ else
+ {
+ for (i = a1->unk_4; i < a1->unk_C; i++)
+ {
+ sav2->unk_20220[i] = (u8)(sav2->unk_20220[i] == 0);
+ }
+ sav2->unk_00004 = 1;
+ sav2->unk_00008 = 0;
+ sav2->largeSectorChanged = 0;
+ }
+ FUN_02016454(1);
+}
+
+void FUN_02022FF0(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1)
+{
+ if (a1->unk_0)
+ sav2->unk_20214 = a1->unk_18;
+ for (int i = 0; i < 2; i++)
+ {
+ sav2->unk_20218[i] = a1->unk_1C[i];
+ }
+ if (!CARD_TryWaitBackupAsync())
+ {
+ CARD_CancelBackupAsync();
+ CARD_UnlockBackup((u16)a1->unk_10);
+ OS_ReleaseLockID((u16)a1->unk_10);
+ }
+ FUN_02016454(1);
+}
+
+int FUN_02023044(struct SaveBlock2 * sav2)
+{
+ int r4;
+ struct UnkSavSub_2047C sp0;
+ FUN_02022DFC(sav2, &sp0, 2);
+ do
+ {
+ r4 = FUN_02022E78(sav2, &sp0);
+ } while (r4 == 0 || r4 == 1);
+ FUN_02022F80(sav2, &sp0, r4);
+ return r4;
+}
+
+int FlashClobberChunkFooter(struct SaveBlock2 * sav2, int x, u32 y)
+{
+ u8 sp0[20];
+ struct SaveBlock2_Sub_20464 * r5 = &sav2->saveSlotSpecs[x];
+ MI_CpuFill8(sp0, 0xFF, 20);
+ return FlashWriteChunk((u32)(GetChunkOffsetFromCurrentSaveSlot(y, r5) + r5->size - 20), sp0, 20);
+}
+
+u32 SavArray_sizeof(int idx)
+{
+ const struct SaveChunkHeader * sch = UNK_020EE700;
+ GF_ASSERT(idx < UNK_020EE6DC);
+ s32 ret = (s32)sch[idx].sizeFunc();
+ ret += (4 - (ret % 4));
+ return (u32)ret;
+}
+
+void SaveBlock2_InitSubstructs(struct SavArrayHeader * headers)
+{
+ const struct SaveChunkHeader * sch = UNK_020EE700;
+ s32 offset = 0;
+ GF_ASSERT(UNK_020EE6DC == 36);
+ for (int i = 0; i < UNK_020EE6DC; i++)
+ {
+ GF_ASSERT(i == sch[i].id);
+ headers[i].id = sch[i].id;
+ headers[i].size = SavArray_sizeof(i);
+ headers[i].offset = (u32)offset;
+ headers[i].field_C = 0;
+ headers[i].field_E = (u16)sch[i].linkedId;
+ offset += headers[i].size;
+ if (i == UNK_020EE6DC - 1 || sch[i].linkedId != sch[i + 1].linkedId)
+ offset += 20;
+ }
+ GF_ASSERT(offset <= 0x20000);
+}
+
+void FUN_02023160(struct SaveBlock2_Sub_20464 * spec, struct SavArrayHeader * headers)
+{
+ int i = 0;
+ int sp4 = 0;
+ u32 r12 = 0;
+ int j = 0;
+ for (i = 0; i < 2; i++)
+ {
+ spec[i].unk_0 = (u8)i;
+ spec[i].size = 0;
+ while (i == headers[j].field_E && j < UNK_020EE6DC)
+ {
+ spec[i].size += headers[j].size;
+ j++;
+ }
+ spec[i].size += 20;
+ spec[i].unk_1 = (u8)sp4;
+ spec[i].offset = r12;
+ spec[i].unk_2 = (u8)((spec[i].size + 0xFFF) / 0x1000);
+ sp4 += spec[i].unk_2;
+ r12 += spec[i].size;
+ }
+ GF_ASSERT(spec[1].unk_1 + spec[1].unk_2 == sp4);
+ GF_ASSERT(sp4 <= 32);
+}
+
+void Sav2_InitDynamicRegion_Internal(u8 * dynamic_region, struct SavArrayHeader * headers)
+{
+ const struct SaveChunkHeader * sch = UNK_020EE700;
+ MI_CpuClearFast(dynamic_region, 0x20000);
+ for (int i = 0; i < UNK_020EE6DC; i++)
+ {
+ u32 offset = headers[i].offset;
+ MI_CpuClearFast(dynamic_region + offset, headers[i].size);
+ sch[i].initFunc((void *)(dynamic_region + offset));
+ }
+}
+
+void CreateChunkFooter(struct SaveBlock2 * sav2, u8 * data, int id, u32 size)
+{
+ struct SavArrayFooter * footer = (struct SavArrayFooter *)(data + size);
+ footer->magic = 0x20060623;
+ footer->unk_4 = sav2->unk_204A4 + 1;
+ footer->unk_8 = size;
+ footer->unk_C = (u16)id;
+ footer->crc = MATH_CalcCRC16CCITT(&sav2->crcTable, data, size + 14);
+}
+
+BOOL ValidateChunk(struct SaveBlock2 * sav2, u8 * data, int id, u32 size)
+{
+ struct SavArrayFooter * footer = (struct SavArrayFooter *)(data + size);
+ if (footer->magic != 0x20060623)
+ return FALSE;
+ if (footer->unk_8 != size)
+ return FALSE;
+ if (footer->unk_C != id)
+ return FALSE;
+ return (footer->crc == MATH_CalcCRC16CCITT(&sav2->crcTable, data, size + 14));
+}
+
+u32 FUN_020232B4(u8 * data, u32 size)
+{
+ struct SavArrayFooter * footer = (struct SavArrayFooter *)(data + size);
+ return footer->unk_4;
+}
+
+int WriteSaveFileToFlash(struct SaveBlock2 * sav2, int idx, u8 * data)
+{
+ FUN_02016444(1);
+ GF_ASSERT(idx < UNK_020EE6D8);
+ const struct SaveChunkHeader * sch = &UNK_020EE6E0[idx];
+ GF_ASSERT(sch->id == idx);
+ u32 sp4 = sch->sizeFunc() + 16;
+ int sp0;
+ if (sav2->unk_204A0 == 1)
+ {
+ CreateChunkFooter(sav2, data, idx, sch->sizeFunc());
+ sp0 = FlashWriteChunk((u32)(sch->linkedId << 12), data, sp4);
+ GF_ASSERT(ValidateChunk(sav2, data, idx, sch->sizeFunc()) == 1);
+ CreateChunkFooter(sav2, data, idx, sch->sizeFunc());
+ sp0 |= FlashWriteChunk((u32)((sch->linkedId + 0x40) << 12), data, sp4);
+ GF_ASSERT(ValidateChunk(sav2, data, idx, sch->sizeFunc()) == 1);
+ }
+ else
+ {
+ CreateChunkFooter(sav2, data, idx, sch->sizeFunc());
+ sp0 = FlashWriteChunk((u32)((sch->linkedId + 0x40) << 12), data, sp4);
+ GF_ASSERT(ValidateChunk(sav2, data, idx, sch->sizeFunc()) == 1);
+ CreateChunkFooter(sav2, data, idx, sch->sizeFunc());
+ sp0 |= FlashWriteChunk((u32)(sch->linkedId << 12), data, sp4);
+ GF_ASSERT(ValidateChunk(sav2, data, idx, sch->sizeFunc()) == 1);
+ }
+ if (sp0 == 1)
+ {
+ FUN_02016454(1);
+ return 2;
+ }
+ FUN_02016454(1);
+ return 3;
+}
+
+u8 * ReadSaveFileFromFlash(struct SaveBlock2 * sav2, u32 heap_id, int idx, int * ret_p)
+{
+ GF_ASSERT(idx < UNK_020EE6D8);
+ const struct SaveChunkHeader * sch = &UNK_020EE6E0[idx];
+ GF_ASSERT(sch->id == idx);
+ u32 sp10 = sch->sizeFunc() + 16;
+ int spC;
+ u32 sp8;
+ int r7;
+ u32 sp4;
+ u8 * r6 = AllocFromHeap(heap_id, sp10);
+ FlashLoadChunk((u32)(sch->linkedId << 12), r6, sp10);
+ spC = ValidateChunk(sav2, r6, idx, sch->sizeFunc());
+ sp8 = FUN_020232B4(r6, sch->sizeFunc());
+ FlashLoadChunk((u32)((sch->linkedId + 0x40) << 12), r6, sp10);
+ r7 = ValidateChunk(sav2, r6, idx, sch->sizeFunc());
+ sp4 = FUN_020232B4(r6, sch->sizeFunc());
+ *ret_p = 1;
+ if (spC == 1 && r7 == 0)
+ {
+ sav2->unk_204A0 = 0;
+ sav2->unk_204A4 = sp8;
+ FlashLoadChunk((u32)(sch->linkedId << 12), r6, sp10);
+ return r6;
+ }
+ if (spC == 0 && r7 == 1)
+ {
+ sav2->unk_204A0 = 1;
+ sav2->unk_204A4 = sp4;
+ FlashLoadChunk((u32)((sch->linkedId + 0x40) << 12), r6, sp10);
+ return r6;
+ }
+ if (spC == 1 && r7 == 1)
+ {
+ if (FUN_020229B8(sp8, sp4) != -1)
+ {
+ sav2->unk_204A0 = 0;
+ sav2->unk_204A4 = sp8;
+ FlashLoadChunk((u32)(sch->linkedId << 12), r6, sp10);
+ return r6;
+ }
+ sav2->unk_204A0 = 1;
+ sav2->unk_204A4 = sp4;
+ FlashLoadChunk((u32)((sch->linkedId + 0x40) << 12), r6, sp10);
+ return r6;
+ }
+ *ret_p = 2;
+ sav2->unk_204A0 = 0;
+ sav2->unk_204A4 = 0;
+ return r6;
+}
+
+BOOL SaveDetectFlash(void)
+{
+ int lock = OS_GetLockID();
+ GF_ASSERT(lock != -3);
+ CARD_LockBackup((u16)lock);
+ u16 flash_type;
+ if (CARD_IdentifyBackup(0x1302))
+ flash_type = 0x1302;
+ else if (CARD_IdentifyBackup(0x1202))
+ flash_type = 0x1202;
+ else
+ flash_type = 0;
+ CARD_UnlockBackup((u16)lock);
+ OS_ReleaseLockID((u16)lock);
+ return flash_type != 0;
+}
+
+int FlashWriteChunk(u32 offset, u8 * data, u32 size)
+{
+ int ret;
+ int id = FlashWriteChunkInternal(offset, data, size);
+ while (!WaitFlashWrite(id, &ret))
+ ;
+ return ret;
+}
+
+BOOL FlashLoadChunk(u32 src, void * dest, u32 size)
+{
+ int lock = OS_GetLockID();
+ GF_ASSERT(lock != -3);
+ CARD_LockBackup((u16)lock);
+ CARDi_ReadBackup(src, dest, size, NULL, NULL, TRUE);
+ BOOL r5 = CARD_WaitBackupAsync();
+ CARD_UnlockBackup((u16)lock);
+ OS_ReleaseLockID((u16)lock);
+ if (!r5)
+ {
+ FreeToHeap(UNK_021C59C8.ptr);
+ FUN_02089D90(1);
+ }
+ return r5;
+}
+
+void FlashWriteCommandCallback(void * arg)
+{
+#pragma unused(arg)
+ UNK_021C59C8.iswritten = TRUE;
+}
+
+int FlashWriteChunkInternal(u32 dest, void * src, u32 size)
+{
+ int lock = OS_GetLockID();
+ GF_ASSERT(lock != -3);
+ CARD_LockBackup((u16)lock);
+ int sp14;
+ if (!CARDi_ReadBackup(0, &sp14, 4, NULL, NULL, FALSE))
+ SaveErrorHandling(lock, 1);
+ UNK_021C59C8.iswritten = FALSE;
+ CARDi_WriteAndVerifyBackup(dest, src, size, FlashWriteCommandCallback, NULL, TRUE);
+ return lock;
+}
+
+BOOL WaitFlashWrite(int lock, BOOL * res)
+{
+ if (UNK_021C59C8.iswritten == TRUE)
+ {
+ CARD_UnlockBackup((u16)lock);
+ OS_ReleaseLockID((u16)lock);
+ switch (CARD_GetResultCode())
+ {
+ case CARD_RESULT_SUCCESS:
+ *res = TRUE;
+ break;
+ default:
+ GF_ASSERT(0);
+ case CARD_RESULT_TIMEOUT:
+ *res = FALSE;
+ SaveErrorHandling(lock, 0);
+ case CARD_RESULT_NO_RESPONSE:
+ *res = FALSE;
+ SaveErrorHandling(lock, 1);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void SaveErrorHandling(int lock, int errno)
+{
+ CARD_UnlockBackup((u16)lock);
+ OS_ReleaseLockID((u16)lock);
+ FreeToHeap(UNK_021C59C8.ptr);
+ FUN_0208A0B8(1, errno);
+}
diff --git a/arm9/src/save_arrays.c b/arm9/src/save_arrays.c
new file mode 100644
index 00000000..abd09b1c
--- /dev/null
+++ b/arm9/src/save_arrays.c
@@ -0,0 +1,120 @@
+#include "global.h"
+#include "bag.h"
+#include "player_data.h"
+#include "save_block_2.h"
+#include "party.h"
+#include "event_data.h"
+
+extern u32 FUN_0202B034(void);
+extern u32 FUN_0202AC20(void);
+extern u32 FUN_0202376C(void);
+extern u32 FUN_0204BE14(void);
+extern u32 FUN_02034D7C(void);
+extern u32 FUN_02023D64(void);
+extern u32 FUN_02023C40(void);
+extern u32 FUN_020254B8(void);
+extern u32 FUN_02024E64(void);
+extern u32 FUN_02034D80(void);
+extern u32 FUN_02025954(void);
+extern u32 FUN_02023AC8(void);
+extern u32 FUN_02026FD8(void);
+extern u32 FUN_02025844(void);
+extern u32 FUN_02028054(void);
+extern u32 FUN_020286F8(void);
+extern u32 FUN_02028980(void);
+extern u32 FUN_02029A84(void);
+extern u32 FUN_02029FB0(void);
+extern u32 FUN_02029C58(void);
+extern u32 FUN_02029EC4(void);
+extern u32 FUN_0202A89C(void);
+extern u32 FUN_0202A8F4(void);
+extern u32 FUN_0202A924(void);
+extern u32 FUN_0202ABC8(void);
+extern u32 FUN_0202B374(void);
+extern u32 FUN_0202B8B0(void);
+extern u32 FUN_020281E0(void);
+extern u32 FUN_02029AE0(void);
+extern u32 FUN_0202BE98(void);
+extern u32 FUN_0202C0E0(void);
+extern u32 FUN_02013B28(void);
+extern u32 PCStorage_sizeof(void);
+extern void FUN_0202B03C(void *);
+extern void FUN_0202AC28(void *);
+extern void FUN_02023770(void *);
+extern void FUN_0204BE18(void *);
+extern void FUN_02034D98(void *);
+extern void FUN_02024378(void *);
+extern void FUN_02023C48(void *);
+extern void FUN_020254CC(void *);
+extern void FUN_02024E6C(void *);
+extern void FUN_02034D88(void *);
+extern void FUN_0202597C(void *);
+extern void FUN_02023AD8(void *);
+extern void FUN_02026F60(void *);
+extern void FUN_0202584C(void *);
+extern void FUN_0202805C(void *);
+extern void FUN_02028724(void *);
+extern void FUN_02028994(void *);
+extern void FUN_02029A8C(void *);
+extern void FUN_02029FB8(void *);
+extern void FUN_02029C60(void *);
+extern void FUN_02029ECC(void *);
+extern void FUN_0202A8A4(void *);
+extern void FUN_0202A8F8(void *);
+extern void FUN_0202A92C(void *);
+extern void FUN_0202ABCC(void *);
+extern void FUN_0202B37C(void *);
+extern void FUN_0202B8B8(void *);
+extern void FUN_020281E8(void *);
+extern void FUN_02029AE8(void *);
+extern void FUN_0202BEA0(void *);
+extern void FUN_0202C0E4(void *);
+extern void FUN_02013B2C(void *);
+extern void PCStorage_init(void *);
+
+const struct SaveChunkHeader UNK_020EE6E0[] = {
+ { 0, 32, (SAVSIZEFN)FUN_0202B034, (SAVINITFN)FUN_0202B03C },
+ { 1, 35, (SAVSIZEFN)FUN_0202AC20, (SAVINITFN)FUN_0202AC28 }
+};
+
+const struct SaveChunkHeader UNK_020EE700[] = {
+ { 0, 0, (SAVSIZEFN)FUN_0202376C, (SAVINITFN)FUN_02023770 },
+ { 1, 0, (SAVSIZEFN)Sav2_PlayerData_sizeof, (SAVINITFN)Sav2_PlayerData_init },
+ { 2, 0, (SAVSIZEFN)SavArray_Party_sizeof, (SAVINITFN)SavArray_Party_init },
+ { 3, 0, (SAVSIZEFN)Sav2_Bag_sizeof, (SAVINITFN)Sav2_Bag_init },
+ { 4, 0, (SAVSIZEFN)SavArray_Flags_sizeof, (SAVINITFN)SavArray_Flags_init },
+ { 5, 0, (SAVSIZEFN)FUN_0204BE14, (SAVINITFN)FUN_0204BE18 },
+ { 6, 0, (SAVSIZEFN)FUN_02034D7C, (SAVINITFN)FUN_02034D98 },
+ { 7, 0, (SAVSIZEFN)FUN_02023D64, (SAVINITFN)FUN_02024378 },
+ { 8, 0, (SAVSIZEFN)FUN_02023C40, (SAVINITFN)FUN_02023C48 },
+ { 9, 0, (SAVSIZEFN)FUN_020254B8, (SAVINITFN)FUN_020254CC },
+ { 10, 0, (SAVSIZEFN)FUN_02024E64, (SAVINITFN)FUN_02024E6C },
+ { 11, 0, (SAVSIZEFN)FUN_02034D80, (SAVINITFN)FUN_02034D88 },
+ { 12, 0, (SAVSIZEFN)FUN_02025954, (SAVINITFN)FUN_0202597C },
+ { 13, 0, (SAVSIZEFN)FUN_02023AC8, (SAVINITFN)FUN_02023AD8 },
+ { 14, 0, (SAVSIZEFN)FUN_02026FD8, (SAVINITFN)FUN_02026F60 },
+ { 15, 0, (SAVSIZEFN)FUN_02025844, (SAVINITFN)FUN_0202584C },
+ { 16, 0, (SAVSIZEFN)FUN_02028054, (SAVINITFN)FUN_0202805C },
+ { 17, 0, (SAVSIZEFN)FUN_020286F8, (SAVINITFN)FUN_02028724 },
+ { 18, 0, (SAVSIZEFN)FUN_02028980, (SAVINITFN)FUN_02028994 },
+ { 19, 0, (SAVSIZEFN)FUN_02029A84, (SAVINITFN)FUN_02029A8C },
+ { 20, 0, (SAVSIZEFN)FUN_02029FB0, (SAVINITFN)FUN_02029FB8 },
+ { 21, 0, (SAVSIZEFN)FUN_02029C58, (SAVINITFN)FUN_02029C60 },
+ { 22, 0, (SAVSIZEFN)FUN_02029EC4, (SAVINITFN)FUN_02029ECC },
+ { 23, 0, (SAVSIZEFN)FUN_0202A89C, (SAVINITFN)FUN_0202A8A4 },
+ { 24, 0, (SAVSIZEFN)FUN_0202A8F4, (SAVINITFN)FUN_0202A8F8 },
+ { 25, 0, (SAVSIZEFN)FUN_0202A924, (SAVINITFN)FUN_0202A92C },
+ { 26, 0, (SAVSIZEFN)FUN_0202ABC8, (SAVINITFN)FUN_0202ABCC },
+ { 27, 0, (SAVSIZEFN)FUN_0202B374, (SAVINITFN)FUN_0202B37C },
+ { 28, 0, (SAVSIZEFN)FUN_0202B8B0, (SAVINITFN)FUN_0202B8B8 },
+ { 29, 0, (SAVSIZEFN)FUN_020281E0, (SAVINITFN)FUN_020281E8 },
+ { 30, 0, (SAVSIZEFN)FUN_02029AE0, (SAVINITFN)FUN_02029AE8 },
+ { 31, 0, (SAVSIZEFN)FUN_0202AC20, (SAVINITFN)FUN_0202AC28 },
+ { 32, 0, (SAVSIZEFN)FUN_0202BE98, (SAVINITFN)FUN_0202BEA0 },
+ { 33, 0, (SAVSIZEFN)FUN_0202C0E0, (SAVINITFN)FUN_0202C0E4 },
+ { 34, 0, (SAVSIZEFN)FUN_02013B28, (SAVINITFN)FUN_02013B2C },
+ { 35, 1, (SAVSIZEFN)PCStorage_sizeof, (SAVINITFN)PCStorage_init },
+};
+
+const int UNK_020EE6D8 = NELEMS(UNK_020EE6E0);
+const int UNK_020EE6DC = NELEMS(UNK_020EE700);
diff --git a/include/player_data.h b/include/player_data.h
index bd9cd3b9..b4c7ce41 100644
--- a/include/player_data.h
+++ b/include/player_data.h
@@ -36,5 +36,7 @@ struct Options * Sav2_PlayerData_GetOptionsAddr(struct SaveBlock2 *);
struct String * PlayerProfile_GetPlayerName_NewString(struct PlayerData *, u32 heap_id);
u32 PlayerProfile_GetTrainerID(struct PlayerData *);
u32 PlayerProfile_GetTrainerGender(struct PlayerData *);
+u32 Sav2_PlayerData_sizeof(void);
+void Sav2_PlayerData_init(struct PlayerDataSav *);
#endif //POKEDIAMOND_PLAYER_DATA_H
diff --git a/include/save_block_2.h b/include/save_block_2.h
index 304469c7..f54e556e 100644
--- a/include/save_block_2.h
+++ b/include/save_block_2.h
@@ -5,7 +5,7 @@
struct SavArrayHeader
{
- u32 id;
+ int id;
u32 size;
u32 offset;
u16 field_C;
@@ -15,38 +15,144 @@ struct SavArrayHeader
struct SavArrayFooter
{
u32 magic;
- u32 next;
+ u32 unk_4;
+ u32 unk_8;
+ u16 unk_C;
+ u16 crc;
+};
+
+struct SaveChunkFooter
+{
+ u32 unk_0;
+ u32 offset;
u32 size;
- u16 id;
+ u32 magic;
+ u8 unk_10;
+ u8 padding_11;
u16 crc;
};
struct SaveBlock2_Sub_20464 {
- u32 unk_0;
+ u8 unk_0;
+ u8 unk_1;
+ u8 unk_2;
+ u8 padding_3;
+ u32 offset;
+ u32 size;
+};
+
+struct UnkSavSub_2047C
+{
+ int unk_0;
+ int unk_4;
+ int unk_8;
+ int unk_C;
+ int unk_10;
+ u32 unk_14;
+ u32 unk_18;
+ u32 unk_1C[2];
+};
+
+struct UnkStruct_0202288C
+{
+ BOOL unk_0;
u32 offset;
u32 size;
};
struct SaveBlock2
{
- /* 0x00000 */ int flashType;
+ /* 0x00000 */ BOOL flashOkay;
/* 0x00004 */ int unk_00004;
/* 0x00008 */ int unk_00008;
- /* 0x0000C */ int unk_0000C;
+ /* 0x0000C */ int largeSectorChanged;
/* 0x00010 */ int unk_00010;
/* 0x00014 */ struct MATHCRC16Table crcTable;
/* 0x00214 */ u8 dynamic_region[0x20000];
- /* 0x20214 */ int unk_20214;
- /* 0x20218 */ u8 unk_20218[8];
+ /* 0x20214 */ u32 unk_20214;
+ /* 0x20218 */ u32 unk_20218[2];
/* 0x20220 */ u8 unk_20220[2];
/* 0x20222 */ u8 filler_20222[2];
/* 0x20224 */ struct SavArrayHeader arrayHeaders[36];
/* 0x20464 */ struct SaveBlock2_Sub_20464 saveSlotSpecs[2];
- /* 0x2047C */ u8 filler_2047C[0x28];
- /* 0x204A4 */ int unk_204A4;
+ /* 0x2047C */ struct UnkSavSub_2047C unk_2047C;
+ /* 0x204A0 */ u32 unk_204A0;
+ /* 0x204A4 */ u32 unk_204A4;
// TODO: finish this struct
}; // size: 0x204A8
-void * SavArray_get(struct SaveBlock2 *, int);
+typedef u32 (*SAVSIZEFN)(void);
+typedef void (*SAVINITFN)(void *);
+
+struct SaveChunkHeader
+{
+ int id;
+ int linkedId;
+ SAVSIZEFN sizeFunc;
+ SAVINITFN initFunc;
+};
+
+extern const struct SaveChunkHeader UNK_020EE6E0[];
+extern const struct SaveChunkHeader UNK_020EE700[];
+extern const int UNK_020EE6DC;
+extern const int UNK_020EE6D8;
+
+struct SaveBlock2 * SaveBlock2_new(void);
+struct SaveBlock2 * FUN_020225F8(void);
+void * SavArray_get(struct SaveBlock2 * sav2, int idx);
+void * FUN_02022634(struct SaveBlock2 * sav2, int idx);
+BOOL FUN_0202263C(struct SaveBlock2 * sav2);
+BOOL FUN_020226FC(struct SaveBlock2 * sav2);
+int FUN_02022720(struct SaveBlock2 * sav2);
+void FUN_020227A0(struct SaveBlock2 * sav2, int a1);
+void Sav2_InitDynamicRegion(struct SaveBlock2 * sav2);
+int FUN_020227FC(struct SaveBlock2 * sav2);
+int FUN_02022800(struct SaveBlock2 * sav2);
+int FUN_02022804(struct SaveBlock2 * sav2);
+int FUN_02022808(struct SaveBlock2 * sav2);
+BOOL FUN_0202280C(struct SaveBlock2 * sav2);
+int SaveGetDirtyBit(struct SaveBlock2 * sav2);
+void SaveSetDirtyBit(void);
+void FUN_02022840(struct SaveBlock2 * sav2, int a1);
+int FUN_02022854(struct SaveBlock2 * sav2);
+void FUN_0202287C(struct SaveBlock2 * sav2);
+void FUN_0202288C(struct UnkStruct_0202288C * header);
+u16 FUN_02022898(struct SaveBlock2 * sav2, void * data, u32 size);
+u32 GetChunkOffsetFromCurrentSaveSlot(u32 slot, struct SaveBlock2_Sub_20464 * header);
+struct SaveChunkFooter * FUN_020228B8(struct SaveBlock2 * sav2, u8 * offset, int idx);
+BOOL FUN_020228E0(struct SaveBlock2 * sav2, void * data, int idx);
+void FUN_0202293C(struct UnkStruct_0202288C * r5, struct SaveBlock2 * sav2, void * data, int idx);
+void FUN_02022968(struct SaveBlock2 * sav2, void * data, int idx);
+int FUN_020229B8(u32 x, u32 y);
+int FUN_020229F0(struct UnkStruct_0202288C * r7, struct UnkStruct_0202288C * r6, u32 * r5, u32 * r4);
+void FUN_02022AA0(struct SaveBlock2 * sav2, struct UnkStruct_0202288C * a1, struct UnkStruct_0202288C * a2, u32 a3, u32 a4);
+int FUN_02022AD8(struct SaveBlock2 * sav2);
+BOOL FlashLoadChunkIntoDynamicRegionFromHeader(u32 slot, struct SaveBlock2_Sub_20464 * header, u8 * dest);
+BOOL Sav2_LoadDynamicRegion(struct SaveBlock2 * sav2);
+int FUN_02022D54(struct SaveBlock2 * sav2, int chunk, u8 slot);
+int FUN_02022D94(struct SaveBlock2 * sav2, int chunk, u8 slot);
+int FUN_02022DC8(struct SaveBlock2 * sav2, int chunk, u8 slot);
+void FUN_02022DFC(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1, int a2);
+int FUN_02022E78(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1);
+void FUN_02022F80(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1, int a2);
+void FUN_02022FF0(struct SaveBlock2 * sav2, struct UnkSavSub_2047C * a1);
+int FUN_02023044(struct SaveBlock2 * sav2);
+int FlashClobberChunkFooter(struct SaveBlock2 * sav2, int x, u32 y);
+u32 SavArray_sizeof(int idx);
+void SaveBlock2_InitSubstructs(struct SavArrayHeader * headers);
+void FUN_02023160(struct SaveBlock2_Sub_20464 * spec, struct SavArrayHeader * headers);
+void Sav2_InitDynamicRegion_Internal(u8 * dynamic_region, struct SavArrayHeader * headers);
+void CreateChunkFooter(struct SaveBlock2 * sav2, u8 * data, int id, u32 size);
+BOOL ValidateChunk(struct SaveBlock2 * sav2, u8 * data, int id, u32 size);
+u32 FUN_020232B4(u8 * data, u32 size);
+int WriteSaveFileToFlash(struct SaveBlock2 * sav2, int idx, u8 * data);
+u8 * ReadSaveFileFromFlash(struct SaveBlock2 * sav2, u32 heap_id, int idx, int * ret_p);
+BOOL SaveDetectFlash(void);
+int FlashWriteChunk(u32 offset, u8 * data, u32 size);
+BOOL FlashLoadChunk(u32 src, void * dest, u32 size);
+void FlashWriteCommandCallback(void * arg);
+int FlashWriteChunkInternal(u32 dest, void * src, u32 size);
+BOOL WaitFlashWrite(int lock, BOOL * res);
+void SaveErrorHandling(int lock, int errno);
#endif //POKEDIAMOND_SAVE_BLOCK_2_H