summaryrefslogtreecommitdiff
path: root/src/code_801DAAE0.cpp
blob: 8d1563f63ad71cd7cf46e2afa9a9293228b36351 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include "ctorStruct.h"
#include <string.h>
#include <SDK/mem.h>
#include "code_801DAAE0.h"

namespace
{
    struct unkClass
    {
        u8 unk0;
        MEMHeapHandle unk4;
        u32 unk8;
    };

    struct unkClass2
    {
        MEMHeapHandle heap;
        u16 groupID;
        u32 unk8;
    };
}

static unkClass* func_801DAAE0(void);
static void* lbl_801DAC9C(MEMHeapHandle heap, u32 size, int fill);
static BOOL func_801DAD1C(MEMHeapHandle heap, void* memBlock, u32 size);
static u32 func_801DAD60(MEMHeapHandle heap);
static void lbl_801DAF1C(void* memBlock, MEMHeapHandle, u32 p3);

static const size_t ARR_SIZE = 16;
static unkClass gUnk804912B0[ARR_SIZE];
static ctorStruct gUnk8063F2D0(1, 4, 0);
static u8 gUnk8063F2D6;
static u8 gUnk8063F2D7;
static MEMHeapHandle gUnk8063F2D8;
static u16 gUnk8063F2DC;

