From 735e4c169e9af558bc6e529a37a1ff2b9060d553 Mon Sep 17 00:00:00 2001 From: Jcw87 Date: Tue, 10 Oct 2023 02:24:45 -0700 Subject: [PATCH] JUTGba --- include/JSystem/JKernel/JKRHeap.h | 4 + include/JSystem/JUtility/JUTGba.h | 60 +++-- include/dolphin/si/SIBios.h | 130 +++++++++++ src/JSystem/JUtility/JUTGba.cpp | 363 +++++++++++++++++++++++++----- 4 files changed, 484 insertions(+), 73 deletions(-) create mode 100644 include/dolphin/si/SIBios.h diff --git a/include/JSystem/JKernel/JKRHeap.h b/include/JSystem/JKernel/JKRHeap.h index be6ea956e..5f5dacb18 100644 --- a/include/JSystem/JKernel/JKRHeap.h +++ b/include/JSystem/JKernel/JKRHeap.h @@ -223,6 +223,10 @@ inline JKRHeap* JKRGetCurrentHeap() { return JKRHeap::getCurrentHeap(); } +inline JKRHeap* JKRSetCurrentHeap(JKRHeap* heap) { + return heap->becomeCurrentHeap(); +} + inline u32 JKRGetMemBlockSize(JKRHeap* heap, void* block) { return JKRHeap::getSize(block, heap); } diff --git a/include/JSystem/JUtility/JUTGba.h b/include/JSystem/JUtility/JUTGba.h index 21577b6da..d8d62b22b 100644 --- a/include/JSystem/JUtility/JUTGba.h +++ b/include/JSystem/JUtility/JUTGba.h @@ -1,20 +1,47 @@ #ifndef JUTGBA_H #define JUTGBA_H -#include "dolphin/types.h" +#include "dolphin/os/OSMessage.h" +#include "dolphin/os/OSTime.h" struct JUTGbaParam; -struct JUTGbaThreadVar; typedef void (*JUTGba_Func)(JUTGbaParam*, void*); +struct JUTGbaParam { + /* 0x00 */ OSMessageQueue field_0x0; + /* 0x20 */ OSMessage field_0x20; + /* 0x24 */ u32 field_0x24; + /* 0x28 */ s32 channel; + /* 0x2C */ u8* program; + /* 0x30 */ int length; + /* 0x34 */ int palette_color; + /* 0x38 */ int palette_speed; + /* 0x3C */ u8 field_0x3c; + /* 0x40 */ int field_0x40; + /* 0x44 */ u8 status; + /* 0x48 */ u8* field_0x48; + /* 0x4C */ JUTGba_Func field_0x4c; + /* 0x50 */ void* field_0x50; + /* 0x54 */ u8 field_0x54; + /* 0x58 */ int field_0x58; +}; + +struct JUTGbaThreadVar { + /* 0x00 */ JUTGbaParam* field_0x0; + /* 0x08 */ OSTime field_0x8; + /* 0x10 */ u32 field_0x10; + /* 0x14 */ u32 field_0x14; + /* 0x18 */ u32 field_0x18; +}; + class JUTGba { public: JUTGba(); - static void create(); - void result_common(int, u32, u32*); - void resultStatus_common(int, u32, u8*); + static JUTGba* create(); + int result_common(int, u32, u32*); + int resultStatus_common(int, u32, u8*); void doJoyBoot(int, s32, s32, u8*, u32, JUTGba_Func, void*); int resultJoyBoot(int, u8*); void doInitProbe(int, JUTGba_Func, void*); @@ -29,20 +56,25 @@ class JUTGba { BOOL resultWrite(int, u8*); void doGetStatus(int, JUTGba_Func, void*); BOOL resultGetStatus(int, u8*); - void gbaThreadMain(void*); - void gbaThread_sleep(s64); + static void* gbaThreadMain(void*); + void gbaThread_sleep(OSTime); void gbaThread_Destroy(JUTGbaThreadVar*); - void gbaThread_JoyBoot(JUTGbaThreadVar*); - void gbaThread_InitProbe(JUTGbaThreadVar*); - void gbaThread_Probe(JUTGbaThreadVar*); - void gbaThread_Reset(JUTGbaThreadVar*); - void gbaThread_Read(JUTGbaThreadVar*); - void gbaThread_Write(JUTGbaThreadVar*); - void gbaThread_GetStatus(JUTGbaThreadVar*); + int gbaThread_JoyBoot(JUTGbaThreadVar*); + int gbaThread_InitProbe(JUTGbaThreadVar*); + int gbaThread_Probe(JUTGbaThreadVar*); + int gbaThread_Reset(JUTGbaThreadVar*); + int gbaThread_Read(JUTGbaThreadVar*); + int gbaThread_Write(JUTGbaThreadVar*); + int gbaThread_GetStatus(JUTGbaThreadVar*); static JUTGba* getManager() { return sManager; } static JUTGba* sManager; + + /* 0x0000 */ OSThread mThreads[4]; + /* 0x0C60 */ u8 mStacks[4][4096]; + /* 0x4C60 */ JUTGbaParam mParams[4]; + /* 0x4DD0 */ u8 field0x4dd0[16]; }; #endif /* JUTGBA_H */ diff --git a/include/dolphin/si/SIBios.h b/include/dolphin/si/SIBios.h new file mode 100644 index 000000000..4e7efc629 --- /dev/null +++ b/include/dolphin/si/SIBios.h @@ -0,0 +1,130 @@ +#ifndef SIBIOS_H +#define SIBIOS_H + +#include "dolphin/os/OSInterrupt.h" +#include "dolphin/os/OSTime.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SI_MAX_CHAN 4 +#define SI_MAX_COMCSR_INLNGTH 128 +#define SI_MAX_COMCSR_OUTLNGTH 128 +#define SI_ERROR_UNDER_RUN 0x0001 +#define SI_ERROR_OVER_RUN 0x0002 +#define SI_ERROR_COLLISION 0x0004 +#define SI_ERROR_NO_RESPONSE 0x0008 +#define SI_ERROR_WRST 0x0010 +#define SI_ERROR_RDST 0x0020 +#define SI_ERROR_UNKNOWN 0x0040 +#define SI_ERROR_BUSY 0x0080 +#define SI_CHAN0 0 +#define SI_CHAN1 1 +#define SI_CHAN2 2 +#define SI_CHAN3 3 +#define SI_CHAN0_BIT 0x80000000 +#define SI_CHAN1_BIT 0x40000000 +#define SI_CHAN2_BIT 0x20000000 +#define SI_CHAN3_BIT 0x10000000 +#define SI_CHAN_BIT(chan) (SI_CHAN0_BIT >> (chan)) +#define SI_TYPE_MASK 0x18000000u +#define SI_TYPE_N64 0x00000000u +#define SI_TYPE_DOLPHIN 0x08000000u +#define SI_TYPE_GC SI_TYPE_DOLPHIN +#define SI_GC_WIRELESS 0x80000000 +#define SI_GC_NOMOTOR 0x20000000 +#define SI_GC_STANDARD 0x01000000 +#define SI_WIRELESS_RECEIVED 0x40000000 +#define SI_WIRELESS_IR 0x04000000 +#define SI_WIRELESS_STATE 0x02000000 +#define SI_WIRELESS_ORIGIN 0x00200000 +#define SI_WIRELESS_FIX_ID 0x00100000 +#define SI_WIRELESS_TYPE 0x000f0000 +#define SI_WIRELESS_LITE_MASK 0x000c0000 +#define SI_WIRELESS_LITE 0x00040000 +#define SI_WIRELESS_CONT_MASK 0x00080000 +#define SI_WIRELESS_CONT 0x00000000 +#define SI_WIRELESS_ID 0x00c0ff00 +#define SI_WIRELESS_TYPE_ID (SI_WIRELESS_TYPE | SI_WIRELESS_ID) +#define SI_N64_CONTROLLER (SI_TYPE_N64 | 0x05000000) +#define SI_N64_MIC (SI_TYPE_N64 | 0x00010000) +#define SI_N64_KEYBOARD (SI_TYPE_N64 | 0x00020000) +#define SI_N64_MOUSE (SI_TYPE_N64 | 0x02000000) +#define SI_GBA (SI_TYPE_N64 | 0x00040000) +#define SI_GC_CONTROLLER (SI_TYPE_GC | SI_GC_STANDARD) +#define SI_GC_RECEIVER (SI_TYPE_GC | SI_GC_WIRELESS) +#define SI_GC_WAVEBIRD \ + (SI_TYPE_GC | SI_GC_WIRELESS | SI_GC_STANDARD | SI_WIRELESS_STATE | SI_WIRELESS_FIX_ID) +#define SI_GC_KEYBOARD (SI_TYPE_GC | 0x00200000) +#define SI_GC_STEERING (SI_TYPE_GC | 0x00000000) + +typedef void (*SICallback)(s32 chan, u32 sr, OSContext* context); +typedef void (*SITypeAndStatusCallback)(s32 chan, u32 type); + +typedef struct SIPacket { + s32 chan; + void* output; + u32 outputBytes; + void* input; + u32 inputBytes; + SICallback callback; + OSTime fire; +} SIPacket; + +typedef struct SIControl { + s32 chan; + u32 poll; + u32 inputBytes; + void* input; + SICallback callback; +} SIControl; + +typedef struct SIComm_s { + u32 tcint : 1; + u32 tcintmsk : 1; + u32 comerr : 1; + u32 rdstint : 1; + u32 rdstintmsk : 1; + u32 pad0 : 4; + u32 outlngth : 7; + u32 pad1 : 1; + u32 inlngth : 7; + u32 pad2 : 5; + u32 channel : 2; + u32 tstart : 1; +} SIComm_s; + +typedef union SIComm_u { + u32 val; + SIComm_s f; +} SIComm_u; + +BOOL SIBusy(void); +BOOL SIIsChanBusy(s32 chan); +static void SIInterruptHandler(OSInterrupt interrupt, OSContext* context); +static BOOL SIEnablePollingInterrupt(BOOL enable); +BOOL SIRegisterPollingHandler(OSInterruptHandler handler); +BOOL SIUnregisterPollingHandler(OSInterruptHandler handler); +void SIInit(void); +u32 SIGetStatus(s32 chan); +void SISetCommand(s32 chan, u32 command); +void SITransferCommands(void); +u32 SISetXY(u32 x, u32 y); +u32 SIEnablePolling(u32 poll); +u32 SIDisablePolling(u32 poll); +static BOOL SIGetResponseRaw(s32 chan); +BOOL SIGetResponse(s32 chan, void* data); +BOOL SITransfer(s32 chan, void* output, u32 outputBytes, void* input, u32 inputBytes, + SICallback callback, OSTime delay); +u32 SIGetType(s32 chan); +u32 SIGetTypeAsync(s32 chan, SITypeAndStatusCallback callback); +u32 SIProbe(s32 chan); + +vu32 __SIRegs[64] : 0xCC006400; + +#ifdef __cplusplus +} +#endif + +#endif /* SIBIOS_H */ diff --git a/src/JSystem/JUtility/JUTGba.cpp b/src/JSystem/JUtility/JUTGba.cpp index 1c0c6ebba..0076b1af2 100644 --- a/src/JSystem/JUtility/JUTGba.cpp +++ b/src/JSystem/JUtility/JUTGba.cpp @@ -4,149 +4,394 @@ // #include "JSystem/JUtility/JUTGba.h" -#include "dolphin/types.h" +#include "JSystem/JKernel/JKRThread.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "dolphin/gba/GBA.h" +#include "dolphin/si/SIBios.h" + +typedef struct OSAlarm OSAlarm; +typedef struct OSContext OSContext; + +struct JUTGbaAlarm : public OSAlarm { + OSThread* thread; +}; /* 802CBEB0-802CBEB4 .text __ct__6JUTGbaFv */ -JUTGba::JUTGba() { - /* Nonmatching */ -} +JUTGba::JUTGba() {} + +JUTGba* JUTGba::sManager; /* 802CBEB4-802CC03C .text create__6JUTGbaFv */ -void JUTGba::create() { - /* Nonmatching */ +JUTGba* JUTGba::create() { + JUT_ASSERT(61, sManager == 0); + sManager = new JUTGba(); + GBAInit(); + OSReport(":::GBA: Init()\n"); + for (int i = 0; i < 4; i++) { + JUTGbaParam* param = sManager->mParams + i; + char* mem = (char*)param; + for (int j = 0; j < sizeof(JUTGbaParam); j++) { + *(mem++) = 0; + } + param->channel = i; + param->program = 0; + param->length = 0; + param->field_0x24 = 0; + OSInitMessageQueue(¶m->field_0x0, ¶m->field_0x20, 1); + } + for (int i = 0; i < 4; i++) { + JUTGbaParam* param = &sManager->mParams[i]; + OSReport(":::GBA: Create Thread %d\n", i); + OSCreateThread(&sManager->mThreads[i], &gbaThreadMain, param, sManager->mStacks + i + 1, 0x1000, 8, 0); + OSResumeThread(&sManager->mThreads[i]); + } + return sManager; } /* 802CC03C-802CC08C .text result_common__6JUTGbaFiUlPUl */ -void JUTGba::result_common(int, unsigned long, unsigned long*) { - /* Nonmatching */ +int JUTGba::result_common(int param_1, u32 param_2, u32* param_3) { + JUTGbaParam* param = &sManager->mParams[param_1]; + if (param->field_0x24 != param_2) { + return -1; + } + if (param->field_0x3c != 1) { + *param_3 = 0; + return -2; + } + *param_3 = param->field_0x40; + return 0; } /* 802CC08C-802CC0E8 .text resultStatus_common__6JUTGbaFiUlPUc */ -void JUTGba::resultStatus_common(int, unsigned long, unsigned char*) { - /* Nonmatching */ +int JUTGba::resultStatus_common(int param_1, u32 param_2, u8* oStatus) { + JUTGbaParam* param = &sManager->mParams[param_1]; + if (param->field_0x24 != param_2) { + return -1; + } + if (param->field_0x3c != 1) { + return -2; + } + if (!param->field_0x40 && oStatus) { + *oStatus = param->status; + } + return param->field_0x40; } /* 802CC0E8-802CC1F8 .text doJoyBoot__6JUTGbaFillPUcUlPFP11JUTGbaParamPv_vPv */ -void JUTGba::doJoyBoot(int, long, long, unsigned char*, unsigned long, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doJoyBoot(int param_1, s32 palette_color, s32 palette_speed, u8* program, u32 length, JUTGba_Func param_6, void* param_7) { + JUT_ASSERT(183, sManager != 0); + JUT_ASSERT(184, program != 0 && length != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->program = program; + param->length = length; + param->palette_color = palette_color; + param->palette_speed = palette_speed; + param->field_0x4c = param_6; + param->field_0x50 = param_7; + param->field_0x3c = 0; + OSSendMessage(¶m->field_0x0, (OSMessage)1, OS_MESSAGE_BLOCK); } /* 802CC1F8-802CC308 .text resultJoyBoot__6JUTGbaFiPUc */ -void JUTGba::resultJoyBoot(int, unsigned char*) { - /* Nonmatching */ +int JUTGba::resultJoyBoot(int param_1, u8* param_2) { + JUT_ASSERT(212, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + if (param->field_0x24 != 1) { + return -1; + } + if (param->field_0x3c == 0) { + if (param->field_0x40 == 1) { + if (param_2) { + *param_2 = 0xFF; + } + } else if (param_2) { + GBAGetProcessStatus(param_1, param_2); + } + return -2; + } + if (param->field_0x40 == 0) { + if (param_2) { + *param_2 = 100; + } + } else if (param_2) { + *param_2 = 0; + } + return param->field_0x40; } /* 802CC308-802CC3A8 .text doInitProbe__6JUTGbaFiPFP11JUTGbaParamPv_vPv */ -void JUTGba::doInitProbe(int, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doInitProbe(int param_1, JUTGba_Func param_2, void* param_3) { + JUT_ASSERT(255, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_2; + param->field_0x50 = param_3; + param->field_0x3c = 0; + OSSendMessage(¶m->field_0x0, (OSMessage)2, OS_MESSAGE_BLOCK); } /* 802CC3A8-802CC430 .text resultInitProbe__6JUTGbaFiPUl */ -void JUTGba::resultInitProbe(int, unsigned long*) { - /* Nonmatching */ +int JUTGba::resultInitProbe(int param_1, u32* param_2) { + JUT_ASSERT(278, sManager != 0); + return result_common(param_1, 2, param_2); } /* 802CC430-802CC4D0 .text doProbe__6JUTGbaFiPFP11JUTGbaParamPv_vPv */ -void JUTGba::doProbe(int, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doProbe(int param_1, JUTGba_Func param_2, void* param_3) { + JUT_ASSERT(287, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_2; + param->field_0x50 = param_3; + param->field_0x3c = 0; + OSSendMessage(¶m->field_0x0, (OSMessage)3, OS_MESSAGE_BLOCK); } /* 802CC4D0-802CC558 .text resultProbe__6JUTGbaFiPUl */ -void JUTGba::resultProbe(int, unsigned long*) { - /* Nonmatching */ +BOOL JUTGba::resultProbe(int param_1, u32* param_2) { + JUT_ASSERT(310, sManager != 0); + return result_common(param_1, 3, param_2); } /* 802CC558-802CC5F8 .text doReset__6JUTGbaFiPFP11JUTGbaParamPv_vPv */ -void JUTGba::doReset(int, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doReset(int param_1, JUTGba_Func param_2, void* param_3) { + JUT_ASSERT(320, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_2; + param->field_0x50 = param_3; + param->field_0x3c = 0; + OSSendMessage(¶m->field_0x0, (OSMessage)4, OS_MESSAGE_BLOCK); } /* 802CC5F8-802CC680 .text resultReset__6JUTGbaFiPUc */ -void JUTGba::resultReset(int, unsigned char*) { - /* Nonmatching */ +BOOL JUTGba::resultReset(int param_1, u8* param_2) { + JUT_ASSERT(340, sManager != 0); + return resultStatus_common(param_1, 4, param_2); } /* 802CC680-802CC728 .text doRead__6JUTGbaFiPUcPFP11JUTGbaParamPv_vPv */ -void JUTGba::doRead(int, unsigned char*, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doRead(int param_1, u8* param_2, JUTGba_Func param_3, void* param_4) { + JUT_ASSERT(350, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_3; + param->field_0x50 = param_4; + param->field_0x3c = 0; + param->field_0x48 = param_2; + OSSendMessage(¶m->field_0x0, (OSMessage)5, OS_MESSAGE_BLOCK); } /* 802CC728-802CC7B0 .text resultRead__6JUTGbaFiPUc */ -void JUTGba::resultRead(int, unsigned char*) { - /* Nonmatching */ +BOOL JUTGba::resultRead(int param_1, u8* param_2) { + JUT_ASSERT(371, sManager != 0); + return resultStatus_common(param_1, 5, param_2); } /* 802CC7B0-802CC858 .text doWrite__6JUTGbaFiPUcPFP11JUTGbaParamPv_vPv */ -void JUTGba::doWrite(int, unsigned char*, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doWrite(int param_1, u8* param_2, JUTGba_Func param_3, void* param_4) { + JUT_ASSERT(381, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_3; + param->field_0x50 = param_4; + param->field_0x3c = 0; + param->field_0x48 = param_2; + OSSendMessage(¶m->field_0x0, (OSMessage)6, OS_MESSAGE_BLOCK); } /* 802CC858-802CC8E0 .text resultWrite__6JUTGbaFiPUc */ -void JUTGba::resultWrite(int, unsigned char*) { - /* Nonmatching */ +BOOL JUTGba::resultWrite(int param_1, u8* param_2) { + JUT_ASSERT(403, sManager != 0); + return resultStatus_common(param_1, 6, param_2); } /* 802CC8E0-802CC980 .text doGetStatus__6JUTGbaFiPFP11JUTGbaParamPv_vPv */ -void JUTGba::doGetStatus(int, void (*)(JUTGbaParam*, void*), void*) { - /* Nonmatching */ +void JUTGba::doGetStatus(int param_1, JUTGba_Func param_2, void* param_3) { + JUT_ASSERT(413, sManager != 0); + JUTGbaParam* param = &sManager->mParams[param_1]; + param->field_0x4c = param_2; + param->field_0x50 = param_3; + param->field_0x3c = 0; + OSSendMessage(¶m->field_0x0, (OSMessage)7, OS_MESSAGE_BLOCK); } /* 802CC980-802CCA08 .text resultGetStatus__6JUTGbaFiPUc */ -void JUTGba::resultGetStatus(int, unsigned char*) { - /* Nonmatching */ +BOOL JUTGba::resultGetStatus(int param_1, u8* param_2) { + JUT_ASSERT(434, sManager != 0); + return resultStatus_common(param_1, 7, param_2); } /* 802CCA08-802CCC6C .text gbaThreadMain__6JUTGbaFPv */ -void JUTGba::gbaThreadMain(void*) { +void* JUTGba::gbaThreadMain(void* param_1) { /* Nonmatching */ + JUTGbaParam* param = (JUTGbaParam*)param_1; + { JKRThread jkrThread(OSGetCurrentThread(), 0); } + JKRSetCurrentHeap(NULL); + JUTGbaThreadVar threadVar; + threadVar.field_0x0 = param; + while (true) { + if (!OSReceiveMessage(¶m->field_0x0, (OSMessage*)&threadVar.field_0x10, OS_MESSAGE_NOBLOCK)) { + param->field_0x54 = 0; + OSReceiveMessage(¶m->field_0x0, (OSMessage*)&threadVar.field_0x10, OS_MESSAGE_BLOCK); + } + param->field_0x54 = 1; + param->field_0x40 = 0; + param->field_0x24 = threadVar.field_0x10; + threadVar.field_0x8 = OSGetTime(); + threadVar.field_0x14 = 0; + threadVar.field_0x18 = 0; + if (threadVar.field_0x10 == 8) { + sManager->gbaThread_Destroy(&threadVar); + param->field_0x3c = 1; + return NULL; + } + while (true) { + if (param->field_0x58) { + break; + } + if (OSMillisecondsToTicks(4000) < OSGetTime() - threadVar.field_0x8) { + if (param->field_0x40 == 3) { + break; + } + param->field_0x40 = 1; + param->field_0x3c = 1; + break; + } + switch (threadVar.field_0x10) { + case 1: + sManager->gbaThread_JoyBoot(&threadVar); + break; + case 2: + sManager->gbaThread_InitProbe(&threadVar); + break; + case 3: + sManager->gbaThread_Probe(&threadVar); + break; + case 4: + sManager->gbaThread_Reset(&threadVar); + break; + case 5: + sManager->gbaThread_Read(&threadVar); + break; + case 6: + sManager->gbaThread_Write(&threadVar); + break; + case 7: + sManager->gbaThread_GetStatus(&threadVar); + break; + default: + OSPanic(__FILE__, 623, "UNKNOWN GBA COMMAND."); + break; + } + if (threadVar.field_0x14) { + if (threadVar.field_0x18) { + sManager->gbaThread_sleep(threadVar.field_0x18); + } + threadVar.field_0x10 = threadVar.field_0x14; + threadVar.field_0x14 = 0; + continue; + } + if (!param->field_0x4c) { + break; + } + param->field_0x4c(param, param->field_0x50); + break; + } + } + return NULL; } /* 802CCC6C-802CCC90 .text JUTGBAThreadAlarmHandler__FP7OSAlarmP9OSContext */ -void JUTGBAThreadAlarmHandler(OSAlarm*, OSContext*) { - /* Nonmatching */ +void JUTGBAThreadAlarmHandler(OSAlarm* alarm, OSContext* context) { + JUTGbaAlarm* gbaAlarm = (JUTGbaAlarm*)alarm; + OSResumeThread(gbaAlarm->thread); } /* 802CCC90-802CCD04 .text gbaThread_sleep__6JUTGbaFx */ -void JUTGba::gbaThread_sleep(long long) { - /* Nonmatching */ +void JUTGba::gbaThread_sleep(OSTime param_1) { + JUTGbaAlarm alarm; + OSCreateAlarm(&alarm); + alarm.thread = OSGetCurrentThread(); + BOOL enable = OSDisableInterrupts(); + OSSetAlarm(&alarm, param_1, &JUTGBAThreadAlarmHandler); + OSSuspendThread(alarm.thread); + OSRestoreInterrupts(enable); } /* 802CCD04-802CCD14 .text gbaThread_Destroy__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_Destroy(JUTGbaThreadVar*) { - /* Nonmatching */ +void JUTGba::gbaThread_Destroy(JUTGbaThreadVar* var) { + var->field_0x0->field_0x40 = 0; } /* 802CCD14-802CCDB8 .text gbaThread_JoyBoot__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_JoyBoot(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_JoyBoot(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = GBAJoyBoot(param->channel, param->palette_color, param->palette_speed, param->program, param->length, ¶m->status); + if (param->field_0x40 == 0) { + param->field_0x3c = 1; + } else if (param->field_0x40 == 1 || param->field_0x40 == 3) { + var->field_0x14 = var->field_0x10; + var->field_0x18 = OSMillisecondsToTicks(15); + } + return param->field_0x40; } /* 802CCDB8-802CCEB8 .text gbaThread_InitProbe__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_InitProbe(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_InitProbe(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = SIProbe(param->channel); + if (OSMillisecondsToTicks(1000) < OSGetTime() - var->field_0x8) { + param->field_0x40 = 8; + param->field_0x3c = 1; + } else if (param->field_0x40 == 0x80) { + var->field_0x14 = var->field_0x10; + var->field_0x18 = OSMillisecondsToTicks(15); + } else if (param->field_0x40 == 8) { + var->field_0x14 = var->field_0x10; + var->field_0x18 = OSMillisecondsToTicks(50); + } else { + param->field_0x3c = 1; + } + return param->field_0x40; } /* 802CCEB8-802CCF38 .text gbaThread_Probe__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_Probe(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_Probe(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = SIProbe(param->channel); + if (param->field_0x40 == 0x80) { + var->field_0x14 = var->field_0x10; + var->field_0x18 = OSMillisecondsToTicks(15); + } else { + param->field_0x3c = 1; + } + return param->field_0x40; } /* 802CCF38-802CCF7C .text gbaThread_Reset__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_Reset(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_Reset(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = GBAReset(param->channel, ¶m->status); + param->field_0x3c = 1; + return param->field_0x40; } /* 802CCF7C-802CCFC4 .text gbaThread_Read__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_Read(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_Read(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = GBARead(param->channel, param->field_0x48, ¶m->status); + param->field_0x3c = 1; + return param->field_0x40; } /* 802CCFC4-802CD00C .text gbaThread_Write__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_Write(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_Write(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = GBAWrite(param->channel, param->field_0x48, ¶m->status); + param->field_0x3c = 1; + return param->field_0x40; } /* 802CD00C-802CD050 .text gbaThread_GetStatus__6JUTGbaFP15JUTGbaThreadVar */ -void JUTGba::gbaThread_GetStatus(JUTGbaThreadVar*) { - /* Nonmatching */ +int JUTGba::gbaThread_GetStatus(JUTGbaThreadVar* var) { + JUTGbaParam* param = var->field_0x0; + param->field_0x40 = GBAGetStatus(param->channel, ¶m->status); + param->field_0x3c = 1; + return param->field_0x40; }