diff options
-rw-r--r-- | arm9/arm9.lsf | 1 | ||||
-rw-r--r-- | arm9/asm/save.s | 2478 | ||||
-rw-r--r-- | arm9/lib/include/CARD_backup.h | 34 | ||||
-rw-r--r-- | arm9/lib/include/CARD_common.h | 45 | ||||
-rw-r--r-- | arm9/lib/include/MATH_crc.h | 7 | ||||
-rw-r--r-- | arm9/lib/include/MI_memory.h | 4 | ||||
-rw-r--r-- | arm9/src/main.c | 5 | ||||
-rw-r--r-- | arm9/src/save.c | 918 | ||||
-rw-r--r-- | arm9/src/save_arrays.c | 120 | ||||
-rw-r--r-- | include/player_data.h | 2 | ||||
-rw-r--r-- | include/save_block_2.h | 128 |
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 |