diff --git a/lib/NitroSDK/asm/os_message.s b/lib/NitroSDK/asm/os_message.s deleted file mode 100644 index f8216b9c..00000000 --- a/lib/NitroSDK/asm/os_message.s +++ /dev/null @@ -1,197 +0,0 @@ - .include "asm/macros.inc" - .include "include/os_thread.inc" - - .text - - arm_func_start OS_InitMessageQueue -OS_InitMessageQueue: ; 0x02079DB8 - mov r3, #0 - str r3, [r0, #4] - str r3, [r0] - str r3, [r0, #0xc] - str r3, [r0, #8] - str r1, [r0, #0x10] - str r2, [r0, #0x14] - str r3, [r0, #0x18] - str r3, [r0, #0x1c] - bx lr - arm_func_end OS_InitMessageQueue - - arm_func_start OS_SendMessage -OS_SendMessage: ; 0x02079DE0 - stmdb sp!, {r3, r4, r5, r6, r7, lr} - mov r5, r0 - mov r4, r1 - mov r7, r2 - bl EnableIrqFlag - ldr r2, [r5, #0x1c] - ldr r1, [r5, #0x14] - mov r6, r0 - cmp r1, r2 - bgt _02079E3C - and r7, r7, #1 -_02079E0C: - cmp r7, #0 - bne _02079E24 - mov r0, r6 - bl SetIrqFlag - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_02079E24: - mov r0, r5 - bl OS_SleepThread - ldr r2, [r5, #0x1c] - ldr r1, [r5, #0x14] - cmp r1, r2 - ble _02079E0C -_02079E3C: - ldr r0, [r5, #0x18] - add r0, r0, r2 - bl _s32_div_f - ldr r2, [r5, #0x10] - add r0, r5, #8 - str r4, [r2, r1, lsl #2] - ldr r1, [r5, #0x1c] - add r1, r1, #1 - str r1, [r5, #0x1c] - bl OS_WakeupThread - mov r0, r6 - bl SetIrqFlag - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_SendMessage - - arm_func_start OS_ReceiveMessage -OS_ReceiveMessage: ; 0x02079E74 - stmdb sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl EnableIrqFlag - ldr r1, [r6, #0x1c] - mov r4, r0 - cmp r1, #0 - bne _02079EC8 - and r7, r7, #1 -_02079E9C: - cmp r7, #0 - bne _02079EB4 - mov r0, r4 - bl SetIrqFlag - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_02079EB4: - add r0, r6, #8 - bl OS_SleepThread - ldr r0, [r6, #0x1c] - cmp r0, #0 - beq _02079E9C -_02079EC8: - cmp r5, #0 - beq _02079EE0 - ldr r1, [r6, #0x10] - ldr r0, [r6, #0x18] - ldr r0, [r1, r0, lsl #2] - str r0, [r5] -_02079EE0: - ldr r0, [r6, #0x18] - ldr r1, [r6, #0x14] - add r0, r0, #1 - bl _s32_div_f - str r1, [r6, #0x18] - ldr r1, [r6, #0x1c] - mov r0, r6 - sub r1, r1, #1 - str r1, [r6, #0x1c] - bl OS_WakeupThread - mov r0, r4 - bl SetIrqFlag - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_ReceiveMessage - - arm_func_start OS_JamMessage -OS_JamMessage: ; 0x02079F18 - stmdb sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl EnableIrqFlag - ldr r1, [r6, #0x14] - ldr r2, [r6, #0x1c] - mov r4, r0 - cmp r1, r2 - bgt _02079F74 - and r7, r7, #1 -_02079F44: - cmp r7, #0 - bne _02079F5C - mov r0, r4 - bl SetIrqFlag - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_02079F5C: - mov r0, r6 - bl OS_SleepThread - ldr r1, [r6, #0x14] - ldr r0, [r6, #0x1c] - cmp r1, r0 - ble _02079F44 -_02079F74: - ldr r0, [r6, #0x18] - add r0, r0, r1 - sub r0, r0, #1 - bl _s32_div_f - str r1, [r6, #0x18] - ldr r0, [r6, #0x10] - str r5, [r0, r1, lsl #2] - ldr r1, [r6, #0x1c] - add r0, r6, #8 - add r1, r1, #1 - str r1, [r6, #0x1c] - bl OS_WakeupThread - mov r0, r4 - bl SetIrqFlag - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_JamMessage - - arm_func_start OS_ReadMessage -OS_ReadMessage: ; 0x02079FB4 - stmdb sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl EnableIrqFlag - ldr r1, [r6, #0x1c] - mov r4, r0 - cmp r1, #0 - bne _0207A008 - and r7, r7, #1 -_02079FDC: - cmp r7, #0 - bne _02079FF4 - mov r0, r4 - bl SetIrqFlag - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_02079FF4: - add r0, r6, #8 - bl OS_SleepThread - ldr r0, [r6, #0x1c] - cmp r0, #0 - beq _02079FDC -_0207A008: - cmp r5, #0 - beq _0207A020 - ldr r1, [r6, #0x10] - ldr r0, [r6, #0x18] - ldr r0, [r1, r0, lsl #2] - str r0, [r5] -_0207A020: - mov r0, r4 - bl SetIrqFlag - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_ReadMessage - diff --git a/lib/NitroSDK/src/os_message.c b/lib/NitroSDK/src/os_message.c new file mode 100644 index 00000000..67657707 --- /dev/null +++ b/lib/NitroSDK/src/os_message.c @@ -0,0 +1,92 @@ +#include + +void OS_InitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount) { + OS_InitThreadQueue(&mq->queueSend); + OS_InitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +BOOL OS_SendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) { + OSIntrMode enabled; + s32 lastIndex; + + enabled = EnableIrqFlag(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + SetIrqFlag(enabled); + return FALSE; + } + OS_SleepThread(&mq->queueSend); + } + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + OS_WakeupThread(&mq->queueReceive); + SetIrqFlag(enabled); + return TRUE; +} + +BOOL OS_ReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) { + OSIntrMode enabled; + + enabled = EnableIrqFlag(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + SetIrqFlag(enabled); + return FALSE; + } + OS_SleepThread(&mq->queueReceive); + } + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + OS_WakeupThread(&mq->queueSend); + SetIrqFlag(enabled); + return TRUE; +} + +BOOL OS_JamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) { + OSIntrMode enabled; + + enabled = EnableIrqFlag(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + SetIrqFlag(enabled); + return FALSE; + } + OS_SleepThread(&mq->queueSend); + } + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + OS_WakeupThread(&mq->queueReceive); + SetIrqFlag(enabled); + return TRUE; +} + +BOOL OS_ReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) { + OSIntrMode enabled; + + enabled = EnableIrqFlag(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + SetIrqFlag(enabled); + return FALSE; + } + OS_SleepThread(&mq->queueReceive); + } + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + SetIrqFlag(enabled); + return TRUE; +} diff --git a/lib/NitroSDK/src/os_mutex.c b/lib/NitroSDK/src/os_mutex.c index 9121b19d..829fc3f7 100644 --- a/lib/NitroSDK/src/os_mutex.c +++ b/lib/NitroSDK/src/os_mutex.c @@ -3,9 +3,9 @@ void OSi_EnqueueTail(OSThread *thread, OSMutex *mtx); void OSi_DequeueItem(OSThread *thread, OSMutex *mtx); -extern void OS_SleepThread(void *); -extern void OS_WakeupThread(void *); -extern OSMutex *OSi_RemoveMutexLinkFromQueue(void *); +// extern void OS_SleepThread(void *); +// extern void OS_WakeupThread(void *); +// extern OSMutex *OSi_RemoveMutexLinkFromQueue(void *); void OS_InitMutex(OSMutex *mtx) { OS_InitThreadQueue(&mtx->queue); diff --git a/lib/include/nitro/os.h b/lib/include/nitro/os.h index ccd10487..7540266f 100644 --- a/lib/include/nitro/os.h +++ b/lib/include/nitro/os.h @@ -29,6 +29,7 @@ //#include #include #include +#include //#include //#include //#include diff --git a/lib/include/nitro/os/message.h b/lib/include/nitro/os/message.h new file mode 100644 index 00000000..96dcaf7f --- /dev/null +++ b/lib/include/nitro/os/message.h @@ -0,0 +1,15 @@ +#ifndef NITRO_OS_MESSAGE_H +#define NITRO_OS_MESSAGE_H + +#include +#include +#include +#include + +void OS_InitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount); +BOOL OS_SendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); +BOOL OS_ReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); +BOOL OS_JamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); +BOOL OS_ReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); + +#endif //NITRO_OS_MESSAGE_H diff --git a/lib/include/nitro/os/thread.h b/lib/include/nitro/os/thread.h new file mode 100644 index 00000000..85b5c648 --- /dev/null +++ b/lib/include/nitro/os/thread.h @@ -0,0 +1,41 @@ +#ifndef NITRO_OS_THREAD_H_ +#define NITRO_OS_THREAD_H_ + +#include +#include + +#define SDK_THREAD_INFINITY + +s32 OSi_GetUnusedThreadId(void); +OSThread *OSi_RemoveLinkFromQueue(OSThreadQueue *queue); +OSThread *OSi_RemoveSpecifiedLinkFromQueue(OSThreadQueue *queue, OSThread *thread); +OSMutex *OSi_RemoveMutexLinkFromQueue(OSMutexQueue *queue); +void OSi_InsertThreadToList(OSThread *thread); +void OSi_RemoveThreadFromList(OSThread *thread); +void OSi_RescheduleThread(void); +void OS_InitThread(void); +BOOL OS_IsThreadAvailable(void); +void OS_CreateThread(OSThread *thread, void (*func) (void *), void *arg, void *stack, u32 stackSize, u32 prio); +void OS_ExitThread(void); +void OS_DestroyThread(OSThread *thread); +void OS_KillThread(OSThread *thread, void *arg); +void OS_KillThreadWithPriority(OSThread *thread, void *arg, u32 prio); +void OSi_CancelThreadAlarmForSleep(OSThread *thread); +void OS_JoinThread(OSThread *thread); +BOOL OS_IsThreadTerminated(const OSThread *thread); +void OS_SleepThread(OSThreadQueue *queue); +void OS_WakeupThread(OSThreadQueue *queue); +void OS_WakeupThreadDirect(OSThread *thread); +OSThread *OS_SelectThread(void); +void OS_RescheduleThread(void); +void OS_YieldThread(void); +BOOL OS_SetThreadPriority(OSThread *thread, u32 prio); +u32 OS_GetThreadPriority(const OSThread *thread); +void OS_Sleep(u32 msec); +OSSwitchThreadCallback OS_SetSwitchThreadCallback(OSSwitchThreadCallback callback); +u32 OS_DisableScheduler(void); +u32 OS_EnableScheduler(void); +void OS_SetThreadDestructor(OSThread *thread, OSThreadDestructor dtor); +void OSi_InsertLinkToQueue(OSThreadQueue *queue, OSThread *thread); + +#endif //NITRO_OS_THREAD_H_ diff --git a/main.lsf b/main.lsf index 81bdf865..d34aaa16 100644 --- a/main.lsf +++ b/main.lsf @@ -241,7 +241,7 @@ Static main Object lib/NitroSDK/asm/os_thread.o Object lib/NitroSDK/asm/os_context.o Object lib/NitroSDK/asm/os_emulator.o - Object lib/NitroSDK/asm/os_message.o + Object lib/NitroSDK/src/os_message.o Object lib/NitroSDK/src/os_mutex.o Object lib/NitroSDK/src/os_cache.o Object lib/NitroSDK/src/os_init.o diff --git a/src/main_02000C6C.c b/src/main_02000C6C.c index 1e378985..1bdbbe37 100644 --- a/src/main_02000C6C.c +++ b/src/main_02000C6C.c @@ -17,7 +17,6 @@ extern void sub_02003ECC(); extern void sub_020082F4(u32*); extern void sub_0204A5D0(); extern void FX_Init(); -extern void OS_DisableScheduler(); extern u32 OS_GetArenaHi(u32); extern u32 OS_GetArenaLo(u32); extern u32 OS_SetArenaLo(u32, u32);