mirror of
https://github.com/pret/pokeplatinum.git
synced 2026-03-21 17:55:13 -05:00
Match the rest of NNS/fnd
This commit is contained in:
parent
689360abd3
commit
afca00a398
|
|
@ -1,577 +0,0 @@
|
|||
.include "macros/function.inc"
|
||||
.include "include/expheap.inc"
|
||||
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
arm_func_start GetRegionOfMBlock
|
||||
GetRegionOfMBlock: ; 0x020A4F0C
|
||||
ldrh r2, [r1, #2]
|
||||
add r3, r1, #0x10
|
||||
mov r2, r2, asr #8
|
||||
and r2, r2, #0x7f
|
||||
mov r2, r2, lsl #0x10
|
||||
sub r2, r1, r2, lsr #16
|
||||
str r2, [r0, #0]
|
||||
ldr r1, [r1, #4]
|
||||
add r1, r1, r3
|
||||
str r1, [r0, #4]
|
||||
bx lr
|
||||
arm_func_end GetRegionOfMBlock
|
||||
|
||||
arm_func_start RemoveMBlock
|
||||
RemoveMBlock: ; 0x020A4F38
|
||||
ldr r2, [r1, #8]
|
||||
ldr r1, [r1, #0xc]
|
||||
cmp r2, #0
|
||||
strne r1, [r2, #0xc]
|
||||
streq r1, [r0]
|
||||
cmp r1, #0
|
||||
strne r2, [r1, #8]
|
||||
streq r2, [r0, #4]
|
||||
mov r0, r2
|
||||
bx lr
|
||||
arm_func_end RemoveMBlock
|
||||
|
||||
arm_func_start InsertMBlock
|
||||
InsertMBlock: ; 0x020A4F60
|
||||
str r2, [r1, #8]
|
||||
cmp r2, #0
|
||||
ldrne r3, [r2, #0xc]
|
||||
strne r1, [r2, #0xc]
|
||||
ldreq r3, [r0]
|
||||
streq r1, [r0]
|
||||
str r3, [r1, #0xc]
|
||||
cmp r3, #0
|
||||
strne r1, [r3, #8]
|
||||
streq r1, [r0, #4]
|
||||
mov r0, r1
|
||||
bx lr
|
||||
arm_func_end InsertMBlock
|
||||
|
||||
arm_func_start InitMBlock
|
||||
InitMBlock: ; 0x020A4F90
|
||||
ldr r3, [r0, #0]
|
||||
mov r2, #0
|
||||
strh r1, [r3]
|
||||
strh r2, [r3, #2]
|
||||
ldr r1, [r0, #4]
|
||||
add r0, r3, #0x10
|
||||
sub r0, r1, r0
|
||||
stmib r3, {r0, r2}
|
||||
mov r0, r3
|
||||
str r2, [r3, #0xc]
|
||||
bx lr
|
||||
arm_func_end InitMBlock
|
||||
|
||||
arm_func_start InitExpHeap
|
||||
InitExpHeap: ; 0x020A4FBC
|
||||
stmfd sp!, {r3, r4, lr}
|
||||
sub sp, sp, #0xc
|
||||
mov r3, r1
|
||||
mov r4, r0
|
||||
str r2, [sp]
|
||||
ldr r1, _020A5028 ; =0x45585048
|
||||
add r2, r4, #0x38
|
||||
bl NNSi_FndInitHeapHead
|
||||
mov r0, #0
|
||||
strh r0, [r4, #0x34]
|
||||
bic r0, r0, #1
|
||||
strh r0, [r4, #0x36]
|
||||
ldr r1, [r4, #0x18]
|
||||
add r0, sp, #4
|
||||
str r1, [sp, #4]
|
||||
ldr r2, [r4, #0x1c]
|
||||
ldr r1, _020A502C ; =0x00004652
|
||||
str r2, [sp, #8]
|
||||
bl InitMBlock
|
||||
str r0, [r4, #0x24]
|
||||
str r0, [r4, #0x28]
|
||||
mov r1, #0
|
||||
str r1, [r4, #0x2c]
|
||||
mov r0, r4
|
||||
str r1, [r4, #0x30]
|
||||
add sp, sp, #0xc
|
||||
ldmia sp!, {r3, r4, pc}
|
||||
; .align 2, 0
|
||||
_020A5028: .word 0x45585048
|
||||
_020A502C: .word 0x00004652
|
||||
arm_func_end InitExpHeap
|
||||
|
||||
arm_func_start AllocUsedBlockFromFreeBlock
|
||||
AllocUsedBlockFromFreeBlock: ; 0x020A5030
|
||||
stmfd sp!, {r4, r5, r6, r7, r8, lr}
|
||||
sub sp, sp, #0x18
|
||||
mov r7, r0
|
||||
add r0, sp, #0x10
|
||||
mov r8, r1
|
||||
mov r6, r2
|
||||
mov r4, r3
|
||||
bl GetRegionOfMBlock
|
||||
ldr r3, [sp, #0x14]
|
||||
sub r5, r6, #0x10
|
||||
add r2, r4, r6
|
||||
mov r0, r7
|
||||
mov r1, r8
|
||||
str r5, [sp, #0x14]
|
||||
str r3, [sp, #0xc]
|
||||
str r2, [sp, #8]
|
||||
bl RemoveMBlock
|
||||
ldr r2, [sp, #0x10]
|
||||
ldr r1, [sp, #0x14]
|
||||
mov r4, r0
|
||||
sub r0, r1, r2
|
||||
cmp r0, #0x14
|
||||
strlo r2, [sp, #0x14]
|
||||
blo _020A50B0
|
||||
ldr r1, _020A51A8 ; =0x00004652
|
||||
add r0, sp, #0x10
|
||||
bl InitMBlock
|
||||
mov r1, r0
|
||||
mov r0, r7
|
||||
mov r2, r4
|
||||
bl InsertMBlock
|
||||
mov r4, r0
|
||||
_020A50B0:
|
||||
ldr r1, [sp, #0xc]
|
||||
ldr r0, [sp, #8]
|
||||
sub r0, r1, r0
|
||||
cmp r0, #0x14
|
||||
strlo r1, [sp, #8]
|
||||
blo _020A50E4
|
||||
ldr r1, _020A51A8 ; =0x00004652
|
||||
add r0, sp, #8
|
||||
bl InitMBlock
|
||||
mov r1, r0
|
||||
mov r0, r7
|
||||
mov r2, r4
|
||||
bl InsertMBlock
|
||||
_020A50E4:
|
||||
ldr r0, [r7, #-4]
|
||||
ldr r1, [sp, #0x14]
|
||||
ldr r2, [sp, #8]
|
||||
and r0, r0, #0xff
|
||||
tst r0, #1
|
||||
sub r2, r2, r1
|
||||
beq _020A5108
|
||||
mov r0, #0
|
||||
bl MIi_CpuClear32
|
||||
_020A5108:
|
||||
ldr r2, [sp, #8]
|
||||
ldr r1, _020A51AC ; =0x00005544
|
||||
add r0, sp, #0
|
||||
str r5, [sp]
|
||||
str r2, [sp, #4]
|
||||
bl InitMBlock
|
||||
mov r1, r0
|
||||
ldrh r3, [r1, #2]
|
||||
ldrh r2, [sp, #0x30]
|
||||
add r0, r7, #8
|
||||
bic r3, r3, #0x8000
|
||||
strh r3, [r1, #2]
|
||||
ldrh r3, [r1, #2]
|
||||
mov r2, r2, lsl #0x1f
|
||||
orr r2, r3, r2, lsr #16
|
||||
strh r2, [r1, #2]
|
||||
ldrh r2, [r1, #2]
|
||||
ldr r3, [sp, #0x14]
|
||||
bic r2, r2, #0x7f00
|
||||
strh r2, [r1, #2]
|
||||
sub r2, r1, r3
|
||||
mov r2, r2, lsl #0x10
|
||||
mov r2, r2, lsr #0x10
|
||||
ldrh r3, [r1, #2]
|
||||
mov r2, r2, lsl #0x19
|
||||
orr r2, r3, r2, lsr #17
|
||||
strh r2, [r1, #2]
|
||||
ldrh r2, [r1, #2]
|
||||
ldrh r3, [r7, #0x10]
|
||||
bic r2, r2, #0xff
|
||||
strh r2, [r1, #2]
|
||||
ldrh r2, [r1, #2]
|
||||
and r3, r3, #0xff
|
||||
orr r2, r2, r3
|
||||
strh r2, [r1, #2]
|
||||
ldr r2, [r7, #0xc]
|
||||
bl InsertMBlock
|
||||
mov r0, r6
|
||||
add sp, sp, #0x18
|
||||
ldmia sp!, {r4, r5, r6, r7, r8, pc}
|
||||
; .align 2, 0
|
||||
_020A51A8: .word 0x00004652
|
||||
_020A51AC: .word 0x00005544
|
||||
arm_func_end AllocUsedBlockFromFreeBlock
|
||||
|
||||
arm_func_start AllocFromHead_dup1
|
||||
AllocFromHead_dup1: ; 0x020A51B0
|
||||
stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr}
|
||||
ldrh r4, [r0, #0x36]
|
||||
mov r3, r1
|
||||
ldr ip, [r0, #0x24]
|
||||
and r1, r4, #1
|
||||
mov r1, r1, lsl #0x10
|
||||
movs r1, r1, lsr #0x10
|
||||
mov r1, #0
|
||||
moveq r6, #1
|
||||
movne r6, #0
|
||||
mov r4, r1
|
||||
cmp ip, #0
|
||||
sub lr, r1, #1
|
||||
beq _020A5240
|
||||
sub r2, r2, #1
|
||||
mvn r5, r2
|
||||
_020A51F0:
|
||||
add r8, ip, #0x10
|
||||
add r7, r2, r8
|
||||
and sb, r5, r7
|
||||
sub r7, sb, r8
|
||||
ldr r8, [ip, #4]
|
||||
add r7, r3, r7
|
||||
cmp r8, r7
|
||||
blo _020A5234
|
||||
cmp lr, r8
|
||||
bls _020A5234
|
||||
mov r1, ip
|
||||
mov lr, r8
|
||||
mov r4, sb
|
||||
cmp r6, #0
|
||||
bne _020A5240
|
||||
cmp r8, r3
|
||||
beq _020A5240
|
||||
_020A5234:
|
||||
ldr ip, [ip, #0xc]
|
||||
cmp ip, #0
|
||||
bne _020A51F0
|
||||
_020A5240:
|
||||
cmp r1, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
mov r5, #0
|
||||
mov r2, r4
|
||||
add r0, r0, #0x24
|
||||
str r5, [sp]
|
||||
bl AllocUsedBlockFromFreeBlock
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
arm_func_end AllocFromHead_dup1
|
||||
|
||||
arm_func_start AllocFromTail_dup1
|
||||
AllocFromTail_dup1: ; 0x020A5264
|
||||
stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr}
|
||||
ldrh r4, [r0, #0x36]
|
||||
mov r3, r1
|
||||
ldr ip, [r0, #0x28]
|
||||
and r1, r4, #1
|
||||
mov r1, r1, lsl #0x10
|
||||
movs r1, r1, lsr #0x10
|
||||
mov r1, #0
|
||||
moveq r5, #1
|
||||
movne r5, #0
|
||||
mov r4, r1
|
||||
cmp ip, #0
|
||||
sub lr, r1, #1
|
||||
beq _020A52F0
|
||||
sub r2, r2, #1
|
||||
mvn r2, r2
|
||||
_020A52A4:
|
||||
ldr r8, [ip, #4]
|
||||
add sb, ip, #0x10
|
||||
add r6, r8, sb
|
||||
sub r6, r6, r3
|
||||
and r7, r2, r6
|
||||
subs r6, r7, sb
|
||||
bmi _020A52E4
|
||||
cmp lr, r8
|
||||
bls _020A52E4
|
||||
mov r1, ip
|
||||
mov lr, r8
|
||||
mov r4, r7
|
||||
cmp r5, #0
|
||||
bne _020A52F0
|
||||
cmp r8, r3
|
||||
beq _020A52F0
|
||||
_020A52E4:
|
||||
ldr ip, [ip, #8]
|
||||
cmp ip, #0
|
||||
bne _020A52A4
|
||||
_020A52F0:
|
||||
cmp r1, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
mov r5, #1
|
||||
mov r2, r4
|
||||
add r0, r0, #0x24
|
||||
str r5, [sp]
|
||||
bl AllocUsedBlockFromFreeBlock
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
arm_func_end AllocFromTail_dup1
|
||||
|
||||
arm_func_start RecycleRegion
|
||||
RecycleRegion: ; 0x020A5314
|
||||
stmfd sp!, {r4, r5, r6, lr}
|
||||
sub sp, sp, #8
|
||||
mov r5, r1
|
||||
ldr r2, [r5, #0]
|
||||
ldr r1, [r5, #4]
|
||||
mov r6, r0
|
||||
str r2, [sp]
|
||||
str r1, [sp, #4]
|
||||
ldr r1, [r6, #0]
|
||||
mov r4, #0
|
||||
cmp r1, #0
|
||||
beq _020A5388
|
||||
ldr r0, [r5, #0]
|
||||
_020A5348:
|
||||
cmp r1, r0
|
||||
movlo r4, r1
|
||||
blo _020A537C
|
||||
ldr r0, [r5, #4]
|
||||
cmp r1, r0
|
||||
bne _020A5388
|
||||
ldr r2, [r1, #4]
|
||||
add r0, r1, #0x10
|
||||
add r2, r2, r0
|
||||
mov r0, r6
|
||||
str r2, [sp, #4]
|
||||
bl RemoveMBlock
|
||||
b _020A5388
|
||||
_020A537C:
|
||||
ldr r1, [r1, #0xc]
|
||||
cmp r1, #0
|
||||
bne _020A5348
|
||||
_020A5388:
|
||||
cmp r4, #0
|
||||
beq _020A53BC
|
||||
ldr r2, [r4, #4]
|
||||
add r1, r4, #0x10
|
||||
ldr r0, [r5, #0]
|
||||
add r1, r2, r1
|
||||
cmp r1, r0
|
||||
bne _020A53BC
|
||||
mov r0, r6
|
||||
mov r1, r4
|
||||
str r4, [sp]
|
||||
bl RemoveMBlock
|
||||
mov r4, r0
|
||||
_020A53BC:
|
||||
ldr r1, [sp, #4]
|
||||
ldr r0, [sp]
|
||||
sub r0, r1, r0
|
||||
cmp r0, #0x10
|
||||
addlo sp, sp, #8
|
||||
movlo r0, #0
|
||||
ldmloia sp!, {r4, r5, r6, pc}
|
||||
ldr r1, _020A5400 ; =0x00004652
|
||||
add r0, sp, #0
|
||||
bl InitMBlock
|
||||
mov r1, r0
|
||||
mov r0, r6
|
||||
mov r2, r4
|
||||
bl InsertMBlock
|
||||
mov r0, #1
|
||||
add sp, sp, #8
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
; .align 2, 0
|
||||
_020A5400: .word 0x00004652
|
||||
arm_func_end RecycleRegion
|
||||
|
||||
arm_func_start NNS_FndCreateExpHeapEx
|
||||
NNS_FndCreateExpHeapEx: ; 0x020A5404
|
||||
stmfd sp!, {r3, lr}
|
||||
add r1, r1, r0
|
||||
add r0, r0, #3
|
||||
bic r1, r1, #3
|
||||
bic r0, r0, #3
|
||||
cmp r0, r1
|
||||
bhi _020A542C
|
||||
sub r3, r1, r0
|
||||
cmp r3, #0x4c
|
||||
bhs _020A5434
|
||||
_020A542C:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A5434:
|
||||
bl InitExpHeap
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndCreateExpHeapEx
|
||||
|
||||
arm_func_start NNS_FndDestroyExpHeap
|
||||
NNS_FndDestroyExpHeap: ; 0x020A543C
|
||||
ldr ip, _020A5444 ; =NNSi_FndFinalizeHeap
|
||||
bx ip
|
||||
; .align 2, 0
|
||||
_020A5444: .word NNSi_FndFinalizeHeap
|
||||
arm_func_end NNS_FndDestroyExpHeap
|
||||
|
||||
arm_func_start NNS_FndAllocFromExpHeapEx
|
||||
NNS_FndAllocFromExpHeapEx: ; 0x020A5448
|
||||
stmfd sp!, {r3, lr}
|
||||
cmp r1, #0
|
||||
moveq r1, #1
|
||||
add r1, r1, #3
|
||||
cmp r2, #0
|
||||
bic r1, r1, #3
|
||||
blt _020A546C
|
||||
bl AllocFromHead_dup1
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A546C:
|
||||
rsb r2, r2, #0
|
||||
bl AllocFromTail_dup1
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndAllocFromExpHeapEx
|
||||
|
||||
arm_func_start NNS_FndResizeForMBlockExpHeap
|
||||
NNS_FndResizeForMBlockExpHeap: ; 0x020A5478
|
||||
stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr}
|
||||
sub sp, sp, #0x10
|
||||
mov r4, r1
|
||||
mov sb, r2
|
||||
sub r8, r4, #0x10
|
||||
add r1, sb, #3
|
||||
ldr r7, [r8, #4]
|
||||
bic sb, r1, #3
|
||||
cmp sb, r7
|
||||
mov r5, r0
|
||||
addeq sp, sp, #0x10
|
||||
moveq r0, sb
|
||||
ldmeqia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
bls _020A5598
|
||||
ldr r6, [r5, #0x24]
|
||||
add r0, r8, #0x10
|
||||
cmp r6, #0
|
||||
add r0, r7, r0
|
||||
beq _020A54D4
|
||||
_020A54C4:
|
||||
cmp r6, r0
|
||||
ldrne r6, [r6, #0xc]
|
||||
cmpne r6, #0
|
||||
bne _020A54C4
|
||||
_020A54D4:
|
||||
cmp r6, #0
|
||||
beq _020A54F0
|
||||
ldr r0, [r6, #4]
|
||||
add r1, r7, #0x10
|
||||
add r0, r1, r0
|
||||
cmp sb, r0
|
||||
bls _020A54FC
|
||||
_020A54F0:
|
||||
add sp, sp, #0x10
|
||||
mov r0, #0
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
_020A54FC:
|
||||
add r0, sp, #8
|
||||
mov r1, r6
|
||||
bl GetRegionOfMBlock
|
||||
mov r1, r6
|
||||
add r0, r5, #0x24
|
||||
bl RemoveMBlock
|
||||
ldr r2, [sp, #0xc]
|
||||
add r3, sb, r4
|
||||
ldr r6, [sp, #8]
|
||||
sub r1, r2, r3
|
||||
str r3, [sp, #8]
|
||||
cmp r1, #0x10
|
||||
strlo r2, [sp, #8]
|
||||
mov r7, r0
|
||||
ldr r0, [sp, #8]
|
||||
sub r0, r0, r4
|
||||
str r0, [r8, #4]
|
||||
ldr r1, [sp, #0xc]
|
||||
ldr r0, [sp, #8]
|
||||
sub r0, r1, r0
|
||||
cmp r0, #0x10
|
||||
blo _020A5570
|
||||
ldr r1, _020A55D4 ; =0x00004652
|
||||
add r0, sp, #8
|
||||
bl InitMBlock
|
||||
mov r1, r0
|
||||
mov r2, r7
|
||||
add r0, r5, #0x24
|
||||
bl InsertMBlock
|
||||
_020A5570:
|
||||
ldr r0, [r5, #0x20]
|
||||
ldr r1, [sp, #8]
|
||||
and r0, r0, #0xff
|
||||
tst r0, #1
|
||||
sub r2, r1, r6
|
||||
beq _020A55C8
|
||||
mov r1, r6
|
||||
mov r0, #0
|
||||
bl MIi_CpuClear32
|
||||
b _020A55C8
|
||||
_020A5598:
|
||||
add r0, sb, r4
|
||||
str r0, [sp]
|
||||
ldr r1, [r8, #4]
|
||||
add r0, r8, #0x10
|
||||
add r0, r1, r0
|
||||
str r0, [sp, #4]
|
||||
add r1, sp, #0
|
||||
add r0, r5, #0x24
|
||||
str sb, [r8, #4]
|
||||
bl RecycleRegion
|
||||
cmp r0, #0
|
||||
streq r7, [r8, #4]
|
||||
_020A55C8:
|
||||
ldr r0, [r8, #4]
|
||||
add sp, sp, #0x10
|
||||
ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc}
|
||||
; .align 2, 0
|
||||
_020A55D4: .word 0x00004652
|
||||
arm_func_end NNS_FndResizeForMBlockExpHeap
|
||||
|
||||
arm_func_start NNS_FndFreeToExpHeap
|
||||
NNS_FndFreeToExpHeap: ; 0x020A55D8
|
||||
stmfd sp!, {r3, r4, r5, lr}
|
||||
sub sp, sp, #8
|
||||
sub r4, r1, #0x10
|
||||
mov r5, r0
|
||||
add r0, sp, #0
|
||||
mov r1, r4
|
||||
bl GetRegionOfMBlock
|
||||
mov r1, r4
|
||||
add r0, r5, #0x2c
|
||||
bl RemoveMBlock
|
||||
add r1, sp, #0
|
||||
add r0, r5, #0x24
|
||||
bl RecycleRegion
|
||||
add sp, sp, #8
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
arm_func_end NNS_FndFreeToExpHeap
|
||||
|
||||
arm_func_start NNS_FndGetTotalFreeSizeForExpHeap
|
||||
NNS_FndGetTotalFreeSizeForExpHeap: ; 0x020A5614
|
||||
ldr r2, [r0, #0x24]
|
||||
mov r0, #0
|
||||
cmp r2, #0
|
||||
bxeq lr
|
||||
_020A5624:
|
||||
ldr r1, [r2, #4]
|
||||
ldr r2, [r2, #0xc]
|
||||
add r0, r0, r1
|
||||
cmp r2, #0
|
||||
bne _020A5624
|
||||
bx lr
|
||||
arm_func_end NNS_FndGetTotalFreeSizeForExpHeap
|
||||
|
||||
arm_func_start NNS_FndSetGroupIDForExpHeap
|
||||
NNS_FndSetGroupIDForExpHeap: ; 0x020A563C
|
||||
ldrh r2, [r0, #0x34]
|
||||
strh r1, [r0, #0x34]
|
||||
mov r0, r2
|
||||
bx lr
|
||||
arm_func_end NNS_FndSetGroupIDForExpHeap
|
||||
|
||||
arm_func_start NNS_FndGetSizeForMBlockExpHeap
|
||||
NNS_FndGetSizeForMBlockExpHeap: ; 0x020A564C
|
||||
ldr r0, [r0, #-0xc]
|
||||
bx lr
|
||||
arm_func_end NNS_FndGetSizeForMBlockExpHeap
|
||||
|
||||
arm_func_start NNS_FndGetGroupIDForMBlockExpHeap
|
||||
NNS_FndGetGroupIDForMBlockExpHeap: ; 0x020A5654
|
||||
ldrh r0, [r0, #-0xe]
|
||||
and r0, r0, #0xff
|
||||
bx lr
|
||||
arm_func_end NNS_FndGetGroupIDForMBlockExpHeap
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
.include "macros/function.inc"
|
||||
.include "include/frameheap.inc"
|
||||
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
arm_func_start InitFrameHeap
|
||||
InitFrameHeap: ; 0x020A5660
|
||||
stmfd sp!, {r3, r4, lr}
|
||||
sub sp, sp, #4
|
||||
mov r3, r1
|
||||
mov r4, r0
|
||||
str r2, [sp]
|
||||
ldr r1, _020A56A4 ; =0x46524D48
|
||||
add r2, r4, #0x30
|
||||
bl NNSi_FndInitHeapHead
|
||||
ldr r0, [r4, #0x18]
|
||||
mov r1, #0
|
||||
str r0, [r4, #0x24]
|
||||
ldr r2, [r4, #0x1c]
|
||||
mov r0, r4
|
||||
str r2, [r4, #0x28]
|
||||
str r1, [r4, #0x2c]
|
||||
add sp, sp, #4
|
||||
ldmia sp!, {r3, r4, pc}
|
||||
; .align 2, 0
|
||||
_020A56A4: .word 0x46524D48
|
||||
arm_func_end InitFrameHeap
|
||||
|
||||
arm_func_start AllocFromHead_dup2
|
||||
AllocFromHead_dup2: ; 0x020A56A8
|
||||
stmfd sp!, {r4, r5, r6, lr}
|
||||
mov r4, r0
|
||||
ldr r3, [r4, #0]
|
||||
sub r0, r2, #1
|
||||
mvn r2, r0
|
||||
add r0, r0, r3
|
||||
and r5, r2, r0
|
||||
ldr r0, [r4, #4]
|
||||
add r6, r1, r5
|
||||
cmp r6, r0
|
||||
movhi r0, #0
|
||||
ldmhiia sp!, {r4, r5, r6, pc}
|
||||
ldr r0, [r4, #-4]
|
||||
sub r2, r6, r3
|
||||
and r0, r0, #0xff
|
||||
tst r0, #1
|
||||
beq _020A56F8
|
||||
mov r1, r3
|
||||
mov r0, #0
|
||||
bl MIi_CpuClear32
|
||||
_020A56F8:
|
||||
mov r0, r5
|
||||
str r6, [r4, #0]
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
arm_func_end AllocFromHead_dup2
|
||||
|
||||
arm_func_start AllocFromTail_dup2
|
||||
AllocFromTail_dup2: ; 0x020A5704
|
||||
stmfd sp!, {r3, r4, r5, lr}
|
||||
mov r4, r0
|
||||
ldr r3, [r4, #4]
|
||||
sub r0, r2, #1
|
||||
mvn r2, r0
|
||||
sub r1, r3, r1
|
||||
ldr r0, [r4, #0]
|
||||
and r5, r2, r1
|
||||
cmp r5, r0
|
||||
movlo r0, #0
|
||||
ldmloia sp!, {r3, r4, r5, pc}
|
||||
ldr r0, [r4, #-4]
|
||||
sub r2, r3, r5
|
||||
and r0, r0, #0xff
|
||||
tst r0, #1
|
||||
beq _020A5750
|
||||
mov r1, r5
|
||||
mov r0, #0
|
||||
bl MIi_CpuClear32
|
||||
_020A5750:
|
||||
mov r0, r5
|
||||
str r5, [r4, #4]
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
arm_func_end AllocFromTail_dup2
|
||||
|
||||
arm_func_start FreeHead
|
||||
FreeHead: ; 0x020A575C
|
||||
ldr r2, [r0, #0x18]
|
||||
mov r1, #0
|
||||
str r2, [r0, #0x24]
|
||||
str r1, [r0, #0x2c]
|
||||
bx lr
|
||||
arm_func_end FreeHead
|
||||
|
||||
arm_func_start FreeTail
|
||||
FreeTail: ; 0x020A5770
|
||||
ldr r2, [r0, #0x2c]
|
||||
cmp r2, #0
|
||||
beq _020A5790
|
||||
_020A577C:
|
||||
ldr r1, [r0, #0x1c]
|
||||
str r1, [r2, #8]
|
||||
ldr r2, [r2, #0xc]
|
||||
cmp r2, #0
|
||||
bne _020A577C
|
||||
_020A5790:
|
||||
ldr r1, [r0, #0x1c]
|
||||
str r1, [r0, #0x28]
|
||||
bx lr
|
||||
arm_func_end FreeTail
|
||||
|
||||
arm_func_start NNS_FndCreateFrmHeapEx
|
||||
NNS_FndCreateFrmHeapEx: ; 0x020A579C
|
||||
stmfd sp!, {r3, lr}
|
||||
add r1, r1, r0
|
||||
add r0, r0, #3
|
||||
bic r1, r1, #3
|
||||
bic r0, r0, #3
|
||||
cmp r0, r1
|
||||
bhi _020A57C4
|
||||
sub r3, r1, r0
|
||||
cmp r3, #0x30
|
||||
bhs _020A57CC
|
||||
_020A57C4:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A57CC:
|
||||
bl InitFrameHeap
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndCreateFrmHeapEx
|
||||
|
||||
arm_func_start NNS_FndDestroyFrmHeap
|
||||
NNS_FndDestroyFrmHeap: ; 0x020A57D4
|
||||
ldr ip, _020A57DC ; =NNSi_FndFinalizeHeap
|
||||
bx ip
|
||||
; .align 2, 0
|
||||
_020A57DC: .word NNSi_FndFinalizeHeap
|
||||
arm_func_end NNS_FndDestroyFrmHeap
|
||||
|
||||
arm_func_start NNS_FndAllocFromFrmHeapEx
|
||||
NNS_FndAllocFromFrmHeapEx: ; 0x020A57E0
|
||||
stmfd sp!, {r3, lr}
|
||||
cmp r1, #0
|
||||
moveq r1, #1
|
||||
add r1, r1, #3
|
||||
cmp r2, #0
|
||||
bic r1, r1, #3
|
||||
add r0, r0, #0x24
|
||||
blt _020A5808
|
||||
bl AllocFromHead_dup2
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A5808:
|
||||
rsb r2, r2, #0
|
||||
bl AllocFromTail_dup2
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndAllocFromFrmHeapEx
|
||||
|
||||
arm_func_start NNS_FndFreeToFrmHeap
|
||||
NNS_FndFreeToFrmHeap: ; 0x020A5814
|
||||
stmfd sp!, {r3, r4, r5, lr}
|
||||
mov r4, r1
|
||||
mov r5, r0
|
||||
tst r4, #1
|
||||
beq _020A582C
|
||||
bl FreeHead
|
||||
_020A582C:
|
||||
tst r4, #2
|
||||
ldmeqia sp!, {r3, r4, r5, pc}
|
||||
mov r0, r5
|
||||
bl FreeTail
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
arm_func_end NNS_FndFreeToFrmHeap
|
||||
|
||||
arm_func_start NNS_FndRecordStateForFrmHeap
|
||||
NNS_FndRecordStateForFrmHeap: ; 0x020A5840
|
||||
stmfd sp!, {r4, r5, r6, lr}
|
||||
mov r6, r0
|
||||
ldr r4, [r6, #0x24]
|
||||
mov r5, r1
|
||||
add r0, r6, #0x24
|
||||
mov r1, #0x10
|
||||
mov r2, #4
|
||||
bl AllocFromHead_dup2
|
||||
cmp r0, #0
|
||||
moveq r0, #0
|
||||
ldmeqia sp!, {r4, r5, r6, pc}
|
||||
str r5, [r0, #0]
|
||||
str r4, [r0, #4]
|
||||
ldr r1, [r6, #0x28]
|
||||
str r1, [r0, #8]
|
||||
ldr r1, [r6, #0x2c]
|
||||
str r1, [r0, #0xc]
|
||||
str r0, [r6, #0x2c]
|
||||
mov r0, #1
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
arm_func_end NNS_FndRecordStateForFrmHeap
|
||||
|
||||
arm_func_start NNS_FndFreeByStateToFrmHeap
|
||||
NNS_FndFreeByStateToFrmHeap: ; 0x020A5890
|
||||
ldr r3, [r0, #0x2c]
|
||||
cmp r1, #0
|
||||
cmpne r3, #0
|
||||
beq _020A58B4
|
||||
_020A58A0:
|
||||
ldr r2, [r3, #0]
|
||||
cmp r2, r1
|
||||
ldrne r3, [r3, #0xc]
|
||||
cmpne r3, #0
|
||||
bne _020A58A0
|
||||
_020A58B4:
|
||||
cmp r3, #0
|
||||
moveq r0, #0
|
||||
bxeq lr
|
||||
ldr r1, [r3, #4]
|
||||
str r1, [r0, #0x24]
|
||||
ldr r1, [r3, #8]
|
||||
str r1, [r0, #0x28]
|
||||
ldr r1, [r3, #0xc]
|
||||
str r1, [r0, #0x2c]
|
||||
mov r0, #1
|
||||
bx lr
|
||||
arm_func_end NNS_FndFreeByStateToFrmHeap
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
.include "macros/function.inc"
|
||||
.include "include/heapcommon.inc"
|
||||
|
||||
.extern Unk_021C3AA0
|
||||
.extern Unk_021C3AA4
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
arm_func_start FindContainHeap
|
||||
FindContainHeap: ; 0x020A4DE8
|
||||
stmfd sp!, {r4, r5, r6, lr}
|
||||
mov r5, r1
|
||||
mov r1, #0
|
||||
mov r6, r0
|
||||
bl NNS_FndGetNextListObject
|
||||
movs r4, r0
|
||||
beq _020A4E48
|
||||
_020A4E04:
|
||||
ldr r0, [r4, #0x18]
|
||||
cmp r0, r5
|
||||
bhi _020A4E34
|
||||
ldr r0, [r4, #0x1c]
|
||||
cmp r5, r0
|
||||
bhs _020A4E34
|
||||
mov r1, r5
|
||||
add r0, r4, #0xc
|
||||
bl FindContainHeap
|
||||
cmp r0, #0
|
||||
moveq r0, r4
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
_020A4E34:
|
||||
mov r0, r6
|
||||
mov r1, r4
|
||||
bl NNS_FndGetNextListObject
|
||||
movs r4, r0
|
||||
bne _020A4E04
|
||||
_020A4E48:
|
||||
mov r0, #0
|
||||
ldmia sp!, {r4, r5, r6, pc}
|
||||
arm_func_end FindContainHeap
|
||||
|
||||
arm_func_start FindListContainHeap
|
||||
FindListContainHeap: ; 0x020A4E50
|
||||
stmfd sp!, {r4, lr}
|
||||
ldr r4, _020A4E74 ; =0x021C3AA4
|
||||
mov r1, r0
|
||||
mov r0, r4
|
||||
bl FindContainHeap
|
||||
cmp r0, #0
|
||||
addne r4, r0, #0xc
|
||||
mov r0, r4
|
||||
ldmia sp!, {r4, pc}
|
||||
; .align 2, 0
|
||||
_020A4E74: .word Unk_021C3AA4
|
||||
arm_func_end FindListContainHeap
|
||||
|
||||
arm_func_start NNSi_FndInitHeapHead
|
||||
NNSi_FndInitHeapHead: ; 0x020A4E78
|
||||
stmfd sp!, {r4, lr}
|
||||
mov r4, r0
|
||||
ldrh r0, [sp, #8]
|
||||
str r1, [r4, #0]
|
||||
mov ip, #0
|
||||
str r2, [r4, #0x18]
|
||||
bic r1, ip, #0xff
|
||||
and r0, r0, #0xff
|
||||
orr r2, r1, r0
|
||||
str r3, [r4, #0x1c]
|
||||
add r0, r4, #0xc
|
||||
mov r1, #4
|
||||
str r2, [r4, #0x20]
|
||||
bl NNS_FndInitList
|
||||
ldr r0, _020A4EEC ; =0x021C3AA0
|
||||
ldr r0, [r0, #0]
|
||||
cmp r0, #0
|
||||
bne _020A4ED8
|
||||
ldr r0, _020A4EF0 ; =0x021C3AA4
|
||||
mov r1, #4
|
||||
bl NNS_FndInitList
|
||||
ldr r0, _020A4EEC ; =0x021C3AA0
|
||||
mov r1, #1
|
||||
str r1, [r0, #0]
|
||||
_020A4ED8:
|
||||
mov r0, r4
|
||||
bl FindListContainHeap
|
||||
mov r1, r4
|
||||
bl NNS_FndAppendListObject
|
||||
ldmia sp!, {r4, pc}
|
||||
; .align 2, 0
|
||||
_020A4EEC: .word Unk_021C3AA0
|
||||
_020A4EF0: .word Unk_021C3AA4
|
||||
arm_func_end NNSi_FndInitHeapHead
|
||||
|
||||
arm_func_start NNSi_FndFinalizeHeap
|
||||
NNSi_FndFinalizeHeap: ; 0x020A4EF4
|
||||
stmfd sp!, {r4, lr}
|
||||
mov r4, r0
|
||||
bl FindListContainHeap
|
||||
mov r1, r4
|
||||
bl NNS_FndRemoveListObject
|
||||
ldmia sp!, {r4, pc}
|
||||
arm_func_end NNSi_FndFinalizeHeap
|
||||
|
||||
.bss
|
||||
|
||||
|
||||
.global Unk_021C3AA0
|
||||
Unk_021C3AA0: ; 0x021C3AA0
|
||||
.space 0x4
|
||||
|
||||
.global Unk_021C3AA4
|
||||
Unk_021C3AA4: ; 0x021C3AA4
|
||||
.space 0xC
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
.public NNSi_FndInitHeapHead
|
||||
.public NNSi_FndFinalizeHeap
|
||||
.public GetRegionOfMBlock
|
||||
.public RemoveMBlock
|
||||
.public InsertMBlock
|
||||
.public InitMBlock
|
||||
.public InitExpHeap
|
||||
.public AllocUsedBlockFromFreeBlock
|
||||
.public AllocFromHead_dup1
|
||||
.public AllocFromTail_dup1
|
||||
.public RecycleRegion
|
||||
.public MIi_CpuClear32
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
.public NNSi_FndInitHeapHead
|
||||
.public NNSi_FndFinalizeHeap
|
||||
.public InitFrameHeap
|
||||
.public AllocFromHead_dup2
|
||||
.public AllocFromTail_dup2
|
||||
.public FreeHead
|
||||
.public FreeTail
|
||||
.public MIi_CpuClear32
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
.public NNS_FndInitList
|
||||
.public NNS_FndAppendListObject
|
||||
.public NNS_FndRemoveListObject
|
||||
.public NNS_FndGetNextListObject
|
||||
.public FindContainHeap
|
||||
.public FindListContainHeap
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
.public SetFirstObject
|
||||
.public NNS_FndAppendListObject
|
||||
.public NNS_FndPrependListObject
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
.public PopMBlock
|
||||
.public MIi_CpuClear32
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
.include "macros/function.inc"
|
||||
.include "include/list_nnsfnd.inc"
|
||||
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
arm_func_start NNS_FndInitList
|
||||
NNS_FndInitList: ; 0x020A4C10
|
||||
mov r2, #0
|
||||
str r2, [r0, #0]
|
||||
str r2, [r0, #4]
|
||||
strh r2, [r0, #8]
|
||||
strh r1, [r0, #0xa]
|
||||
bx lr
|
||||
arm_func_end NNS_FndInitList
|
||||
|
||||
arm_func_start SetFirstObject
|
||||
SetFirstObject: ; 0x020A4C28
|
||||
ldrh r3, [r0, #0xa]
|
||||
mov r2, #0
|
||||
add ip, r1, r3
|
||||
str r2, [ip, #4]
|
||||
str r2, [r1, r3]
|
||||
str r1, [r0, #0]
|
||||
str r1, [r0, #4]
|
||||
ldrh r1, [r0, #8]
|
||||
add r1, r1, #1
|
||||
strh r1, [r0, #8]
|
||||
bx lr
|
||||
arm_func_end SetFirstObject
|
||||
|
||||
arm_func_start NNS_FndAppendListObject
|
||||
NNS_FndAppendListObject: ; 0x020A4C54
|
||||
stmfd sp!, {r3, lr}
|
||||
ldr r2, [r0, #0]
|
||||
cmp r2, #0
|
||||
bne _020A4C6C
|
||||
bl SetFirstObject
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A4C6C:
|
||||
ldrh ip, [r0, #0xa]
|
||||
ldr r3, [r0, #4]
|
||||
mov r2, #0
|
||||
str r3, [r1, ip]
|
||||
add r3, r1, ip
|
||||
str r2, [r3, #4]
|
||||
ldrh r2, [r0, #0xa]
|
||||
ldr r3, [r0, #4]
|
||||
add r2, r3, r2
|
||||
str r1, [r2, #4]
|
||||
str r1, [r0, #4]
|
||||
ldrh r1, [r0, #8]
|
||||
add r1, r1, #1
|
||||
strh r1, [r0, #8]
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndAppendListObject
|
||||
|
||||
arm_func_start NNS_FndPrependListObject
|
||||
NNS_FndPrependListObject: ; 0x020A4CA8
|
||||
stmfd sp!, {r3, lr}
|
||||
ldr r2, [r0, #0]
|
||||
cmp r2, #0
|
||||
bne _020A4CC0
|
||||
bl SetFirstObject
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A4CC0:
|
||||
ldrh r3, [r0, #0xa]
|
||||
mov r2, #0
|
||||
str r2, [r1, r3]
|
||||
ldr r2, [r0, #0]
|
||||
add r3, r1, r3
|
||||
str r2, [r3, #4]
|
||||
ldrh r2, [r0, #0xa]
|
||||
ldr r3, [r0, #0]
|
||||
str r1, [r3, r2]
|
||||
str r1, [r0, #0]
|
||||
ldrh r1, [r0, #8]
|
||||
add r1, r1, #1
|
||||
strh r1, [r0, #8]
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndPrependListObject
|
||||
|
||||
arm_func_start NNS_FndInsertListObject
|
||||
NNS_FndInsertListObject: ; 0x020A4CF8
|
||||
stmfd sp!, {r3, lr}
|
||||
cmp r1, #0
|
||||
bne _020A4D10
|
||||
mov r1, r2
|
||||
bl NNS_FndAppendListObject
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A4D10:
|
||||
ldr r3, [r0, #0]
|
||||
cmp r1, r3
|
||||
bne _020A4D28
|
||||
mov r1, r2
|
||||
bl NNS_FndPrependListObject
|
||||
ldmia sp!, {r3, pc}
|
||||
_020A4D28:
|
||||
ldrh lr, [r0, #0xa]
|
||||
ldr r3, [r1, lr]
|
||||
add ip, r2, lr
|
||||
str r3, [r2, lr]
|
||||
str r1, [ip, #4]
|
||||
add r3, r3, lr
|
||||
str r2, [r3, #4]
|
||||
ldrh r3, [r0, #0xa]
|
||||
str r2, [r1, r3]
|
||||
ldrh r1, [r0, #8]
|
||||
add r1, r1, #1
|
||||
strh r1, [r0, #8]
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndInsertListObject
|
||||
|
||||
arm_func_start NNS_FndRemoveListObject
|
||||
NNS_FndRemoveListObject: ; 0x020A4D5C
|
||||
stmfd sp!, {r3, lr}
|
||||
ldrh ip, [r0, #0xa]
|
||||
ldr r3, [r1, ip]
|
||||
add lr, r1, ip
|
||||
cmp r3, #0
|
||||
ldreq r1, [lr, #4]
|
||||
streq r1, [r0]
|
||||
ldrne r2, [lr, #4]
|
||||
addne r1, r3, ip
|
||||
strne r2, [r1, #4]
|
||||
ldr r3, [lr, #4]
|
||||
cmp r3, #0
|
||||
ldreq r1, [lr]
|
||||
streq r1, [r0, #4]
|
||||
ldrneh r1, [r0, #0xa]
|
||||
ldrne r2, [lr]
|
||||
strne r2, [r3, r1]
|
||||
mov r1, #0
|
||||
str r1, [lr]
|
||||
str r1, [lr, #4]
|
||||
ldrh r1, [r0, #8]
|
||||
sub r1, r1, #1
|
||||
strh r1, [r0, #8]
|
||||
ldmia sp!, {r3, pc}
|
||||
arm_func_end NNS_FndRemoveListObject
|
||||
|
||||
arm_func_start NNS_FndGetNextListObject
|
||||
NNS_FndGetNextListObject: ; 0x020A4DBC
|
||||
cmp r1, #0
|
||||
ldreq r0, [r0]
|
||||
ldrneh r0, [r0, #0xa]
|
||||
addne r0, r1, r0
|
||||
ldrne r0, [r0, #4]
|
||||
bx lr
|
||||
arm_func_end NNS_FndGetNextListObject
|
||||
|
||||
arm_func_start NNS_FndGetPrevListObject
|
||||
NNS_FndGetPrevListObject: ; 0x020A4DD4
|
||||
cmp r1, #0
|
||||
ldreq r0, [r0, #4]
|
||||
ldrneh r0, [r0, #0xa]
|
||||
ldrne r0, [r1, r0]
|
||||
bx lr
|
||||
arm_func_end NNS_FndGetPrevListObject
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
.include "macros/function.inc"
|
||||
.include "include/unitheap.inc"
|
||||
|
||||
|
||||
|
||||
.text
|
||||
|
||||
|
||||
arm_func_start PopMBlock
|
||||
PopMBlock: ; 0x020A58E0
|
||||
ldr r2, [r0, #0]
|
||||
cmp r2, #0
|
||||
ldrne r1, [r2]
|
||||
strne r1, [r0]
|
||||
mov r0, r2
|
||||
bx lr
|
||||
arm_func_end PopMBlock
|
||||
|
||||
arm_func_start NNS_FndAllocFromUnitHeap
|
||||
NNS_FndAllocFromUnitHeap: ; 0x020A58F8
|
||||
stmfd sp!, {r3, r4, r5, lr}
|
||||
mov r5, r0
|
||||
add r0, r5, #0x24
|
||||
bl PopMBlock
|
||||
movs r4, r0
|
||||
beq _020A5930
|
||||
ldr r0, [r5, #0x20]
|
||||
ldr r2, [r5, #0x28]
|
||||
and r0, r0, #0xff
|
||||
tst r0, #1
|
||||
beq _020A5930
|
||||
mov r1, r4
|
||||
mov r0, #0
|
||||
bl MIi_CpuClear32
|
||||
_020A5930:
|
||||
mov r0, r4
|
||||
ldmia sp!, {r3, r4, r5, pc}
|
||||
arm_func_end NNS_FndAllocFromUnitHeap
|
||||
|
||||
arm_func_start NNS_FndFreeToUnitHeap
|
||||
NNS_FndFreeToUnitHeap: ; 0x020A5938
|
||||
ldr r2, [r0, #0x24]
|
||||
str r2, [r1, #0]
|
||||
str r1, [r0, #0x24]
|
||||
bx lr
|
||||
arm_func_end NNS_FndFreeToUnitHeap
|
||||
975
lib/NitroSystem/src/fnd/expheap.c
Normal file
975
lib/NitroSystem/src/fnd/expheap.c
Normal file
|
|
@ -0,0 +1,975 @@
|
|||
|
||||
#include <nitro.h>
|
||||
#include <nnsys/misc.h>
|
||||
#include <nnsys/fnd/expheap.h>
|
||||
#include <nnsys/fnd/config.h>
|
||||
|
||||
#include "include/heapcommoni.h"
|
||||
|
||||
#define MBLOCK_FREE_SIGNATURE ('FR')
|
||||
#define MBLOCK_USED_SIGNATURE ('UD')
|
||||
#define MAX_GROUPID 0xff
|
||||
#define DEFAULT_GROUPID 0
|
||||
#define MIN_ALIGNMENT 4
|
||||
#define DEFAULT_ALLOC_MODE NNS_FND_EXPHEAP_ALLOC_MODE_FIRST
|
||||
#define MIN_FREE_BLOCK_SIZE 4
|
||||
|
||||
typedef struct NNSiMemRegion NNSiMemRegion;
|
||||
|
||||
struct NNSiMemRegion {
|
||||
void * start;
|
||||
void * end;
|
||||
};
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
#define HEAP_WARNING(exp, ...) \
|
||||
(void)((exp) && (OS_Printf(__VA_ARGS__), 0))
|
||||
|
||||
#endif
|
||||
|
||||
static NNS_FND_INLINE void * MaxPtr (void * a, void * b) {
|
||||
return NNSiGetUIntPtr(a) > NNSiGetUIntPtr(b) ? a: b;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE BOOL IsValidExpHeapHandle (NNSFndHeapHandle handle) {
|
||||
if (handle == NNS_FND_HEAP_INVALID_HANDLE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = handle;
|
||||
return pHeapHd->signature == NNSI_EXPHEAP_SIGNATURE;
|
||||
}
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndExpHeapHead * GetExpHeapHeadPtrFromHeapHead (NNSiFndHeapHead * pHHead) {
|
||||
return AddU32ToPtr(pHHead, sizeof(NNSiFndHeapHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndHeapHead * GetHeapHeadPtrFromExpHeapHead (NNSiFndExpHeapHead * pEHHead) {
|
||||
return SubU32ToPtr(pEHHead, sizeof(NNSiFndHeapHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndExpHeapHead * GetExpHeapHeadPtrFromHandle (NNSFndHeapHandle heap) {
|
||||
return GetExpHeapHeadPtrFromHeapHead(heap);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void * GetMemPtrForMBlock (NNSiFndExpHeapMBlockHead * pMBlkHd) {
|
||||
return AddU32ToPtr(pMBlkHd, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE const void * GetMemCPtrForMBlock (const NNSiFndExpHeapMBlockHead * pMBlkHd) {
|
||||
return AddU32ToCPtr(pMBlkHd, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndExpHeapMBlockHead * GetMBlockHeadPtr (void * memBlock) {
|
||||
return SubU32ToPtr(memBlock, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE const NNSiFndExpHeapMBlockHead * GetMBlockHeadCPtr (const void * memBlock) {
|
||||
return SubU32ToCPtr(memBlock, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void * GetMBlockEndAddr (NNSiFndExpHeapMBlockHead * pMBHead) {
|
||||
return AddU32ToPtr(GetMemPtrForMBlock(pMBHead), pMBHead->blockSize);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE u16 GetAlignmentForMBlock (const NNSiFndExpHeapMBlockHead * pMBlkHd) {
|
||||
return (u16)NNSi_FndGetBitValue(pMBlkHd->attribute, 8, 7);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void SetAlignmentForMBlock (NNSiFndExpHeapMBlockHead * pMBlkHd, u16 alignment) {
|
||||
NNSi_FndSetBitValue(pMBlkHd->attribute, 8, 7, alignment);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE u16 GetGroupIDForMBlock (const NNSiFndExpHeapMBlockHead * pMBHead) {
|
||||
return (u16)NNSi_FndGetBitValue(pMBHead->attribute, 0, 8);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void SetGroupIDForMBlock (NNSiFndExpHeapMBlockHead * pMBHead, u16 id) {
|
||||
NNSi_FndSetBitValue(pMBHead->attribute, 0, 8, id);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE u16 GetAllocDirForMBlock (const NNSiFndExpHeapMBlockHead * pMBHead) {
|
||||
return (u16)NNSi_FndGetBitValue(pMBHead->attribute, 15, 1);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void SetAllocDirForMBlock (NNSiFndExpHeapMBlockHead * pMBHead, u16 mode) {
|
||||
NNSi_FndSetBitValue(pMBHead->attribute, 15, 1, mode);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE u16 GetAllocMode (NNSiFndExpHeapHead * pEHHead) {
|
||||
return (u16)NNSi_FndGetBitValue(pEHHead->feature, 0, 1);
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void SetAllocMode (NNSiFndExpHeapHead * pEHHead, u16 mode) {
|
||||
NNSi_FndSetBitValue(pEHHead->feature, 0, 1, mode);
|
||||
}
|
||||
|
||||
static void GetRegionOfMBlock (NNSiMemRegion * region, NNSiFndExpHeapMBlockHead * block) {
|
||||
region->start = SubU32ToPtr(block, GetAlignmentForMBlock(block));
|
||||
region->end = GetMBlockEndAddr(block);
|
||||
}
|
||||
|
||||
static NNSiFndExpHeapMBlockHead * RemoveMBlock (NNSiFndExpMBlockList * list, NNSiFndExpHeapMBlockHead * block) {
|
||||
NNSiFndExpHeapMBlockHead * const prev = block->pMBHeadPrev;
|
||||
NNSiFndExpHeapMBlockHead * const next = block->pMBHeadNext;
|
||||
|
||||
if (prev) {
|
||||
prev->pMBHeadNext = next;
|
||||
} else {
|
||||
list->head = next;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
next->pMBHeadPrev = prev;
|
||||
} else {
|
||||
list->tail = prev;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
static NNSiFndExpHeapMBlockHead * InsertMBlock (NNSiFndExpMBlockList * list, NNSiFndExpHeapMBlockHead * target, NNSiFndExpHeapMBlockHead * prev) {
|
||||
NNSiFndExpHeapMBlockHead * next;
|
||||
|
||||
target->pMBHeadPrev = prev;
|
||||
if (prev) {
|
||||
next = prev->pMBHeadNext;
|
||||
prev->pMBHeadNext = target;
|
||||
} else {
|
||||
next = list->head;
|
||||
list->head = target;
|
||||
}
|
||||
|
||||
target->pMBHeadNext = next;
|
||||
if (next) {
|
||||
next->pMBHeadPrev = target;
|
||||
} else {
|
||||
list->tail = target;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void AppendMBlock (NNSiFndExpMBlockList * list, NNSiFndExpHeapMBlockHead * block) {
|
||||
(void)InsertMBlock(list, block, list->tail);
|
||||
}
|
||||
|
||||
static NNSiFndExpHeapMBlockHead * InitMBlock (const NNSiMemRegion * pRegion, u16 signature) {
|
||||
NNSiFndExpHeapMBlockHead * block = pRegion->start;
|
||||
|
||||
block->signature = signature;
|
||||
block->attribute = 0;
|
||||
block->blockSize = GetOffsetFromPtr(GetMemPtrForMBlock(block), pRegion->end);
|
||||
block->pMBHeadPrev = NULL;
|
||||
block->pMBHeadNext = NULL;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndExpHeapMBlockHead * InitFreeMBlock (const NNSiMemRegion * pRegion) {
|
||||
return InitMBlock(pRegion, MBLOCK_FREE_SIGNATURE);
|
||||
}
|
||||
|
||||
static NNSiFndHeapHead * InitExpHeap (void * startAddress, void * endAddress, u16 optFlag) {
|
||||
NNSiFndHeapHead * pHeapHd = startAddress;
|
||||
NNSiFndExpHeapHead * pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
NNSi_FndInitHeapHead(
|
||||
pHeapHd,
|
||||
NNSI_EXPHEAP_SIGNATURE,
|
||||
AddU32ToPtr(pExpHeapHd, sizeof(NNSiFndExpHeapHead)),
|
||||
endAddress,
|
||||
optFlag
|
||||
);
|
||||
|
||||
pExpHeapHd->groupID = DEFAULT_GROUPID;
|
||||
pExpHeapHd->feature = 0;
|
||||
SetAllocMode(pExpHeapHd, DEFAULT_ALLOC_MODE);
|
||||
|
||||
{
|
||||
NNSiFndExpHeapMBlockHead * pMBHead;
|
||||
NNSiMemRegion region;
|
||||
region.start = pHeapHd->heapStart;
|
||||
region.end = pHeapHd->heapEnd;
|
||||
pMBHead = InitFreeMBlock(®ion);
|
||||
|
||||
pExpHeapHd->mbFreeList.head = pMBHead;
|
||||
pExpHeapHd->mbFreeList.tail = pMBHead;
|
||||
pExpHeapHd->mbUsedList.head = NULL;
|
||||
pExpHeapHd->mbUsedList.tail = NULL;
|
||||
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
static void * AllocUsedBlockFromFreeBlock (NNSiFndExpHeapHead * pEHHead, NNSiFndExpHeapMBlockHead * pMBHeadFree, void * mblock, u32 size, u16 direction) {
|
||||
NNSiMemRegion freeRgnT;
|
||||
NNSiMemRegion freeRgnB;
|
||||
NNSiFndExpHeapMBlockHead * pMBHeadFreePrev;
|
||||
|
||||
GetRegionOfMBlock(&freeRgnT, pMBHeadFree);
|
||||
freeRgnB.end = freeRgnT.end;
|
||||
freeRgnB.start = AddU32ToPtr(mblock, size);
|
||||
freeRgnT.end = SubU32ToPtr(mblock, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
|
||||
pMBHeadFreePrev = RemoveMBlock(&pEHHead->mbFreeList, pMBHeadFree);
|
||||
|
||||
if (GetOffsetFromPtr(freeRgnT.start, freeRgnT.end) < sizeof(NNSiFndExpHeapMBlockHead) + MIN_FREE_BLOCK_SIZE) {
|
||||
freeRgnT.end = freeRgnT.start;
|
||||
} else {
|
||||
pMBHeadFreePrev = InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&freeRgnT), pMBHeadFreePrev);
|
||||
}
|
||||
|
||||
if (GetOffsetFromPtr(freeRgnB.start, freeRgnB.end) < sizeof(NNSiFndExpHeapMBlockHead) + MIN_FREE_BLOCK_SIZE) {
|
||||
freeRgnB.start = freeRgnB.end;
|
||||
} else {
|
||||
(void)InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&freeRgnB), pMBHeadFreePrev);
|
||||
}
|
||||
|
||||
FillAllocMemory(GetHeapHeadPtrFromExpHeapHead(pEHHead), freeRgnT.end, GetOffsetFromPtr(freeRgnT.end, freeRgnB.start));
|
||||
|
||||
{
|
||||
NNSiFndExpHeapMBlockHead * pMBHeadNewUsed;
|
||||
NNSiMemRegion region;
|
||||
|
||||
region.start = SubU32ToPtr(mblock, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
region.end = freeRgnB.start;
|
||||
|
||||
pMBHeadNewUsed = InitMBlock(®ion, MBLOCK_USED_SIGNATURE);
|
||||
SetAllocDirForMBlock(pMBHeadNewUsed, direction);
|
||||
SetAlignmentForMBlock(pMBHeadNewUsed, (u16)GetOffsetFromPtr(freeRgnT.end, pMBHeadNewUsed));
|
||||
SetGroupIDForMBlock(pMBHeadNewUsed, pEHHead->groupID);
|
||||
AppendMBlock(&pEHHead->mbUsedList, pMBHeadNewUsed);
|
||||
}
|
||||
|
||||
return mblock;
|
||||
}
|
||||
|
||||
static void * AllocFromHead (NNSiFndHeapHead * pHeapHd, u32 size, int alignment) {
|
||||
NNSiFndExpHeapHead * pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
const BOOL bAllocFirst = GetAllocMode(pExpHeapHd) == NNS_FND_EXPHEAP_ALLOC_MODE_FIRST;
|
||||
|
||||
NNSiFndExpHeapMBlockHead * pMBlkHd = NULL;
|
||||
NNSiFndExpHeapMBlockHead * pMBlkHdFound = NULL;
|
||||
u32 foundSize = 0xffffffff;
|
||||
void * foundMBlock = NULL;
|
||||
|
||||
for (pMBlkHd = pExpHeapHd->mbFreeList.head; pMBlkHd; pMBlkHd = pMBlkHd->pMBHeadNext) {
|
||||
void * const mblock = GetMemPtrForMBlock(pMBlkHd);
|
||||
void * const reqMBlock = NNSi_FndRoundUpPtr(mblock, alignment);
|
||||
const u32 offset = GetOffsetFromPtr(mblock, reqMBlock);
|
||||
|
||||
if (pMBlkHd->blockSize >= size + offset
|
||||
&& foundSize > pMBlkHd->blockSize) {
|
||||
pMBlkHdFound = pMBlkHd;
|
||||
foundSize = pMBlkHd->blockSize;
|
||||
foundMBlock = reqMBlock;
|
||||
|
||||
if (bAllocFirst || foundSize == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pMBlkHdFound) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return AllocUsedBlockFromFreeBlock(
|
||||
pExpHeapHd,
|
||||
pMBlkHdFound,
|
||||
foundMBlock,
|
||||
size,
|
||||
NNS_FND_EXPHEAP_ALLOC_DIR_FRONT
|
||||
);
|
||||
}
|
||||
|
||||
static void * AllocFromTail (NNSiFndHeapHead * pHeapHd, u32 size, int alignment) {
|
||||
NNSiFndExpHeapHead * pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
const BOOL bAllocFirst = GetAllocMode(pExpHeapHd) == NNS_FND_EXPHEAP_ALLOC_MODE_FIRST;
|
||||
|
||||
NNSiFndExpHeapMBlockHead * pMBlkHd = NULL;
|
||||
NNSiFndExpHeapMBlockHead * pMBlkHdFound = NULL;
|
||||
u32 foundSize = 0xffffffff;
|
||||
void * foundMBlock = NULL;
|
||||
|
||||
for (pMBlkHd = pExpHeapHd->mbFreeList.tail; pMBlkHd; pMBlkHd = pMBlkHd->pMBHeadPrev) {
|
||||
void * const mblock = GetMemPtrForMBlock(pMBlkHd);
|
||||
void * const mblockEnd = AddU32ToPtr(mblock, pMBlkHd->blockSize);
|
||||
void * const reqMBlock = NNSi_FndRoundDownPtr(SubU32ToPtr(mblockEnd, size), alignment);
|
||||
|
||||
if (ComparePtr(reqMBlock, mblock) >= 0
|
||||
&& foundSize > pMBlkHd->blockSize) {
|
||||
pMBlkHdFound = pMBlkHd;
|
||||
foundSize = pMBlkHd->blockSize;
|
||||
foundMBlock = reqMBlock;
|
||||
|
||||
if (bAllocFirst || foundSize == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pMBlkHdFound) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return AllocUsedBlockFromFreeBlock(
|
||||
pExpHeapHd,
|
||||
pMBlkHdFound,
|
||||
foundMBlock,
|
||||
size,
|
||||
NNS_FND_EXPHEAP_ALLOC_DIR_REAR
|
||||
);
|
||||
}
|
||||
|
||||
static BOOL RecycleRegion (NNSiFndExpHeapHead * pEHHead, const NNSiMemRegion * pRegion) {
|
||||
NNSiFndExpHeapMBlockHead * pBlkPrFree = NULL;
|
||||
NNSiMemRegion freeRgn = *pRegion;
|
||||
|
||||
{
|
||||
NNSiFndExpHeapMBlockHead * pBlk;
|
||||
|
||||
for (pBlk = pEHHead->mbFreeList.head; pBlk; pBlk = pBlk->pMBHeadNext) {
|
||||
if (pBlk < pRegion->start) {
|
||||
pBlkPrFree = pBlk;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pBlk == pRegion->end) {
|
||||
freeRgn.end = GetMBlockEndAddr(pBlk);
|
||||
(void)RemoveMBlock(&pEHHead->mbFreeList, pBlk);
|
||||
|
||||
FillNoUseMemory(GetHeapHeadPtrFromExpHeapHead(pEHHead), pBlk, sizeof(NNSiFndExpHeapMBlockHead));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBlkPrFree && GetMBlockEndAddr(pBlkPrFree) == pRegion->start) {
|
||||
freeRgn.start = pBlkPrFree;
|
||||
pBlkPrFree = RemoveMBlock(&pEHHead->mbFreeList, pBlkPrFree);
|
||||
}
|
||||
|
||||
if (GetOffsetFromPtr(freeRgn.start, freeRgn.end) < sizeof(NNSiFndExpHeapMBlockHead)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FillFreeMemory(GetHeapHeadPtrFromExpHeapHead(pEHHead), pRegion->start, GetOffsetFromPtr(pRegion->start, pRegion->end));
|
||||
|
||||
(void)InsertMBlock(
|
||||
&pEHHead->mbFreeList,
|
||||
InitFreeMBlock(&freeRgn),
|
||||
pBlkPrFree
|
||||
);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static BOOL CheckMBlock (const NNSiFndExpHeapMBlockHead * pMBHead, NNSiFndHeapHead * pHeapHd, u16 signature, const char * heapType, u32 flag) {
|
||||
const BOOL bPrint = 0 != (flag & NNS_FND_HEAP_ERROR_PRINT);
|
||||
const void * const memBlock = GetMemCPtrForMBlock(pMBHead);
|
||||
|
||||
if (pHeapHd) {
|
||||
if (NNSiGetUIntPtr(pMBHead) < NNSiGetUIntPtr(pHeapHd->heapStart)
|
||||
|| NNSiGetUIntPtr(memBlock) > NNSiGetUIntPtr(pHeapHd->heapEnd)
|
||||
) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Bad %s memory block address. - address %08X, heap area [%08X - %08X)\n",
|
||||
heapType, memBlock, pHeapHd->heapStart, pHeapHd->heapEnd
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (NNSiGetUIntPtr(pMBHead) >= 0x11000000) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Bad %s memory block address. - address %08X\n",
|
||||
heapType, memBlock
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pMBHead->signature != signature) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Bad %s memory block signature. - address %08X, signature %04X\n",
|
||||
heapType, memBlock, pMBHead->signature
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pMBHead->blockSize >= 0x01000000) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Too large %s memory block. - address %08X, block size %08X\n",
|
||||
heapType, memBlock, pMBHead->blockSize
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pHeapHd) {
|
||||
if (NNSiGetUIntPtr(memBlock) + pMBHead->blockSize > NNSiGetUIntPtr(pHeapHd->heapEnd)) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " wrong size %s memory block. - address %08X, block size %08X\n",
|
||||
heapType, memBlock, pMBHead->blockSize
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static NNS_FND_INLINE BOOL CheckUsedMBlock (const NNSiFndExpHeapMBlockHead * pMBHead, NNSiFndHeapHead * pHeapHd, u32 flag) {
|
||||
return CheckMBlock(pMBHead, pHeapHd, MBLOCK_USED_SIGNATURE, "used", flag);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static NNS_FND_INLINE BOOL CheckFreeMBlock (const NNSiFndExpHeapMBlockHead * pMBHead, NNSiFndHeapHead * pHeapHd, u32 flag) {
|
||||
return CheckMBlock(pMBHead, pHeapHd, MBLOCK_FREE_SIGNATURE, "free", flag);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static BOOL CheckMBlockPrevPtr (const NNSiFndExpHeapMBlockHead * pMBHead, const NNSiFndExpHeapMBlockHead * pMBHeadPrev, u32 flag) {
|
||||
const BOOL bPrint = 0 != (flag & NNS_FND_HEAP_ERROR_PRINT);
|
||||
|
||||
if (pMBHead->pMBHeadPrev != pMBHeadPrev) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Wrong link memory block. - address %08X, previous address %08X != %08X\n",
|
||||
GetMemCPtrForMBlock(pMBHead), pMBHead->pMBHeadPrev, pMBHeadPrev
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static BOOL CheckMBlockNextPtr (const NNSiFndExpHeapMBlockHead * pMBHead, const NNSiFndExpHeapMBlockHead * pMBHeadNext, u32 flag) {
|
||||
const BOOL bPrint = 0 != (flag & NNS_FND_HEAP_ERROR_PRINT);
|
||||
|
||||
if (pMBHead->pMBHeadNext != pMBHeadNext) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Wrong link memory block. - address %08X, next address %08X != %08X\n",
|
||||
GetMemCPtrForMBlock(pMBHead), pMBHead->pMBHeadNext, pMBHeadNext
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static BOOL CheckMBlockLinkTail (const NNSiFndExpHeapMBlockHead * pMBHead, const NNSiFndExpHeapMBlockHead * pMBHeadTail, const char * heapType, u32 flag) {
|
||||
const BOOL bPrint = 0 != (flag & NNS_FND_HEAP_ERROR_PRINT);
|
||||
|
||||
if (pMBHead != pMBHeadTail) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Wrong memory brock list %s pointer. - address %08X, %s address %08X != %08X\n",
|
||||
heapType, GetMemCPtrForMBlock(pMBHead), heapType, pMBHead, pMBHeadTail
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static BOOL IsValidUsedMBlock (const void * memBlock, NNSFndHeapHandle heap) {
|
||||
NNSiFndHeapHead * pHeapHd = heap;
|
||||
|
||||
if (!memBlock) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return CheckUsedMBlock(GetMBlockHeadCPtr(memBlock), pHeapHd, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
void NNSi_FndDumpExpHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
{
|
||||
u32 usedSize = 0;
|
||||
u32 usedCnt = 0;
|
||||
u32 freeSize = 0;
|
||||
u32 freeCnt = 0;
|
||||
|
||||
NNSiFndHeapHead * pHeapHd = heap;
|
||||
NNSiFndExpHeapHead * pExpHeapHd = GetExpHeapHeadPtrFromHandle(pHeapHd);
|
||||
|
||||
NNSi_FndDumpHeapHead(pHeapHd);
|
||||
|
||||
OS_Printf(" attr address: size gid aln prev_ptr next_ptr\n");
|
||||
|
||||
OS_Printf(" (Used Blocks)\n");
|
||||
|
||||
if (pExpHeapHd->mbUsedList.head == NULL) {
|
||||
OS_Printf(" NONE\n");
|
||||
} else {
|
||||
NNSiFndExpHeapMBlockHead * pMBHead;
|
||||
|
||||
for (pMBHead = pExpHeapHd->mbUsedList.head; pMBHead; pMBHead = pMBHead->pMBHeadNext) {
|
||||
if (pMBHead->signature != MBLOCK_USED_SIGNATURE) {
|
||||
OS_Printf(" xxxxx %08x: -------- --- --- (-------- --------)\nabort\n", pMBHead);
|
||||
break;
|
||||
}
|
||||
|
||||
OS_Printf(
|
||||
" %s %08x: %8d %3d %3d (%08x %08x)\n",
|
||||
GetAllocDirForMBlock(pMBHead) == NNS_FND_EXPHEAP_ALLOC_DIR_REAR ? " rear" : "front",
|
||||
GetMemPtrForMBlock(pMBHead),
|
||||
pMBHead->blockSize,
|
||||
GetGroupIDForMBlock(pMBHead),
|
||||
GetAlignmentForMBlock(pMBHead),
|
||||
pMBHead->pMBHeadPrev ? GetMemPtrForMBlock(pMBHead->pMBHeadPrev): NULL,
|
||||
pMBHead->pMBHeadNext ? GetMemPtrForMBlock(pMBHead->pMBHeadNext): NULL
|
||||
);
|
||||
|
||||
usedSize += sizeof(NNSiFndExpHeapMBlockHead) + pMBHead->blockSize + GetAlignmentForMBlock(pMBHead);
|
||||
|
||||
usedCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
OS_Printf(" (Free Blocks)\n");
|
||||
|
||||
if (pExpHeapHd->mbFreeList.head == NULL) {
|
||||
OS_Printf(" NONE\n");
|
||||
} else {
|
||||
NNSiFndExpHeapMBlockHead * pMBHead;
|
||||
|
||||
for (pMBHead = pExpHeapHd->mbFreeList.head; pMBHead; pMBHead = pMBHead->pMBHeadNext) {
|
||||
if (pMBHead->signature != MBLOCK_FREE_SIGNATURE) {
|
||||
OS_Printf(" xxxxx %08x: -------- --- --- (-------- --------)\nabort\n", pMBHead);
|
||||
break;
|
||||
}
|
||||
|
||||
OS_Printf(
|
||||
" %s %08x: %8d %3d %3d (%08x %08x)\n",
|
||||
" free",
|
||||
GetMemPtrForMBlock(pMBHead),
|
||||
pMBHead->blockSize,
|
||||
GetGroupIDForMBlock(pMBHead),
|
||||
GetAlignmentForMBlock(pMBHead),
|
||||
pMBHead->pMBHeadPrev ? GetMemPtrForMBlock(pMBHead->pMBHeadPrev): NULL,
|
||||
pMBHead->pMBHeadNext ? GetMemPtrForMBlock(pMBHead->pMBHeadNext): NULL
|
||||
);
|
||||
|
||||
freeCnt++;
|
||||
}
|
||||
}
|
||||
|
||||
OS_Printf("\n");
|
||||
|
||||
{
|
||||
u32 heapSize = GetOffsetFromPtr(pHeapHd->heapStart, pHeapHd->heapEnd);
|
||||
OS_Printf(
|
||||
" %d / %d bytes (%6.2f%%) used (U:%d F:%d)\n",
|
||||
usedSize, heapSize, 100.0 * usedSize / heapSize, usedCnt, freeCnt
|
||||
);
|
||||
}
|
||||
|
||||
OS_Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NNSFndHeapHandle NNS_FndCreateExpHeapEx (void * startAddress, u32 size, u16 optFlag) {
|
||||
void * endAddress;
|
||||
|
||||
SDK_NULL_ASSERT(startAddress);
|
||||
|
||||
endAddress = NNSi_FndRoundDownPtr(AddU32ToPtr(startAddress, size), MIN_ALIGNMENT);
|
||||
startAddress = NNSi_FndRoundUpPtr(startAddress, MIN_ALIGNMENT);
|
||||
|
||||
if (NNSiGetUIntPtr(startAddress) > NNSiGetUIntPtr(endAddress)
|
||||
|| GetOffsetFromPtr(startAddress, endAddress) < sizeof(NNSiFndHeapHead) + sizeof(NNSiFndExpHeapHead)
|
||||
+ sizeof(NNSiFndExpHeapMBlockHead) + MIN_ALIGNMENT
|
||||
) {
|
||||
return NNS_FND_HEAP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = InitExpHeap(startAddress, endAddress, optFlag);
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndDestroyExpHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
NNSi_FndFinalizeHeap(heap);
|
||||
}
|
||||
|
||||
void * NNS_FndAllocFromExpHeapEx (NNSFndHeapHandle heap, u32 size, int alignment) {
|
||||
void * memory = NULL;
|
||||
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
NNS_ASSERT(alignment % MIN_ALIGNMENT == 0);
|
||||
NNS_ASSERT(MIN_ALIGNMENT <= abs(alignment) && abs(alignment) <= 32);
|
||||
|
||||
if (size == 0) {
|
||||
size = 1;
|
||||
}
|
||||
|
||||
size = NNSi_FndRoundUp(size, MIN_ALIGNMENT);
|
||||
|
||||
if (alignment >= 0) {
|
||||
memory = AllocFromHead(heap, size, alignment);
|
||||
} else {
|
||||
memory = AllocFromTail(heap, size, -alignment);
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
u32 NNS_FndResizeForMBlockExpHeap (NNSFndHeapHandle heap, void * memBlock, u32 size) {
|
||||
NNSiFndExpHeapHead * pEHHead;
|
||||
NNSiFndExpHeapMBlockHead * pMBHead;
|
||||
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
NNS_ASSERT(IsValidUsedMBlock(memBlock, heap));
|
||||
|
||||
pEHHead = GetExpHeapHeadPtrFromHandle(heap);
|
||||
pMBHead = GetMBlockHeadPtr(memBlock);
|
||||
|
||||
size = NNSi_FndRoundUp(size, MIN_ALIGNMENT);
|
||||
if (size == pMBHead->blockSize) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (size > pMBHead->blockSize) {
|
||||
void * crUsedEnd = GetMBlockEndAddr(pMBHead);
|
||||
NNSiFndExpHeapMBlockHead * block;
|
||||
|
||||
for (block = pEHHead->mbFreeList.head; block; block = block->pMBHeadNext) {
|
||||
if (block == crUsedEnd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!block || size > pMBHead->blockSize + sizeof(NNSiFndExpHeapMBlockHead) + block->blockSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiMemRegion rgnNewFree;
|
||||
void * oldFreeStart;
|
||||
NNSiFndExpHeapMBlockHead * nextBlockPrev;
|
||||
|
||||
GetRegionOfMBlock(&rgnNewFree, block);
|
||||
nextBlockPrev = RemoveMBlock(&pEHHead->mbFreeList, block);
|
||||
|
||||
oldFreeStart = rgnNewFree.start;
|
||||
rgnNewFree.start = AddU32ToPtr(memBlock, size);
|
||||
|
||||
if (GetOffsetFromPtr(rgnNewFree.start, rgnNewFree.end) < sizeof(NNSiFndExpHeapMBlockHead)) {
|
||||
rgnNewFree.start = rgnNewFree.end;
|
||||
}
|
||||
|
||||
pMBHead->blockSize = GetOffsetFromPtr(memBlock, rgnNewFree.start);
|
||||
|
||||
if (GetOffsetFromPtr(rgnNewFree.start, rgnNewFree.end) >= sizeof(NNSiFndExpHeapMBlockHead)) {
|
||||
(void)InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&rgnNewFree), nextBlockPrev);
|
||||
}
|
||||
|
||||
FillAllocMemory(
|
||||
heap,
|
||||
oldFreeStart,
|
||||
GetOffsetFromPtr(oldFreeStart, rgnNewFree.start)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
NNSiMemRegion rgnNewFree;
|
||||
const u32 oldBlockSize = pMBHead->blockSize;
|
||||
|
||||
rgnNewFree.start = AddU32ToPtr(memBlock, size);
|
||||
rgnNewFree.end = GetMBlockEndAddr(pMBHead);
|
||||
|
||||
pMBHead->blockSize = size;
|
||||
|
||||
if (!RecycleRegion(pEHHead, &rgnNewFree)) {
|
||||
pMBHead->blockSize = oldBlockSize;
|
||||
}
|
||||
}
|
||||
|
||||
return pMBHead->blockSize;
|
||||
}
|
||||
|
||||
void NNS_FndFreeToExpHeap (NNSFndHeapHandle heap, void * memBlock) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = heap;
|
||||
NNSiFndExpHeapHead * pExpHeapHd = GetExpHeapHeadPtrFromHandle(pHeapHd);
|
||||
NNSiFndExpHeapMBlockHead * pMBHead = GetMBlockHeadPtr(memBlock);
|
||||
NNSiMemRegion region;
|
||||
|
||||
NNS_ASSERT(pHeapHd->heapStart <= memBlock && memBlock < pHeapHd->heapEnd);
|
||||
|
||||
GetRegionOfMBlock(®ion, pMBHead);
|
||||
(void)RemoveMBlock(&pExpHeapHd->mbUsedList, pMBHead);
|
||||
(void)RecycleRegion(pExpHeapHd, ®ion);
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndGetTotalFreeSizeForExpHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
{
|
||||
u32 sumSize = 0;
|
||||
NNSiFndExpHeapHead * pEHHead = GetExpHeapHeadPtrFromHandle(heap);
|
||||
NNSiFndExpHeapMBlockHead * pMBHead;
|
||||
|
||||
for(pMBHead = pEHHead->mbFreeList.head; pMBHead; pMBHead = pMBHead->pMBHeadNext) {
|
||||
sumSize += pMBHead->blockSize;
|
||||
}
|
||||
|
||||
return sumSize;
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndGetAllocatableSizeForExpHeapEx (NNSFndHeapHandle heap, int alignment) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
NNS_ASSERT(alignment % MIN_ALIGNMENT == 0);
|
||||
NNS_ASSERT(MIN_ALIGNMENT <= abs(alignment) && abs(alignment) <= 32);
|
||||
|
||||
alignment = abs(alignment);
|
||||
|
||||
{
|
||||
NNSiFndExpHeapHead * pEHHead = GetExpHeapHeadPtrFromHandle(heap);
|
||||
u32 maxSize = 0;
|
||||
u32 offsetMin = 0xFFFFFFFF;
|
||||
NNSiFndExpHeapMBlockHead * pMBlkHd;
|
||||
|
||||
for (pMBlkHd = pEHHead->mbFreeList.head; pMBlkHd; pMBlkHd = pMBlkHd->pMBHeadNext) {
|
||||
void * baseAddress = NNSi_FndRoundUpPtr(GetMemPtrForMBlock(pMBlkHd), alignment);
|
||||
|
||||
if (NNSiGetUIntPtr(baseAddress) < NNSiGetUIntPtr(GetMBlockEndAddr(pMBlkHd))) {
|
||||
const u32 blockSize = GetOffsetFromPtr(baseAddress, GetMBlockEndAddr(pMBlkHd));
|
||||
|
||||
const u32 offset = GetOffsetFromPtr(GetMemPtrForMBlock(pMBlkHd), baseAddress);
|
||||
|
||||
if (maxSize < blockSize
|
||||
|| (maxSize == blockSize && offsetMin > offset)
|
||||
) {
|
||||
maxSize = blockSize;
|
||||
offsetMin = offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maxSize;
|
||||
}
|
||||
}
|
||||
|
||||
u16 NNS_FndSetAllocModeForExpHeap (NNSFndHeapHandle heap, u16 mode) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndExpHeapHead * const pEHHead = GetExpHeapHeadPtrFromHandle(heap);
|
||||
u16 oldMode = GetAllocMode(pEHHead);
|
||||
SetAllocMode(pEHHead, mode);
|
||||
|
||||
return oldMode;
|
||||
}
|
||||
}
|
||||
|
||||
u16 NNS_FndGetAllocModeForExpHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
return GetAllocMode(GetExpHeapHeadPtrFromHandle(heap));
|
||||
}
|
||||
|
||||
u16 NNS_FndSetGroupIDForExpHeap (NNSFndHeapHandle heap, u16 groupID) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
NNS_ASSERT(groupID <= MAX_GROUPID);
|
||||
|
||||
{
|
||||
NNSiFndExpHeapHead * pEHHead = GetExpHeapHeadPtrFromHandle(heap);
|
||||
u16 oldGroupID = pEHHead->groupID;
|
||||
pEHHead->groupID = groupID;
|
||||
|
||||
return oldGroupID;
|
||||
}
|
||||
}
|
||||
|
||||
u16 NNS_FndGetGroupIDForExpHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
|
||||
return GetExpHeapHeadPtrFromHandle(heap)->groupID;
|
||||
}
|
||||
|
||||
void NNS_FndVisitAllocatedForExpHeap (NNSFndHeapHandle heap, NNSFndHeapVisitor visitor, u32 userParam) {
|
||||
NNS_ASSERT(IsValidExpHeapHandle(heap));
|
||||
SDK_NULL_ASSERT(visitor);
|
||||
|
||||
{
|
||||
NNSiFndExpHeapMBlockHead * pMBHead = GetExpHeapHeadPtrFromHandle(heap)->mbUsedList.head;
|
||||
|
||||
while (pMBHead) {
|
||||
NNSiFndExpHeapMBlockHead * pMBHeadNext = pMBHead->pMBHeadNext;
|
||||
(*visitor)(GetMemPtrForMBlock(pMBHead), heap, userParam);
|
||||
pMBHead = pMBHeadNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndGetSizeForMBlockExpHeap (const void * memBlock) {
|
||||
NNS_ASSERT(IsValidUsedMBlock(memBlock, NULL));
|
||||
|
||||
return GetMBlockHeadCPtr(memBlock)->blockSize;
|
||||
}
|
||||
|
||||
u16 NNS_FndGetGroupIDForMBlockExpHeap (const void * memBlock) {
|
||||
NNS_ASSERT(IsValidUsedMBlock(memBlock, NULL));
|
||||
|
||||
return GetGroupIDForMBlock(GetMBlockHeadCPtr(memBlock));
|
||||
}
|
||||
|
||||
u16 NNS_FndGetAllocDirForMBlockExpHeap (const void * memBlock) {
|
||||
NNS_ASSERT(IsValidUsedMBlock(memBlock, NULL));
|
||||
|
||||
return GetAllocDirForMBlock(GetMBlockHeadCPtr(memBlock));
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
BOOL NNS_FndCheckExpHeap (NNSFndHeapHandle heap, u32 optFlag) {
|
||||
const BOOL bPrint = 0 != (optFlag & NNS_FND_HEAP_ERROR_PRINT);
|
||||
u32 totalBytes = 0;
|
||||
|
||||
if (!IsValidExpHeapHandle(heap)) {
|
||||
HEAP_WARNING(bPrint, "[NNS Foundation " "Exp" " Heap]" " Invalid heap handle. - %08X\n", heap);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * const pHeapHd = heap;
|
||||
NNSiFndExpHeapHead * const pExpHeapHd = GetExpHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
NNSiFndExpHeapMBlockHead * pMBHead = NULL;
|
||||
NNSiFndExpHeapMBlockHead * pMBHeadPrev = NULL;
|
||||
|
||||
for (pMBHead = pExpHeapHd->mbUsedList.head; pMBHead; pMBHeadPrev = pMBHead, pMBHead = pMBHead->pMBHeadNext) {
|
||||
if (!CheckUsedMBlock(pMBHead, pHeapHd, optFlag)
|
||||
|| !CheckMBlockPrevPtr(pMBHead, pMBHeadPrev, optFlag)
|
||||
) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
totalBytes += sizeof(NNSiFndExpHeapMBlockHead) + pMBHead->blockSize + GetAlignmentForMBlock(pMBHead);
|
||||
}
|
||||
|
||||
if (!CheckMBlockLinkTail(pMBHeadPrev, pExpHeapHd->mbUsedList.tail, "tail", optFlag)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pMBHead = NULL;
|
||||
pMBHeadPrev = NULL;
|
||||
for (pMBHead = pExpHeapHd->mbFreeList.head; pMBHead; pMBHeadPrev = pMBHead, pMBHead = pMBHead->pMBHeadNext) {
|
||||
if (!CheckFreeMBlock(pMBHead, pHeapHd, optFlag)
|
||||
|| !CheckMBlockPrevPtr(pMBHead, pMBHeadPrev, optFlag)
|
||||
) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
totalBytes += sizeof(NNSiFndExpHeapMBlockHead) + pMBHead->blockSize;
|
||||
}
|
||||
|
||||
if (!CheckMBlockLinkTail(pMBHeadPrev, pExpHeapHd->mbFreeList.tail, "tail", optFlag)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (totalBytes != GetOffsetFromPtr(pHeapHd->heapStart, pHeapHd->heapEnd)) {
|
||||
HEAP_WARNING(
|
||||
bPrint, "[NNS Foundation " "Exp" " Heap]" " Incorrect total memory block size. - heap size %08X, sum size %08X\n",
|
||||
GetOffsetFromPtr(pHeapHd->heapStart, pHeapHd->heapEnd), totalBytes
|
||||
);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
BOOL NNS_FndCheckForMBlockExpHeap (const void * memBlock, NNSFndHeapHandle heap, u32 optFlag) {
|
||||
const NNSiFndExpHeapMBlockHead * pMBHead = NULL;
|
||||
NNSiFndHeapHead * const pHeapHd = heap;
|
||||
|
||||
if (!memBlock) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pMBHead = GetMBlockHeadCPtr(memBlock);
|
||||
|
||||
if (!CheckUsedMBlock(pMBHead, pHeapHd, optFlag)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pMBHead->pMBHeadPrev) {
|
||||
if (!CheckUsedMBlock(pMBHead->pMBHeadPrev, pHeapHd, optFlag)
|
||||
|| !CheckMBlockNextPtr(pMBHead->pMBHeadPrev, pMBHead, optFlag)
|
||||
) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (pHeapHd) {
|
||||
if (!CheckMBlockLinkTail(pMBHead, GetExpHeapHeadPtrFromHeapHead(pHeapHd)->mbUsedList.head, "head", optFlag)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pMBHead->pMBHeadNext) {
|
||||
if (!CheckUsedMBlock(pMBHead->pMBHeadNext, pHeapHd, optFlag)
|
||||
|| !CheckMBlockPrevPtr(pMBHead->pMBHeadNext, pMBHead, optFlag)
|
||||
) {
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if (pHeapHd) {
|
||||
if (!CheckMBlockLinkTail(pMBHead, GetExpHeapHeadPtrFromHeapHead(pHeapHd)->mbUsedList.tail, "tail", optFlag)) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
373
lib/NitroSystem/src/fnd/frameheap.c
Normal file
373
lib/NitroSystem/src/fnd/frameheap.c
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
|
||||
#include <nitro.h>
|
||||
#include <nnsys/misc.h>
|
||||
#include <nnsys/fnd/frameheap.h>
|
||||
#include <nnsys/fnd/config.h>
|
||||
|
||||
#include "include/heapcommoni.h"
|
||||
|
||||
#define MIN_ALIGNMENT 4
|
||||
|
||||
static NNS_FND_INLINE BOOL IsValidFrmHeapHandle (NNSFndHeapHandle handle) {
|
||||
if (handle == NNS_FND_HEAP_INVALID_HANDLE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = handle;
|
||||
return pHeapHd->signature == NNSI_FRMHEAP_SIGNATURE;
|
||||
}
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndFrmHeapHead * GetFrmHeapHeadPtrFromHeapHead (NNSiFndHeapHead * pHHead) {
|
||||
return AddU32ToPtr(pHHead, sizeof(NNSiFndHeapHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndHeapHead * GetHeapHeadPtrFromFrmHeapHead (NNSiFndFrmHeapHead * pFrmHeapHd) {
|
||||
return SubU32ToPtr(pFrmHeapHd, sizeof(NNSiFndHeapHead));
|
||||
}
|
||||
|
||||
static NNSiFndHeapHead * InitFrameHeap (void * startAddress, void * endAddress, u16 optFlag) {
|
||||
NNSiFndHeapHead * pHeapHd = startAddress;
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
NNSi_FndInitHeapHead(
|
||||
pHeapHd,
|
||||
NNSI_FRMHEAP_SIGNATURE,
|
||||
AddU32ToPtr(pFrmHeapHd, sizeof(NNSiFndFrmHeapHead)),
|
||||
endAddress,
|
||||
optFlag
|
||||
);
|
||||
|
||||
pFrmHeapHd->headAllocator = pHeapHd->heapStart;
|
||||
pFrmHeapHd->tailAllocator = pHeapHd->heapEnd;
|
||||
|
||||
pFrmHeapHd->pState = NULL;
|
||||
|
||||
return pHeapHd;
|
||||
}
|
||||
|
||||
static void * AllocFromHead (NNSiFndFrmHeapHead * pFrmHeapHd, u32 size, int alignment) {
|
||||
void * newBlock = NNSi_FndRoundUpPtr(pFrmHeapHd->headAllocator, alignment);
|
||||
void * endAddress = AddU32ToPtr(newBlock, size);
|
||||
|
||||
if (NNSiGetUIntPtr(endAddress) > NNSiGetUIntPtr(pFrmHeapHd->tailAllocator)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FillAllocMemory(
|
||||
GetHeapHeadPtrFromFrmHeapHead(pFrmHeapHd),
|
||||
pFrmHeapHd->headAllocator,
|
||||
GetOffsetFromPtr(pFrmHeapHd->headAllocator, endAddress)
|
||||
);
|
||||
|
||||
pFrmHeapHd->headAllocator = endAddress;
|
||||
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
static void * AllocFromTail (NNSiFndFrmHeapHead * pFrmHeapHd, u32 size, int alignment) {
|
||||
void * newBlock = NNSi_FndRoundDownPtr(SubU32ToPtr(pFrmHeapHd->tailAllocator, size), alignment);
|
||||
|
||||
if (NNSiGetUIntPtr(newBlock) < NNSiGetUIntPtr(pFrmHeapHd->headAllocator)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FillAllocMemory(
|
||||
GetHeapHeadPtrFromFrmHeapHead(pFrmHeapHd),
|
||||
newBlock,
|
||||
GetOffsetFromPtr(newBlock, pFrmHeapHd->tailAllocator)
|
||||
);
|
||||
|
||||
pFrmHeapHd->tailAllocator = newBlock;
|
||||
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
static void FreeHead (NNSiFndHeapHead * pHeapHd) {
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
FillFreeMemory(
|
||||
pHeapHd,
|
||||
pHeapHd->heapStart,
|
||||
GetOffsetFromPtr(pHeapHd->heapStart, pFrmHeapHd->headAllocator)
|
||||
);
|
||||
|
||||
pFrmHeapHd->headAllocator = pHeapHd->heapStart;
|
||||
pFrmHeapHd->pState = NULL;
|
||||
}
|
||||
|
||||
static void FreeTail (NNSiFndHeapHead * pHeapHd) {
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
FillFreeMemory(
|
||||
pHeapHd,
|
||||
pFrmHeapHd->tailAllocator,
|
||||
GetOffsetFromPtr(pFrmHeapHd->tailAllocator, pHeapHd->heapEnd)
|
||||
);
|
||||
|
||||
{
|
||||
NNSiFndFrmHeapState * pState;
|
||||
for (pState = pFrmHeapHd->pState; pState; pState = pState->pPrevState) {
|
||||
pState->tailAllocator = pHeapHd->heapEnd;
|
||||
}
|
||||
}
|
||||
|
||||
pFrmHeapHd->tailAllocator = pHeapHd->heapEnd;
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static void PrintSize (u32 size, u32 wholeSize) {
|
||||
OS_Printf("%9d (%6.2f%%)", size, 100.0 * size / wholeSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void * NNSi_FndGetFreeStartForFrmHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
return GetFrmHeapHeadPtrFromHeapHead(heap)->headAllocator;
|
||||
}
|
||||
|
||||
void * NNSi_FndGetFreeEndForFrmHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
return GetFrmHeapHeadPtrFromHeapHead(heap)->tailAllocator;
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
void NNSi_FndDumpFrmHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * const pHeapHd = heap;
|
||||
NNSiFndFrmHeapHead * const pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
const u32 heapSize = GetOffsetFromPtr(pHeapHd->heapStart, pHeapHd->heapEnd);
|
||||
|
||||
NNSi_FndDumpHeapHead(pHeapHd);
|
||||
|
||||
OS_Printf(" head [%p - %p) ", pHeapHd->heapStart, pFrmHeapHd->headAllocator);
|
||||
PrintSize(GetOffsetFromPtr(pHeapHd->heapStart, pFrmHeapHd->headAllocator), heapSize);
|
||||
OS_Printf("\n free ");
|
||||
PrintSize(GetOffsetFromPtr(pFrmHeapHd->headAllocator, pFrmHeapHd->tailAllocator), heapSize);
|
||||
OS_Printf("\n tail [%p - %p) ", pFrmHeapHd->tailAllocator, pHeapHd->heapEnd);
|
||||
PrintSize(GetOffsetFromPtr(pFrmHeapHd->tailAllocator, pHeapHd->heapEnd), heapSize);
|
||||
OS_Printf("\n");
|
||||
|
||||
if (pFrmHeapHd->pState) {
|
||||
NNSiFndFrmHeapState * pState;
|
||||
|
||||
OS_Printf(" state : [tag] [head] [tail]\n");
|
||||
|
||||
for (pState = pFrmHeapHd->pState; pState; pState = pState->pPrevState) {
|
||||
OS_Printf(
|
||||
" '%c%c%c%c' : %p %p\n", pState->tagName >> 24, (pState->tagName >> 16) & 0xFF, (pState->tagName >> 8) & 0xFF, pState->tagName & 0xFF,
|
||||
pState->headAllocator, pState->tailAllocator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
OS_Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NNSFndHeapHandle NNS_FndCreateFrmHeapEx (void * startAddress, u32 size, u16 optFlag) {
|
||||
void * endAddress;
|
||||
|
||||
SDK_NULL_ASSERT(startAddress);
|
||||
|
||||
endAddress = NNSi_FndRoundDownPtr(AddU32ToPtr(startAddress, size), MIN_ALIGNMENT);
|
||||
startAddress = NNSi_FndRoundUpPtr(startAddress, MIN_ALIGNMENT);
|
||||
|
||||
if (NNSiGetUIntPtr(startAddress) > NNSiGetUIntPtr(endAddress)
|
||||
|| GetOffsetFromPtr(startAddress, endAddress) < sizeof(NNSiFndHeapHead) + sizeof(NNSiFndFrmHeapHead)
|
||||
) {
|
||||
return NNS_FND_HEAP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHHead = InitFrameHeap(startAddress, endAddress, optFlag);
|
||||
return pHHead;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndDestroyFrmHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
NNSi_FndFinalizeHeap(heap);
|
||||
}
|
||||
|
||||
void * NNS_FndAllocFromFrmHeapEx (NNSFndHeapHandle heap, u32 size, int alignment) {
|
||||
void * memory = NULL;
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd;
|
||||
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
NNS_ASSERT(alignment % MIN_ALIGNMENT == 0);
|
||||
NNS_ASSERT(MIN_ALIGNMENT <= abs(alignment) && abs(alignment) <= 32);
|
||||
|
||||
pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(heap);
|
||||
|
||||
if (size == 0) {
|
||||
size = 1;
|
||||
}
|
||||
|
||||
size = NNSi_FndRoundUp(size, MIN_ALIGNMENT);
|
||||
|
||||
if (alignment >= 0) {
|
||||
memory = AllocFromHead(pFrmHeapHd, size, alignment);
|
||||
} else {
|
||||
memory = AllocFromTail(pFrmHeapHd, size, -alignment);
|
||||
}
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
void NNS_FndFreeToFrmHeap (NNSFndHeapHandle heap, int mode) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
if (mode & NNS_FND_FRMHEAP_FREE_HEAD) {
|
||||
FreeHead(heap);
|
||||
}
|
||||
|
||||
if (mode & NNS_FND_FRMHEAP_FREE_TAIL) {
|
||||
FreeTail(heap);
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndGetAllocatableSizeForFrmHeapEx (NNSFndHeapHandle heap, int alignment) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
NNS_ASSERT(alignment % MIN_ALIGNMENT == 0);
|
||||
NNS_ASSERT(MIN_ALIGNMENT <= abs(alignment) && abs(alignment) <= 32);
|
||||
|
||||
alignment = abs(alignment);
|
||||
|
||||
{
|
||||
const NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(heap);
|
||||
const void * block = NNSi_FndRoundUpPtr(pFrmHeapHd->headAllocator, alignment);
|
||||
|
||||
if (NNSiGetUIntPtr(block) > NNSiGetUIntPtr(pFrmHeapHd->tailAllocator)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetOffsetFromPtr(block, pFrmHeapHd->tailAllocator);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL NNS_FndRecordStateForFrmHeap (NNSFndHeapHandle heap, u32 tagName) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(heap);
|
||||
void * oldHeadAllocator = pFrmHeapHd->headAllocator;
|
||||
|
||||
NNSiFndFrmHeapState * pState = AllocFromHead(pFrmHeapHd, sizeof(NNSiFndFrmHeapState), MIN_ALIGNMENT);
|
||||
if (!pState) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pState->tagName = tagName;
|
||||
pState->headAllocator = oldHeadAllocator;
|
||||
pState->tailAllocator = pFrmHeapHd->tailAllocator;
|
||||
pState->pPrevState = pFrmHeapHd->pState;
|
||||
|
||||
pFrmHeapHd->pState = pState;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL NNS_FndFreeByStateToFrmHeap (NNSFndHeapHandle heap, u32 tagName) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(heap);
|
||||
NNSiFndFrmHeapState * pState = pFrmHeapHd->pState;
|
||||
|
||||
if (tagName != 0) {
|
||||
for (; pState; pState = pState->pPrevState) {
|
||||
if (pState->tagName == tagName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pState) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pFrmHeapHd->headAllocator = pState->headAllocator;
|
||||
pFrmHeapHd->tailAllocator = pState->tailAllocator;
|
||||
|
||||
pFrmHeapHd->pState = pState->pPrevState;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndAdjustFrmHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = heap;
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
if (0 < GetOffsetFromPtr(pFrmHeapHd->tailAllocator, pHeapHd->heapEnd)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pFrmHeapHd->tailAllocator = pHeapHd->heapEnd = pFrmHeapHd->headAllocator;
|
||||
|
||||
return GetOffsetFromPtr(heap, pHeapHd->heapEnd);
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndResizeForMBlockFrmHeap (NNSFndHeapHandle heap, void * memBlock, u32 newSize) {
|
||||
NNSiFndHeapHead * pHeapHd = NULL;
|
||||
NNSiFndFrmHeapHead * pFrmHeapHd = NULL;
|
||||
|
||||
NNS_ASSERT(IsValidFrmHeapHandle(heap));
|
||||
NNS_ASSERT(memBlock == NNSi_FndRoundDownPtr(memBlock, MIN_ALIGNMENT));
|
||||
|
||||
pHeapHd = heap;
|
||||
pFrmHeapHd = GetFrmHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
|
||||
NNS_ASSERT(
|
||||
ComparePtr(pHeapHd->heapStart, memBlock) <= 0
|
||||
&& ComparePtr(pFrmHeapHd->headAllocator, memBlock) > 0
|
||||
);
|
||||
NNS_ASSERT(
|
||||
pFrmHeapHd->pState == NULL
|
||||
|| ComparePtr(pFrmHeapHd->pState, memBlock) < 0
|
||||
);
|
||||
|
||||
if (newSize == 0) {
|
||||
newSize = 1;
|
||||
}
|
||||
newSize = NNSi_FndRoundUp(newSize, MIN_ALIGNMENT);
|
||||
|
||||
{
|
||||
const u32 oldSize = GetOffsetFromPtr(memBlock, pFrmHeapHd->headAllocator);
|
||||
void * endAddress = AddU32ToPtr(memBlock, newSize);
|
||||
|
||||
if (newSize == oldSize) {
|
||||
return newSize;
|
||||
}
|
||||
|
||||
if (newSize > oldSize) {
|
||||
if (ComparePtr(endAddress, pFrmHeapHd->tailAllocator) > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FillAllocMemory(heap, pFrmHeapHd->headAllocator, newSize - oldSize);
|
||||
} else {
|
||||
FillFreeMemory(heap, endAddress, oldSize - newSize);
|
||||
}
|
||||
|
||||
pFrmHeapHd->headAllocator = endAddress;
|
||||
|
||||
return newSize;
|
||||
}
|
||||
}
|
||||
146
lib/NitroSystem/src/fnd/heapcommon.c
Normal file
146
lib/NitroSystem/src/fnd/heapcommon.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#include <nitro.h>
|
||||
#include <nnsys/misc.h>
|
||||
#include <nnsys/fnd/heapcommon.h>
|
||||
#include <nnsys/fnd/expheap.h>
|
||||
#include <nnsys/fnd/frameheap.h>
|
||||
#include <nnsys/fnd/unitheap.h>
|
||||
#include <nnsys/fnd/config.h>
|
||||
|
||||
#include "include/heapcommoni.h"
|
||||
|
||||
static NNSFndList sRootList;
|
||||
static BOOL sRootListInitialized = FALSE;
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
static u32 sFillVals[NNS_FND_HEAP_FILL_MAX] = {
|
||||
0xC3C3C3C3,
|
||||
0xF3F3F3F3,
|
||||
0xD3D3D3D3,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static NNSiFndHeapHead * FindContainHeap (NNSFndList * pList, const void * memBlock) {
|
||||
NNSiFndHeapHead * pHeapHd = NULL;
|
||||
while (NULL != (pHeapHd = NNS_FndGetNextListObject(pList, pHeapHd))) {
|
||||
if (NNSiGetUIntPtr(pHeapHd->heapStart) <= NNSiGetUIntPtr(memBlock)
|
||||
&& NNSiGetUIntPtr(memBlock) < NNSiGetUIntPtr(pHeapHd->heapEnd)
|
||||
) {
|
||||
NNSiFndHeapHead * pChildHeapHd = FindContainHeap(&pHeapHd->childList, memBlock);
|
||||
if (pChildHeapHd) {
|
||||
return pChildHeapHd;
|
||||
}
|
||||
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static NNSFndList * FindListContainHeap (NNSiFndHeapHead * pHeapHd) {
|
||||
NNSFndList * pList = &sRootList;
|
||||
|
||||
NNSiFndHeapHead * pContainHeap = FindContainHeap(&sRootList, pHeapHd);
|
||||
|
||||
if (pContainHeap) {
|
||||
pList = &pContainHeap->childList;
|
||||
}
|
||||
|
||||
return pList;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void DumpHeapList (void) {
|
||||
return;
|
||||
}
|
||||
|
||||
void NNSi_FndInitHeapHead (NNSiFndHeapHead * pHeapHd, u32 signature, void * heapStart, void * heapEnd, u16 optFlag) {
|
||||
pHeapHd->signature = signature;
|
||||
|
||||
pHeapHd->heapStart = heapStart;
|
||||
pHeapHd->heapEnd = heapEnd;
|
||||
|
||||
pHeapHd->attribute = 0;
|
||||
SetOptForHeap(pHeapHd, optFlag);
|
||||
|
||||
FillNoUseMemory(
|
||||
pHeapHd,
|
||||
heapStart,
|
||||
GetOffsetFromPtr(heapStart, heapEnd)
|
||||
);
|
||||
|
||||
NNS_FND_INIT_LIST(&pHeapHd->childList, NNSiFndHeapHead, link);
|
||||
|
||||
if (!sRootListInitialized) {
|
||||
NNS_FND_INIT_LIST(&sRootList, NNSiFndHeapHead, link);
|
||||
sRootListInitialized = TRUE;
|
||||
}
|
||||
|
||||
NNS_FndAppendListObject(FindListContainHeap(pHeapHd), pHeapHd);
|
||||
DumpHeapList();
|
||||
}
|
||||
|
||||
void NNSi_FndFinalizeHeap (NNSiFndHeapHead * pHeapHd) {
|
||||
NNS_FndRemoveListObject(FindListContainHeap(pHeapHd), pHeapHd);
|
||||
DumpHeapList();
|
||||
}
|
||||
|
||||
void NNSi_FndDumpHeapHead (NNSiFndHeapHead * pHeapHd) {
|
||||
OS_Printf("[NNS Foundation ");
|
||||
|
||||
switch (pHeapHd->signature) {
|
||||
case NNSI_EXPHEAP_SIGNATURE: OS_Printf("Exp"); break;
|
||||
case NNSI_FRMHEAP_SIGNATURE: OS_Printf("Frame"); break;
|
||||
case NNSI_UNTHEAP_SIGNATURE: OS_Printf("Unit"); break;
|
||||
default:
|
||||
NNS_ASSERT(FALSE);
|
||||
}
|
||||
|
||||
OS_Printf(" Heap]\n");
|
||||
|
||||
OS_Printf(" whole [%p - %p)\n", pHeapHd, pHeapHd->heapEnd);
|
||||
}
|
||||
|
||||
NNSFndHeapHandle NNS_FndFindContainHeap (const void * memBlock) {
|
||||
return FindContainHeap(&sRootList, memBlock);
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
void NNS_FndDumpHeap (NNSFndHeapHandle heap) {
|
||||
NNSiFndHeapHead * pHeapHd = heap;
|
||||
switch (pHeapHd->signature) {
|
||||
case NNSI_EXPHEAP_SIGNATURE: NNSi_FndDumpExpHeap(heap); break;
|
||||
case NNSI_FRMHEAP_SIGNATURE: NNSi_FndDumpFrmHeap(heap); break;
|
||||
case NNSI_UNTHEAP_SIGNATURE: NNSi_FndDumpUnitHeap(heap); break;
|
||||
default:
|
||||
OS_Printf("[NNS Foundation] dump heap : unknown heap. - %p\n", heap);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
u32 NNS_FndSetFillValForHeap (int type, u32 val) {
|
||||
NNS_ASSERT(type < NNS_FND_HEAP_FILL_MAX);
|
||||
|
||||
{
|
||||
u32 oldVal = sFillVals[type];
|
||||
sFillVals[type] = val;
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
u32 NNS_FndGetFillValForHeap (int type) {
|
||||
NNS_ASSERT(type < NNS_FND_HEAP_FILL_MAX);
|
||||
|
||||
return sFillVals[type];
|
||||
}
|
||||
|
||||
#endif
|
||||
154
lib/NitroSystem/src/fnd/include/heapcommoni.h
Normal file
154
lib/NitroSystem/src/fnd/include/heapcommoni.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
#ifndef NNS_FND_HEAPCOMMONI_H_
|
||||
#define NNS_FND_HEAPCOMMONI_H_
|
||||
|
||||
#include <nitro/types.h>
|
||||
#include <nnsys/fnd/config.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef s32 NNSiIntPtr;
|
||||
typedef u32 NNSiUIntPtr;
|
||||
|
||||
#define NNSi_FndRoundUp(value, alignment) \
|
||||
(((value) + (alignment - 1)) & ~(alignment - 1))
|
||||
|
||||
#define NNSi_FndRoundUpPtr(ptr, alignment) \
|
||||
((void *)NNSi_FndRoundUp(NNSiGetUIntPtr(ptr), alignment))
|
||||
|
||||
#define NNSi_FndRoundDown(value, alignment) \
|
||||
((value) & ~(alignment - 1))
|
||||
|
||||
#define NNSi_FndRoundDownPtr(ptr, alignment) \
|
||||
((void *)NNSi_FndRoundDown(NNSiGetUIntPtr(ptr), alignment))
|
||||
|
||||
#define NNSi_FndGetBitValue(data, st, bits) \
|
||||
(((data) >> (st)) & ((1 << (bits)) - 1))
|
||||
|
||||
#define NNSi_FndSetBitValue(data, st, bits, val) \
|
||||
do \
|
||||
{ \
|
||||
u32 maskBits = (u32)((1 << (bits)) - 1); \
|
||||
u32 newVal = (val) & maskBits; \
|
||||
(void)(maskBits <<= st); \
|
||||
(data) &= ~maskBits; \
|
||||
(data) |= newVal << (st); \
|
||||
} while (FALSE);
|
||||
|
||||
NNS_FND_INLINE NNSiUIntPtr NNSiGetUIntPtr (const void * ptr)
|
||||
{
|
||||
return (NNSiUIntPtr)ptr;
|
||||
}
|
||||
|
||||
NNS_FND_INLINE u32 GetOffsetFromPtr (const void * start, const void * end)
|
||||
{
|
||||
return NNSiGetUIntPtr(end) - NNSiGetUIntPtr(start);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE void * AddU32ToPtr (void * ptr, u32 val)
|
||||
{
|
||||
return (void *)(NNSiGetUIntPtr(ptr) + val);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE const void * AddU32ToCPtr (const void * ptr, u32 val)
|
||||
{
|
||||
return (const void *)(NNSiGetUIntPtr(ptr) + val);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE void * SubU32ToPtr (void * ptr, u32 val)
|
||||
{
|
||||
return (void *)(NNSiGetUIntPtr(ptr) - val);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE const void * SubU32ToCPtr (const void * ptr, u32 val)
|
||||
{
|
||||
return (const void *)(NNSiGetUIntPtr(ptr) - val);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE int ComparePtr (const void * a, const void * b)
|
||||
{
|
||||
const u8 * wa = a;
|
||||
const u8 * wb = b;
|
||||
|
||||
return wa - wb;
|
||||
}
|
||||
|
||||
NNS_FND_INLINE u16 GetOptForHeap (const NNSiFndHeapHead * pHeapHd)
|
||||
{
|
||||
return (u16)NNSi_FndGetBitValue(pHeapHd->attribute, 0, 8);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE void SetOptForHeap (
|
||||
NNSiFndHeapHead * pHeapHd,
|
||||
u16 optFlag
|
||||
)
|
||||
{
|
||||
NNSi_FndSetBitValue(pHeapHd->attribute, 0, 8, optFlag);
|
||||
}
|
||||
|
||||
NNS_FND_INLINE void FillAllocMemory (
|
||||
NNSiFndHeapHead * pHeapHd,
|
||||
void * address,
|
||||
u32 size
|
||||
)
|
||||
{
|
||||
if (GetOptForHeap(pHeapHd) & NNS_FND_HEAP_OPT_0_CLEAR) {
|
||||
MI_CpuFill32(address, 0, size);
|
||||
} else {
|
||||
#if !defined(NNS_FINALROM)
|
||||
if (GetOptForHeap(pHeapHd) & NNS_FND_HEAP_OPT_DEBUG_FILL) {
|
||||
MI_CpuFill32(address, NNS_FndGetFillValForHeap(NNS_FND_HEAP_FILL_ALLOC), size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(NNS_FINALROM)
|
||||
#define FillFreeMemory(pHeapHd, address, size) ((void)0)
|
||||
#else
|
||||
NNS_FND_INLINE void FillFreeMemory (
|
||||
NNSiFndHeapHead * pHeapHd,
|
||||
void * address,
|
||||
u32 size
|
||||
)
|
||||
{
|
||||
if (GetOptForHeap(pHeapHd) & NNS_FND_HEAP_OPT_DEBUG_FILL) {
|
||||
MI_CpuFill32(address, NNS_FndGetFillValForHeap(NNS_FND_HEAP_FILL_FREE), size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NNS_FINALROM)
|
||||
#define FillNoUseMemory(pHeapHd, address, size) ((void)0)
|
||||
#else
|
||||
NNS_FND_INLINE void FillNoUseMemory (
|
||||
NNSiFndHeapHead * pHeapHd,
|
||||
void * address,
|
||||
u32 size
|
||||
)
|
||||
{
|
||||
if (GetOptForHeap(pHeapHd) & NNS_FND_HEAP_OPT_DEBUG_FILL) {
|
||||
MI_CpuFill32(address, NNS_FndGetFillValForHeap(NNS_FND_HEAP_FILL_NOUSE), size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void NNSi_FndInitHeapHead(
|
||||
NNSiFndHeapHead * pHeapHd,
|
||||
u32 signature,
|
||||
void * heapStart,
|
||||
void * heapEnd,
|
||||
u16 optFlag);
|
||||
|
||||
void NNSi_FndFinalizeHeap(
|
||||
NNSiFndHeapHead * pHeapHd);
|
||||
|
||||
void NNSi_FndDumpHeapHead(
|
||||
NNSiFndHeapHead * pHeapHd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
141
lib/NitroSystem/src/fnd/list_nnsfnd.c
Normal file
141
lib/NitroSystem/src/fnd/list_nnsfnd.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include <nnsys/misc.h>
|
||||
#include <nnsys/fnd/list.h>
|
||||
|
||||
#define OBJ_TO_LINK(list, obj) ((NNSFndLink *)(((u32)(obj)) + (list)->offset))
|
||||
|
||||
void NNS_FndInitList (NNSFndList * list, u16 offset) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
|
||||
list->headObject = NULL;
|
||||
list->tailObject = NULL;
|
||||
list->numObjects = 0;
|
||||
list->offset = offset;
|
||||
}
|
||||
|
||||
static void SetFirstObject (NNSFndList * list, void * object) {
|
||||
NNSFndLink * link;
|
||||
|
||||
NNS_NULL_ASSERT(list);
|
||||
NNS_NULL_ASSERT(object);
|
||||
|
||||
link = OBJ_TO_LINK(list, object);
|
||||
|
||||
link->nextObject = NULL;
|
||||
link->prevObject = NULL;
|
||||
list->headObject = object;
|
||||
list->tailObject = object;
|
||||
list->numObjects++;
|
||||
}
|
||||
|
||||
void NNS_FndAppendListObject (NNSFndList * list, void * object) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
NNS_NULL_ASSERT(object);
|
||||
|
||||
if (list->headObject == NULL) {
|
||||
SetFirstObject(list, object);
|
||||
} else {
|
||||
NNSFndLink * link = OBJ_TO_LINK(list, object);
|
||||
|
||||
link->prevObject = list->tailObject;
|
||||
link->nextObject = NULL;
|
||||
|
||||
OBJ_TO_LINK(list, list->tailObject)->nextObject = object;
|
||||
list->tailObject = object;
|
||||
list->numObjects++;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndPrependListObject (NNSFndList * list, void * object) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
NNS_NULL_ASSERT(object);
|
||||
|
||||
if (list->headObject == NULL) {
|
||||
SetFirstObject(list, object);
|
||||
} else {
|
||||
NNSFndLink * link = OBJ_TO_LINK(list, object);
|
||||
|
||||
link->prevObject = NULL;
|
||||
link->nextObject = list->headObject;
|
||||
|
||||
OBJ_TO_LINK(list, list->headObject)->prevObject = object;
|
||||
list->headObject = object;
|
||||
list->numObjects++;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndInsertListObject (NNSFndList * list, void * target, void * object) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
NNS_NULL_ASSERT(object);
|
||||
|
||||
if (target == NULL) {
|
||||
NNS_FndAppendListObject(list, object);
|
||||
} else if (target == list->headObject) {
|
||||
NNS_FndPrependListObject(list, object);
|
||||
} else {
|
||||
NNSFndLink * link = OBJ_TO_LINK(list, object);
|
||||
void * prevObj = OBJ_TO_LINK(list, target)->prevObject;
|
||||
NNSFndLink * prevLnk = OBJ_TO_LINK(list, prevObj);
|
||||
|
||||
link->prevObject = prevObj;
|
||||
link->nextObject = target;
|
||||
prevLnk->nextObject = object;
|
||||
OBJ_TO_LINK(list, target)->prevObject = object;
|
||||
list->numObjects++;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndRemoveListObject (NNSFndList * list, void * object) {
|
||||
NNSFndLink * link;
|
||||
|
||||
NNS_NULL_ASSERT(list);
|
||||
NNS_NULL_ASSERT(object);
|
||||
|
||||
link = OBJ_TO_LINK(list, object);
|
||||
|
||||
if (link->prevObject == NULL) {
|
||||
list->headObject = link->nextObject;
|
||||
} else {
|
||||
OBJ_TO_LINK(list, link->prevObject)->nextObject = link->nextObject;
|
||||
}
|
||||
if (link->nextObject == NULL) {
|
||||
list->tailObject = link->prevObject;
|
||||
} else {
|
||||
OBJ_TO_LINK(list, link->nextObject)->prevObject = link->prevObject;
|
||||
}
|
||||
link->prevObject = NULL;
|
||||
link->nextObject = NULL;
|
||||
list->numObjects--;
|
||||
}
|
||||
|
||||
void * NNS_FndGetNextListObject (NNSFndList * list, void * object) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
|
||||
if (object == NULL) {
|
||||
return list->headObject;
|
||||
}
|
||||
return OBJ_TO_LINK(list, object)->nextObject;
|
||||
}
|
||||
|
||||
void * NNS_FndGetPrevListObject (NNSFndList * list, void * object) {
|
||||
NNS_NULL_ASSERT(list);
|
||||
|
||||
if (object == NULL) {
|
||||
return list->tailObject;
|
||||
}
|
||||
return OBJ_TO_LINK(list, object)->prevObject;
|
||||
}
|
||||
|
||||
void * NNS_FndGetNthListObject (NNSFndList * list, u16 index) {
|
||||
int count = 0;
|
||||
NNSFndLink * object = NULL;
|
||||
|
||||
NNS_NULL_ASSERT(list);
|
||||
|
||||
while ((object = NNS_FndGetNextListObject(list, object)) != NULL) {
|
||||
if (index == count) {
|
||||
return object;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
172
lib/NitroSystem/src/fnd/unitheap.c
Normal file
172
lib/NitroSystem/src/fnd/unitheap.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#include <nitro.h>
|
||||
#include <nnsys/misc.h>
|
||||
#include <nnsys/fnd/unitheap.h>
|
||||
#include <nnsys/fnd/config.h>
|
||||
|
||||
#include "include/heapcommoni.h"
|
||||
|
||||
#define MIN_ALIGNMENT 4
|
||||
|
||||
static NNSiFndUntHeapMBlockHead * PopMBlock (NNSiFndUntMBlockList * list) {
|
||||
NNSiFndUntHeapMBlockHead * block = list->head;
|
||||
if (block) {
|
||||
list->head = block->pMBlkHdNext;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE void PushMBlock (NNSiFndUntMBlockList * list, NNSiFndUntHeapMBlockHead * block) {
|
||||
block->pMBlkHdNext = list->head;
|
||||
list->head = block;
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE NNSiFndUntHeapHead * GetUnitHeapHeadPtrFromHeapHead (NNSiFndHeapHead * pHeapHd) {
|
||||
return AddU32ToPtr(pHeapHd, sizeof(NNSiFndHeapHead));
|
||||
}
|
||||
|
||||
static NNS_FND_INLINE BOOL IsValidUnitHeapHandle (NNSFndHeapHandle handle) {
|
||||
if (handle == NNS_FND_HEAP_INVALID_HANDLE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * pHeapHd = handle;
|
||||
return pHeapHd->signature == NNSI_UNTHEAP_SIGNATURE;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NNS_FINALROM)
|
||||
|
||||
void NNSi_FndDumpUnitHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidUnitHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndHeapHead * const pHeapHd = heap;
|
||||
NNSiFndUntHeapHead * const pUnitHeapHd = GetUnitHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
const u32 heapSize = GetOffsetFromPtr(pHeapHd->heapStart, pHeapHd->heapEnd);
|
||||
|
||||
const u32 freeSize = NNS_FndCountFreeBlockForUnitHeap(heap) * pUnitHeapHd->mBlkSize;
|
||||
const u32 usedSize = heapSize - freeSize;
|
||||
|
||||
NNSi_FndDumpHeapHead(pHeapHd);
|
||||
|
||||
OS_Printf(
|
||||
" %d / %d bytes (%6.2f%%) used\n",
|
||||
usedSize, heapSize, 100.0f * usedSize / heapSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NNSFndHeapHandle NNS_FndCreateUnitHeapEx (void * startAddress, u32 heapSize, u32 memBlockSize, int alignment, u16 optFlag) {
|
||||
NNSiFndHeapHead * pHeapHd;
|
||||
void * heapEnd;
|
||||
|
||||
SDK_NULL_ASSERT(startAddress);
|
||||
|
||||
NNS_ASSERT(alignment % MIN_ALIGNMENT == 0);
|
||||
NNS_ASSERT(MIN_ALIGNMENT <= alignment && alignment <= 32);
|
||||
|
||||
pHeapHd = NNSi_FndRoundUpPtr(startAddress, MIN_ALIGNMENT);
|
||||
heapEnd = NNSi_FndRoundDownPtr(AddU32ToPtr(startAddress, heapSize), MIN_ALIGNMENT);
|
||||
|
||||
if (ComparePtr(pHeapHd, heapEnd) > 0) {
|
||||
return NNS_FND_HEAP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
memBlockSize = NNSi_FndRoundUp(memBlockSize, alignment);
|
||||
|
||||
{
|
||||
NNSiFndUntHeapHead * pUntHeapHd = GetUnitHeapHeadPtrFromHeapHead(pHeapHd);
|
||||
void * heapStart = NNSi_FndRoundUpPtr(AddU32ToPtr(pUntHeapHd, sizeof(NNSiFndUntHeapHead)), alignment);
|
||||
u32 elementNum;
|
||||
|
||||
if (ComparePtr(heapStart, heapEnd) > 0) {
|
||||
return NNS_FND_HEAP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
elementNum = GetOffsetFromPtr(heapStart, heapEnd) / memBlockSize;
|
||||
if (elementNum == 0) {
|
||||
return NNS_FND_HEAP_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
heapEnd = AddU32ToPtr(heapStart, elementNum * memBlockSize);
|
||||
|
||||
NNSi_FndInitHeapHead(
|
||||
pHeapHd,
|
||||
NNSI_UNTHEAP_SIGNATURE,
|
||||
heapStart,
|
||||
heapEnd,
|
||||
optFlag
|
||||
);
|
||||
|
||||
pUntHeapHd->mbFreeList.head = heapStart;
|
||||
pUntHeapHd->mBlkSize = memBlockSize;
|
||||
|
||||
{
|
||||
NNSiFndUntHeapMBlockHead * pMBlkHd = pUntHeapHd->mbFreeList.head;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < elementNum - 1; ++i, pMBlkHd = pMBlkHd->pMBlkHdNext) {
|
||||
pMBlkHd->pMBlkHdNext = AddU32ToPtr(pMBlkHd, memBlockSize);
|
||||
}
|
||||
|
||||
pMBlkHd->pMBlkHdNext = NULL;
|
||||
}
|
||||
|
||||
return pHeapHd;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndDestroyUnitHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidUnitHeapHandle(heap));
|
||||
NNSi_FndFinalizeHeap(heap);
|
||||
}
|
||||
|
||||
void * NNS_FndAllocFromUnitHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidUnitHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndUntHeapHead * pUntHeapHd = GetUnitHeapHeadPtrFromHeapHead(heap);
|
||||
NNSiFndUntHeapMBlockHead * pMBlkHd = PopMBlock(&pUntHeapHd->mbFreeList);
|
||||
|
||||
if (pMBlkHd) {
|
||||
FillAllocMemory(heap, pMBlkHd, pUntHeapHd->mBlkSize);
|
||||
}
|
||||
|
||||
return pMBlkHd;
|
||||
}
|
||||
}
|
||||
|
||||
void NNS_FndFreeToUnitHeap (NNSFndHeapHandle heap, void * memBlock) {
|
||||
NNS_ASSERT(IsValidUnitHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndUntHeapHead * pUntHeapHd = GetUnitHeapHeadPtrFromHeapHead(heap);
|
||||
|
||||
FillFreeMemory(heap, memBlock, pUntHeapHd->mBlkSize);
|
||||
PushMBlock(&pUntHeapHd->mbFreeList, memBlock);
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndCountFreeBlockForUnitHeap (NNSFndHeapHandle heap) {
|
||||
NNS_ASSERT(IsValidUnitHeapHandle(heap));
|
||||
|
||||
{
|
||||
NNSiFndUntHeapHead * pUntHeapHd = GetUnitHeapHeadPtrFromHeapHead(heap);
|
||||
NNSiFndUntHeapMBlockHead * pMBlkHd = pUntHeapHd->mbFreeList.head;
|
||||
u32 cnt = 0;
|
||||
|
||||
for (; pMBlkHd; pMBlkHd = pMBlkHd->pMBlkHdNext) {
|
||||
++cnt;
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
|
||||
u32 NNS_FndCalcHeapSizeForUnitHeap (u32 memBlockSize, u32 memBlockNum, int alignment) {
|
||||
return sizeof(NNSiFndHeapHead) + sizeof(NNSiFndUntHeapHead) + (alignment - 4) + memBlockNum * NNSi_FndRoundUp(memBlockSize, alignment);
|
||||
}
|
||||
10
main.lsf
10
main.lsf
|
|
@ -379,11 +379,11 @@ Static main
|
|||
Object lib/NitroDWC/asm/base/dwc_account.o
|
||||
Object asm/unk_020A490C.o
|
||||
Object asm/unk_020A4A34.o
|
||||
Object lib/NitroSystem/asm/fnd/list_nnsfnd.o
|
||||
Object lib/NitroSystem/asm/fnd/heapcommon.o
|
||||
Object lib/NitroSystem/asm/fnd/expheap.o
|
||||
Object lib/NitroSystem/asm/fnd/frameheap.o
|
||||
Object lib/NitroSystem/asm/fnd/unitheap.o
|
||||
Object lib/NitroSystem/src/fnd/list_nnsfnd.o
|
||||
Object lib/NitroSystem/src/fnd/heapcommon.o
|
||||
Object lib/NitroSystem/src/fnd/expheap.o
|
||||
Object lib/NitroSystem/src/fnd/frameheap.o
|
||||
Object lib/NitroSystem/src/fnd/unitheap.o
|
||||
Object lib/NitroSystem/src/fnd/allocator.o
|
||||
Object lib/NitroSystem/asm/gfd/gfd_texvramman.o
|
||||
Object lib/NitroSystem/asm/gfd/gfd_plttvramman.o
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user