extern "C" {

static unkClass* func_801DAAE0(void)
{
    for (u32 i = 0; i < ARR_SIZE; i++)
        if (gUnk804912B0[i].unk0 == 0)
            return &gUnk804912B0[i];
    return NULL;
}

BOOL func_801DAB28(void)
{
    return gUnk8063F2D6;
}

void func_801DAB30(void)
{
    memset(gUnk804912B0, 0, sizeof(gUnk804912B0));
    gUnk8063F2D8 = 0;
    gUnk8063F2DC = 0;
    gUnk8063F2D6 = 1;
    gUnk8063F2D7 = 0;
}

MEMHeapHandle func_801DAB78(void* p1, u32 p2, u16 p3)
{
    if (!func_801DAB28())
        return 0;
    unkClass* r31 = func_801DAAE0();
    if (!r31)
        return 0;
    MEMHeapHandle r3 = MEMCreateExpHeapEx(p1, p2, p3);
    r31->unk0 = 1;
    r31->unk4 = r3;
    r31->unk8 = p2;
    return r3;
}

MEMHeapHandle func_801DAC0C(void)
{
    return gUnk8063F2D8;
}

MEMHeapHandle func_801DAC14(MEMHeapHandle p1)
{
    MEMHeapHandle r3 = func_801DAC0C();
    gUnk8063F2D8 = p1;
    return r3;
}

u16 func_801DAC44(u16 p1)
{
    u16 r31 = gUnk8063F2DC;
    gUnk8063F2DC = p1;
    MEMSetGroupIDForExpHeap(lbl_8063E8E8, (u16)(p1 & 0xff));
    MEMSetGroupIDForExpHeap(lbl_8063E8EC, (u16)(gUnk8063F2DC & 0xff));
    return r31;
}

u16 func_801DAC90(MEMHeapHandle heap, u16 groupID)
{
    return MEMSetGroupIDForExpHeap(heap, groupID);
}

// "new" used in combination with func_801DAD48
void* func_801DAC94(MEMHeapHandle heap, u32 size)
{
    return MEMAllocFromExpHeapEx(heap, size, 32);
}

static void* lbl_801DAC9C(MEMHeapHandle heap, u32 size, int fill)
{
    void* r31 = func_801DAC94(heap, size);
    if (!r31)
        return NULL;
    memset(r31, fill, size);
    return r31;
}

void* func_801DAD00(MEMHeapHandle heap, u32 size)
{
    return lbl_801DAC9C(heap, size, 0);
}

void* func_801DAD08(MEMHeapHandle heap, u32 size, int alignment)
{
    return MEMAllocFromExpHeapEx(heap, size, alignment);
}

void* func_801DAD0C(MEMHeapHandle heap, u32 size, int alignment)
{
    return MEMAllocFromExpHeapEx(heap, size, (alignment > 0) ? -alignment : alignment);
}

static BOOL func_801DAD1C(MEMHeapHandle heap, void* memBlock, u32 size)
{
    return MEMResizeForMBlockExpHeap(heap, memBlock, size) != 0;
}

// TODO: another "delete" that seems to be called in some destructors
// see func_8016E5C0 for a destructor that calls both this and global operator delete
void func_801DAD48(MEMHeapHandle heap, void* memBlock)
{
    if (memBlock)
        MEMFreeToExpHeap(heap, memBlock);
}

u32 func_801DAD58(u32, const void* memBlock)
{
    return MEMGetSizeForMBlockExpHeap(memBlock);
}

static u32 func_801DAD60(MEMHeapHandle heap)
{
    return MEMGetTotalFreeSizeForExpHeap(heap);
}

void* func_801DAD64(size_t size)
{
    return func_801DAC94(func_801DAC0C(), size);
}

void* func_801DAD98(u32 size)
{
    return func_801DAD00(func_801DAC0C(), size);
}

void* func_801DADCC(u32 size, int alignment)
{
    return func_801DAD08(func_801DAC0C(), size, alignment);
}

void* func_801DAE10(u32 size, int alignment)
{
    return func_801DAD08(func_801DAC0C(), size, (alignment > 0) ? -alignment : alignment);
}

BOOL func_801DAE60(void* memBlock, u32 size)
{
    return func_801DAD1C(func_801DAC0C(), memBlock, size);
}

void func_801DAEA4(void* memBlock)
{
    if (memBlock)
        func_801DAD48(func_801DAC0C(), memBlock);
}

u32 func_801DAEE0(const void* memBlock)
{
    if (memBlock == NULL)
        return 0;
    return MEMGetSizeForMBlockExpHeap(memBlock);
}

u32 func_801DAEF8(void)
{
    return func_801DAD60(func_801DAC0C());
}

static void lbl_801DAF1C(void* memBlock, MEMHeapHandle, u32 p3)
{
    if (MEMGetGroupIDForMBlockExpHeap(memBlock) == ((unkClass2 *)p3)->groupID)
        MEMFreeToExpHeap(((unkClass2 *)p3)->heap, memBlock);
}

void func_801DAF70(MEMHeapHandle heap, u16 groupID)
{
    unkClass2 param;
    param.heap = heap;
    param.groupID = groupID;
    param.unk8 = 0;
    MEMVisitAllocatedForExpHeap(heap, lbl_801DAF1C, (u32)&param);
}

void func_801DAFAC(register u32* dest, register const u32* src, register size_t n)
{
    if ((u32)dest & 0x1f || (u32)src & 0x1f || n & 0x1f) {
        memcpy(dest, src, n);
    } else {
        n /= 32;
        #ifdef NONMATCHING
        // 1. instruction order of loads and stores is not right
        // 2. branch instruction should be bdnz, not bne
        dest--;
        src--;
        do
        {
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
            *++dest = *++src;
        } while (--n > 0);
        #else
        // Note: reg0 prevents the previous if condition from using 
        // r12 as its scratch register instead of r0
        register u32 reg0;
        asm
        {
            mtctr n
            addi r3, dest, -4
            addi r4, src, -4
        lbl_801DAFD8:
            lwzu reg0, 4(r4)
            lwzu r5, 4(r4)
            lwzu r6, 4(r4)
            lwzu r7, 4(r4)
            lwzu r8, 4(r4)
            lwzu r9, 4(r4)
            lwzu r10, 4(r4)
            lwzu r11, 4(r4)
            stwu reg0, 4(r3)
            stwu r5, 4(r3)
            stwu r6, 4(r3)
            stwu r7, 4(r3)
            stwu r8, 4(r3)
            stwu r9, 4(r3)
            stwu r10, 4(r3)
            stwu r11, 4(r3)
            bdnz lbl_801DAFD8
        }
        #pragma peephole on
        #endif
    }
}

} //extern "C"