mirror of
https://github.com/pret/pmd-red.git
synced 2026-08-07 03:04:38 -05:00
557 lines
12 KiB
C
557 lines
12 KiB
C
#include "global.h"
|
|
#include "music.h"
|
|
#include "memory.h"
|
|
#include "cpu.h"
|
|
|
|
void Hang(void)
|
|
{
|
|
while(1)
|
|
{
|
|
asm("swi 0x2");
|
|
}
|
|
}
|
|
|
|
// Unused
|
|
void sub_800D098(void)
|
|
{
|
|
u32 dispcnt_save;
|
|
u32 ie_store;
|
|
|
|
while(REG_VCOUNT < 160)
|
|
;
|
|
|
|
// Save DISPCNT and set to 0
|
|
dispcnt_save = REG_DISPCNT;
|
|
REG_DISPCNT = 0;
|
|
|
|
*(u16 *)BG_PLTT = 0xefff;
|
|
|
|
while(REG_KEYINPUT != KEYS_MASK)
|
|
;
|
|
|
|
|
|
REG_IME = 0;
|
|
|
|
// Save IE Register
|
|
ie_store = REG_IE;
|
|
REG_IE = INTR_FLAG_KEYPAD | INTR_FLAG_GAMEPAK;
|
|
|
|
REG_KEYCNT = 0xC304; // TODO 1100 0011 0000 0100
|
|
// Select:
|
|
// * Select button
|
|
// * L/R Button
|
|
// Enable IRQ
|
|
// Logical AND
|
|
// So do something when all buttons above are pressed
|
|
|
|
REG_IME = 1;
|
|
|
|
SoundBiasReset();
|
|
asm("swi 0x3");
|
|
SoundBiasSet();
|
|
|
|
REG_IME = 0;
|
|
|
|
REG_IE = ie_store; // restore IE
|
|
REG_KEYCNT = 0; // reset KEYCNT
|
|
|
|
REG_IME = 1;
|
|
|
|
while(REG_VCOUNT < 160){}
|
|
REG_DISPCNT = dispcnt_save; // restore DISPCNT
|
|
while(REG_KEYINPUT != KEYS_MASK){} // All buttons
|
|
}
|
|
|
|
// arm9.bin::02007FF8
|
|
void sprintfStatic(char *buffer, const char *text, ...)
|
|
{
|
|
va_list vArgv;
|
|
va_start(vArgv, text);
|
|
vsprintf(buffer, text, vArgv);
|
|
va_end(vArgv);
|
|
}
|
|
|
|
// Unused
|
|
void sub_800D16C(const char *text, ...)
|
|
{
|
|
char buffer[1024];
|
|
va_list vArgv;
|
|
va_start(vArgv, text);
|
|
vsprintf(buffer, text, vArgv);
|
|
va_end(vArgv);
|
|
}
|
|
|
|
// Unused
|
|
void sub_800D10A(const char *r0, u32 r1, u32 r2, u32 r3, ...)
|
|
{
|
|
}
|
|
|
|
void nullsub_183(void)
|
|
{
|
|
}
|
|
|
|
void nullsub_188(void)
|
|
{
|
|
}
|
|
|
|
void nullsub_184(void)
|
|
{
|
|
}
|
|
|
|
u32 sub_800D1B4(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
u32 sub_800D1B8(u32 r0, u32 r1, u32 r2)
|
|
{
|
|
return r2;
|
|
}
|
|
|
|
void nullsub_187(void)
|
|
{
|
|
}
|
|
|
|
// New file?
|
|
union PtrU16U8
|
|
{
|
|
u16 *asU16;
|
|
u8 *asU8;
|
|
};
|
|
|
|
// Important note: This struct is used in arm_funcs.s, which means the offsets of this struct's memebers CANNOT be changed, unless sub_80001E8 and sub_8000228 are accordingly changed.
|
|
struct UnkStruct_202DCF8
|
|
{
|
|
u8 unk0;
|
|
u8 unk1;
|
|
u8 unk2;
|
|
u8 unk3;
|
|
s32 unk4;
|
|
u8 unk8;
|
|
u8 unk9;
|
|
u8 unkA;
|
|
u8 unkB;
|
|
u8 fillC[0x14-0xC];
|
|
s32 unk14;
|
|
s32 unk18[4];
|
|
union PtrU16U8 unk28;
|
|
u16 *unk2C;
|
|
u16 *unk30[4];
|
|
u16 *unk40[4];
|
|
u16 *unk50[4];
|
|
u16 unk60[12];
|
|
u16 unk78[12];
|
|
u16 unk90[2][3][12];
|
|
};
|
|
|
|
EWRAM_DATA static u16 gUnknown_202D808[132] = {0};
|
|
EWRAM_DATA static u16 gUnknown_202D910[2][132] = {0};
|
|
EWRAM_DATA static u16 gUnknown_202DB20[8] = {0};
|
|
EWRAM_DATA static u16 gUnknown_202DB30[2][8] = {0};
|
|
EWRAM_DATA static u32 gUnknown_202DB50[2] = {0}; // Only first index used
|
|
EWRAM_DATA static u32 gUnknown_202DB58[2] = {0};
|
|
EWRAM_DATA static u32 gUnknown_202DB60[2] = {0};
|
|
EWRAM_DATA static u32 gUnknown_202DB68 = 0;
|
|
EWRAM_DATA static s32 gUnknown_202DB6C = 0;
|
|
EWRAM_DATA static u8 gUnknown_202DB70 = 0;
|
|
EWRAM_DATA static u32 gUnknown_202DB74 = 0;
|
|
// These should not be in EWRAM, but in IWRAM...
|
|
EWRAM_DATA u32 gUnknown_202DB78[16] = {0};
|
|
EWRAM_DATA u32 gUnknown_202DBB8[80] = {0};
|
|
|
|
EWRAM_DATA struct UnkStruct_202DCF8 gUnknown_202DCF8 = {0};
|
|
|
|
extern u32 sub_80001E8(void);
|
|
extern void sub_8000228(void);
|
|
|
|
void sub_800D6AC(void);
|
|
void sub_800D7D0(void);
|
|
static u32 sub_800D820(u16 *a0, u16 a1[2][8]);
|
|
static void sub_800D7B8(void);
|
|
static void sub_800D944(u16 *a0);
|
|
static u32 sub_800D9B8(u16 dst[2][8]);
|
|
|
|
bool8 sub_800D1C0(u32 unused)
|
|
{
|
|
if(gUnknown_202DB60[0] != 2)
|
|
return FALSE;
|
|
if(gUnknown_202DB60[1] != 2)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
static void sub_800D1E0(void)
|
|
{
|
|
s32 iVar1;
|
|
u32 iVar2;
|
|
for(iVar1 = 0; iVar1 < 2; iVar1++)
|
|
{
|
|
for(iVar2 = 0; iVar2 < 8; iVar2++)
|
|
{
|
|
if(gUnknown_202DB30[iVar1][iVar2] == 0xfdfd)
|
|
{
|
|
gUnknown_202DB60[iVar1] = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void sub_800D224(s32 a0)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
if (((a0 >> i) & 1) && gUnknown_202DB60[i] == 1) {
|
|
u32 j;
|
|
u16 *ptr = gUnknown_202D910[i];
|
|
|
|
for (j = 0; j < 8; j++) {
|
|
if (gUnknown_202DB58[i] + j >= gUnknown_202DB74 / 2) {
|
|
gUnknown_202DB60[i] = 2;
|
|
break;
|
|
}
|
|
ptr[gUnknown_202DB58[i] + j] = gUnknown_202DB30[i][j];
|
|
}
|
|
|
|
gUnknown_202DB58[i] += 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void sub_800D2EC(u32 unused)
|
|
{
|
|
u32 i;
|
|
u16 *ptr = gUnknown_202D808;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (gUnknown_202DB50[0] < (gUnknown_202DB74 / 2)) {
|
|
gUnknown_202DB20[i] = ptr[gUnknown_202DB50[0]++];
|
|
}
|
|
else {
|
|
gUnknown_202DB20[i] = 0xFCFC;
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 sub_800D33C(void)
|
|
{
|
|
s32 ret = 0;
|
|
|
|
gUnknown_202DB6C = gUnknown_202DB68;
|
|
gUnknown_202DB68 = sub_800D820(gUnknown_202DB20, gUnknown_202DB30);
|
|
if (gUnknown_202DB70 == 0) {
|
|
if (gUnknown_202DB68 & 0x100) {
|
|
gUnknown_202DB70 = 1;
|
|
}
|
|
return 0;
|
|
}
|
|
else if (gUnknown_202DB68 & 0x1000) {
|
|
return 3;
|
|
}
|
|
else if (gUnknown_202DB68 & 0x2000) {
|
|
return 4;
|
|
}
|
|
else if (gUnknown_202DB68 & 0x8000) {
|
|
u32 bits1, bits2;
|
|
|
|
bits1 = gUnknown_202DB68 << 28;
|
|
bits1 >>= 28;
|
|
|
|
bits2 = gUnknown_202DB68 << 20;
|
|
bits2 >>= 28;
|
|
if (bits1 != bits2)
|
|
return 5;
|
|
}
|
|
|
|
if (((gUnknown_202DB68 | gUnknown_202DB6C) & 0xE)) {
|
|
u32 si0Cnt = (*(vu32 *)REG_ADDR_SIOCNT);
|
|
si0Cnt <<= 26;
|
|
si0Cnt >>= 30;
|
|
if ((gUnknown_202DB68 & (1 << si0Cnt))) {
|
|
sub_800D1E0();
|
|
sub_800D224(gUnknown_202DB68);
|
|
if (sub_800D1C0(gUnknown_202DB68)) {
|
|
return 2;
|
|
}
|
|
sub_800D2EC(gUnknown_202DB68);
|
|
ret = 1;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static inline void ClearUnkMemory(void)
|
|
{
|
|
gUnknown_202DB68 = 0;
|
|
gUnknown_202DB6C = 0;
|
|
gUnknown_202DB70 = 0;
|
|
gUnknown_202DB74 = 0;
|
|
gUnknown_202DB60[0] = 0;
|
|
gUnknown_202DB60[1] = 0;
|
|
MemoryClear16(gUnknown_202DB20, sizeof(gUnknown_202DB20));
|
|
MemoryClear16(gUnknown_202DB30[0], sizeof(gUnknown_202DB30));
|
|
gUnknown_202DB50[0] = 0;
|
|
gUnknown_202DB58[0] = 0;
|
|
gUnknown_202DB58[1] = 0;
|
|
MemoryClear16(gUnknown_202D808, sizeof(gUnknown_202D808));
|
|
MemoryClear16(gUnknown_202D910[0], sizeof(gUnknown_202D910));
|
|
}
|
|
|
|
// These two are the same, except sub_800D414 calls an additional func
|
|
void sub_800D414(void)
|
|
{
|
|
ClearUnkMemory();
|
|
sub_800D6AC();
|
|
}
|
|
|
|
void sub_800D494(void)
|
|
{
|
|
ClearUnkMemory();
|
|
}
|
|
|
|
void sub_800D510(void)
|
|
{
|
|
REG_RCNT = 0x8000;
|
|
}
|
|
|
|
void sub_800D520(void)
|
|
{
|
|
vu16 var = 1; // Has to be u16, not s16
|
|
u8 si0Cnt = (*(vu8 *)REG_ADDR_SIOCNT); // First 8 bits
|
|
|
|
if (!(si0Cnt & 0x30)) {
|
|
while (--var != (u16) -1) {
|
|
VBlankIntrWait();
|
|
}
|
|
}
|
|
sub_800D7D0();
|
|
}
|
|
|
|
void sub_800D570(void)
|
|
{
|
|
sub_800D7B8();
|
|
}
|
|
|
|
UNUSED static u8 sub_800D57C(void)
|
|
{
|
|
return gUnknown_202DB70;
|
|
}
|
|
|
|
u8 sub_800D588(void)
|
|
{
|
|
return (gUnknown_202DB68 & 0x80);
|
|
}
|
|
|
|
void sub_800D59C(u16 *src, u32 size)
|
|
{
|
|
u32 i;
|
|
u16 bits;
|
|
s32 count = 0;
|
|
u16 *dst = gUnknown_202D808;
|
|
|
|
gUnknown_202DB74 = ((size + 1) & ~(1)) + 8;
|
|
CpuCopy(&dst[2], src, size);
|
|
bits = 0xFDFD;
|
|
dst[0] = bits;
|
|
dst[1] = 0;
|
|
for (i = 0; i < (gUnknown_202DB74 / 2) - 2; i++) {
|
|
count += dst[i];
|
|
}
|
|
|
|
gUnknown_202D808[1] = ~count - (gUnknown_202DB74 / 2);
|
|
}
|
|
|
|
bool8 sub_800D600(void)
|
|
{
|
|
u32 i, j;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
s32 count = 0;
|
|
u16 *ptr = gUnknown_202D910[i];
|
|
|
|
for (j = 0; j < (gUnknown_202DB74 / 2) - 2; j++) {
|
|
count += ptr[j];
|
|
}
|
|
|
|
// Interesting casts and arithmetics here.
|
|
if ((s16) count != (s16) (-1 - (gUnknown_202DB74 / 2)))
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void sub_800D670(u32 id, void *dst, u32 size)
|
|
{
|
|
CpuCopy(dst, &gUnknown_202D910[id][2], size);
|
|
}
|
|
|
|
void sub_800D68C(u32 id)
|
|
{
|
|
MemoryFill8(gUnknown_202D910[id], 0, sizeof(gUnknown_202D910[0]));
|
|
}
|
|
|
|
void sub_800D6AC(void)
|
|
{
|
|
s32 i;
|
|
|
|
REG_IME = 0;
|
|
REG_IE &= 0xFF3F;
|
|
REG_IME = 1;
|
|
REG_RCNT = 0;
|
|
(*(vu32 *)REG_ADDR_SIOCNT) = 0x2000;
|
|
REG_SIOCNT |= 0x4003;
|
|
CpuFill32(0, &gUnknown_202DCF8, 0x120);
|
|
CpuCopy32(sub_80001E8, gUnknown_202DB78, sizeof(gUnknown_202DB78));
|
|
CpuCopy32(sub_8000228, gUnknown_202DBB8, sizeof(gUnknown_202DBB8));
|
|
gUnknown_202DCF8.unk14 = -1;
|
|
gUnknown_202DCF8.unk28.asU16 = gUnknown_202DCF8.unk60;
|
|
gUnknown_202DCF8.unk2C = gUnknown_202DCF8.unk78;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
gUnknown_202DCF8.unk30[i] = gUnknown_202DCF8.unk90[i][0];
|
|
gUnknown_202DCF8.unk40[i] = gUnknown_202DCF8.unk90[i][1];
|
|
gUnknown_202DCF8.unk50[i] = gUnknown_202DCF8.unk90[i][2];
|
|
}
|
|
|
|
REG_IME = 0;
|
|
REG_IE |= 0x80;
|
|
REG_IME = 1;
|
|
}
|
|
|
|
static void sub_800D7B8(void)
|
|
{
|
|
if (gUnknown_202DCF8.unk0 != 0) {
|
|
gUnknown_202DCF8.unk8 = 1;
|
|
}
|
|
}
|
|
|
|
void sub_800D7D0(void)
|
|
{
|
|
REG_IME = 0;
|
|
REG_IE &= 0xFF3F;
|
|
REG_IME = 1;
|
|
REG_SIOCNT = 0x2003;
|
|
REG_TM3CNT = 0xB1FC;
|
|
REG_IF = 0xC0;
|
|
gUnknown_202DCF8.unk8 = 0;
|
|
}
|
|
|
|
static u32 sub_800D820(u16 *a0, u16 a1[2][8])
|
|
{
|
|
u32 ret, var;
|
|
u32 bits1, bits2, b;
|
|
u32 r3, r2;
|
|
u32 si0cnt = (*(vu32 *)REG_ADDR_SIOCNT);
|
|
|
|
switch (gUnknown_202DCF8.unk1) {
|
|
case 0:
|
|
if (gUnknown_202DCF8.unk14 == -1) {
|
|
u16 bits = si0cnt & 0x88;
|
|
if (bits != 8)
|
|
break;
|
|
if (!((u8)(si0cnt & 0x4))) {
|
|
vu8 *sioPtru8;
|
|
u32 sioBits;
|
|
|
|
REG_IME = 0;
|
|
REG_IE &= 0xFF7F;
|
|
REG_IE |= 0x40;
|
|
REG_IME = 1;
|
|
sioPtru8 = ((vu8 *)REG_ADDR_SIOCNT);
|
|
sioBits = sioPtru8[1] & ~0x40;
|
|
sioPtru8[1] = sioBits;
|
|
REG_IF = 0xC0;
|
|
REG_TM3CNT = 0xB1FC;
|
|
gUnknown_202DCF8.unk0 = 8;
|
|
}
|
|
}
|
|
gUnknown_202DCF8.unk1 = 1;
|
|
// fallthrough
|
|
case 1:
|
|
if (gUnknown_202DCF8.unk2 != 0) {
|
|
if (gUnknown_202DCF8.unkA < 8) {
|
|
gUnknown_202DCF8.unkA++;
|
|
}
|
|
else {
|
|
gUnknown_202DCF8.unk1 = 2;
|
|
}
|
|
}
|
|
// fallthrough
|
|
case 2:
|
|
sub_800D9B8(a1);
|
|
sub_800D944(a0);
|
|
break;
|
|
}
|
|
|
|
gUnknown_202DCF8.unkB++;
|
|
r3 = gUnknown_202DCF8.unk3;
|
|
r2 = gUnknown_202DCF8.unk2 << 8;
|
|
b = ((gUnknown_202DCF8.unk0 == 8) ? 0x80 : 0) | r3 | r2;
|
|
var = b;
|
|
if (gUnknown_202DCF8.unk9 != 0) {
|
|
var |= 0x1000;
|
|
}
|
|
|
|
bits1 = (gUnknown_202DCF8.unkA >> 3) << 15;
|
|
bits2 = (si0cnt << 26) >> 30;
|
|
if (bits2 >= 2) {
|
|
ret = 0x2000 | var | bits1;
|
|
}
|
|
else {
|
|
ret = var | bits1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void sub_800D944(u16 *src)
|
|
{
|
|
u32 i;
|
|
s32 count = 0;
|
|
|
|
gUnknown_202DCF8.unk28.asU8[0] = gUnknown_202DCF8.unkB;
|
|
gUnknown_202DCF8.unk28.asU8[1] = gUnknown_202DCF8.unk2 ^ gUnknown_202DCF8.unk3;
|
|
gUnknown_202DCF8.unk28.asU16[1] = 0;
|
|
CpuCopy32(src, &gUnknown_202DCF8.unk28.asU16[2], 0x10);
|
|
for (i = 0; i < 10; i++) {
|
|
count += gUnknown_202DCF8.unk28.asU16[i];
|
|
}
|
|
|
|
gUnknown_202DCF8.unk28.asU16[1] = ~count - 12;
|
|
if (gUnknown_202DCF8.unk0 != 0) {
|
|
REG_TM3CNT_H = 0;
|
|
}
|
|
gUnknown_202DCF8.unk14 = -1;
|
|
if (gUnknown_202DCF8.unk0 != 0 && gUnknown_202DCF8.unk8 != 0) {
|
|
REG_TM3CNT_H = 0xC0;
|
|
}
|
|
}
|
|
|
|
static u32 sub_800D9B8(u16 dst[2][8])
|
|
{
|
|
s32 i;
|
|
u8 sp0[4];
|
|
u32 (*func)(void) = (void *)gUnknown_202DB78;
|
|
u32 *spAsU32 = (u32 *)sp0;
|
|
|
|
*spAsU32 = func();
|
|
gUnknown_202DCF8.unk3 = 0;
|
|
for (i = 0; i < 2; i++) {
|
|
u32 j;
|
|
s32 count = 0;
|
|
|
|
for (j = 0; j < 10; j++) {
|
|
count += gUnknown_202DCF8.unk50[i][j];
|
|
}
|
|
|
|
if (sp0[i] != 0 && (s16)(count) == (s16)(-13)) {
|
|
CpuCopy32(&gUnknown_202DCF8.unk50[i][2], dst[i], 0x10);
|
|
gUnknown_202DCF8.unk3 |= (1 << i);
|
|
}
|
|
CpuFill32(0, &gUnknown_202DCF8.unk50[i][2], 0x10);
|
|
}
|
|
gUnknown_202DCF8.unk2 |= gUnknown_202DCF8.unk3;
|
|
return gUnknown_202DCF8.unk3;
|
|
}
|