This commit is contained in:
Yotona 2024-11-10 12:09:24 -07:00
parent 79ff104c06
commit bc3cadd56a
7 changed files with 258 additions and 2 deletions

View File

@ -277,8 +277,8 @@ segments:
#- [0x, asm, P2/target]
- [0xe18f8, asm, P2/text]
#- [0x, asm, P2/thread]
#- [0x, asm, P2/tn]
- [0xe3268, c, P2/thread]
- [0xe3420, asm, P2/tn]
- [0xe5e38, c, P2/transition]
- [0xe6378, asm, P2/turret]

View File

@ -4,6 +4,8 @@ _exit = 0x1000B8; // type:func
__builtin_delete = 0x18d778; // type:func
memcmp = 0x1F59C4; // type:func
_gpReg = 0x2832F0;
////////////////////////////////////////////////////////////////
// Unknown file
// Related to save files
@ -1069,6 +1071,19 @@ DecrementSwHandsOff__FP2SW = 0x1dda50; // type:func
g_psw = 0x275710; // size:0x4
////////////////////////////////////////////////////////////////
// P2/thread.c
////////////////////////////////////////////////////////////////
SemaCreate__Fii = 0x1e2268; // type:func
InitCritSect__FP8CRITSECT = 0x1e22c0; // type:func
EnterCritSect__FP8CRITSECT = 0x1e22f8; // type:func
LeaveCritSect__FP8CRITSECT = 0x1e2358; // type:func
StartupThread__Fv = 0x1e2398; // type:func
g_athread = 0x275958; // size:0xC
g_abRenderLoopStack = 0x6056d0; // size:0x20000
////////////////////////////////////////////////////////////////
// P2/transition.c
////////////////////////////////////////////////////////////////
@ -1220,6 +1235,17 @@ sceCdBreak = 0x203e28; // type:func
sceClose = 0x1f8c38; // type:func
////////////////////////////////////////////////////////////////
// sce/klib.c
////////////////////////////////////////////////////////////////
CreateThread = 0x1F6A10; // type:func
ChangeThreadPriority = 0x1F6A50; // type:func
GetThreadId = 0x1F6A90; // type:func
CreateSema = 0x1F6B20; // type:func
SignalSema = 0x1F6B40; // type:func
WaitSema = 0x1F6B60; // type:func
////////////////////////////////////////////////////////////////
// sce/rand.c
////////////////////////////////////////////////////////////////

View File

@ -11,6 +11,8 @@
#include "types.h"
#include "vtables.h"
extern int _gpReg; // Global pointer register
/**
* @brief RGBA color value.
*/

View File

@ -10,4 +10,8 @@
// ...
void FrameRenderLoop(void*);
extern u8 g_abRenderLoopStack[0x20000];
#endif // FRM_H

100
include/sce/kernel.h Normal file
View File

@ -0,0 +1,100 @@
/**
* @file kernel.h
*
* @brief Control for Semaphores and Threads
*/
#ifndef KERNEL_H
#define KERNEL_H
#include "common.h"
extern "C" {
struct ThreadParam {
int status; // Thread status
void (*entry)(void *); // Thread entry point
void *stack; // Stack address used by the thread (16-byte aligned)
int stackSize; // Stack size in bytes, must be a multiple of 16
void *gpReg; // GP register value
int initPriority; // Initial thread priority (1-127). Must be specified when creating a thread
int currentPriority; // Current thread priority
unsigned int attr; // Reserved for system use
unsigned int option; // Reserved for system use
int waitType; // Wait type
int waitId; // Semaphore ID if waitType is "semaphore"
int wakeupCount; // Wakeup request count
};
struct SemaParam {
int currentCount; // Current semaphore count
int maxCount; // Maximum semaphore count
int initCount; // Initial semaphore count
int numWaitThreads; // Number of threads waiting on the semaphore
unsigned int attr; // Semaphore attributes
unsigned int option; // Optional user-defined data
};
/**
* @brief Create a counting semaphore object.
*
* @details Up to 256 semaphores can be created, 3 of which are reserved during runtime
* initialization by `crt0.s` (2 from `_InitSys` and 1 from `InitThread`).
*
* @param sparam Initial semaphore parameters
* @return Semaphore ID on success, -1 if creation would exceed the maximum number of semaphores
* or a negative value was passed for `sema->initCount`
*/
int CreateSema(SemaParam *sparam);
/**
* @brief Get semaphore resource
*
* @param sema Semaphore ID
* @return Semaphore count on success, -1 on failure
*/
int WaitSema(int sema);
/**
* @brief Release semaphore resource
*
* @details If the `sid` value is 0 and there is no free space in the semaphore queue,
* the thread at the wait queue start will be released and placed in READY state.
* In all other cases, the value of the semaphore is incremented.
*
* @param sid Semaphore ID
* @return Semaphore ID on success, -1 on failure
*/
int SignalSema(int sid);
/**
* @brief Create a new thread
*
* @details The created thread is placed in a DORMANT state and not executed until the thread is started.
*
* @param tparam Initial thread parameters
*
* @return Thread ID on success, -1 on failure
*/
int CreateThread(struct ThreadParam *tparam);
/**
* @brief Get the ID of the calling thread.
*
* @return Thread ID
*/
int GetThreadId(void);
/**
* @brief Change the priority of a thread
*
* @details The thread will be entered at the end of the ready queue at the corresponding priority.
* The new priority setting will be valid until the thread is terminated or the priority is changed again.
*
* @param tid Thread ID
* @param priority New priority (1-127)
*
* @return The previous priority of the thread on success, -1 on failure
*/
int ChangeThreadPriority(int tid, int priority);
}
#endif // KERNEL_H

55
include/thread.h Normal file
View File

@ -0,0 +1,55 @@
/**
* @file thread.h
*
* @brief Thread and critical section utilities
*/
#ifndef THREAD_H
#define THREAD_H
#include "common.h"
struct CRITSECT
{
int cEnter;
int thread;
int sema;
};
/**
* @brief Create a semaphore.
*
* @param initCount Initial count.
* @param maxCount Maximum count.
* @return The semaphore ID.
*/
int SemaCreate(int initCount, int maxCount);
/**
* @brief Initialize a critical section.
*
* @param pcritsect Critical section.
*/
void InitCritSect(CRITSECT* pcritsect);
/**
* @brief Enter a critical section.
*
* @param pcritsect Critical section.
*/
void EnterCritSect(CRITSECT* pcritsect);
/**
* @brief Leave a critical section.
*
* @param pcritsect Critical section.
*/
void LeaveCritSect(CRITSECT* pcritsect);
/**
* @brief Initialize parameters for a rendering thread.
*/
void StartupThread();
extern CRITSECT g_athread;
#endif // THREAD_H

69
src/P2/thread.c Normal file
View File

@ -0,0 +1,69 @@
#include "common.h"
#include <sce/kernel.h>
#include <sce/memset.h>
#include <thread.h>
#include <frm.h>
int SemaCreate(int initCount, int maxCount)
{
SemaParam sp;
memset(&sp, 0, sizeof(SemaParam));
sp.initCount = initCount;
sp.maxCount = maxCount;
return CreateSema(&sp);
}
INCLUDE_ASM(const s32, "P2/thread", func_001E22B8);
void InitCritSect(CRITSECT *pcritsect)
{
pcritsect->thread = -1;
pcritsect->sema = SemaCreate(1, 1);
}
void EnterCritSect(CRITSECT *pcritsect)
{
int threadId = GetThreadId();
if (threadId != pcritsect->thread)
{
WaitSema(pcritsect->sema);
pcritsect->thread = threadId;
pcritsect->cEnter = 1;
}
else
{
pcritsect->cEnter++;
}
}
void LeaveCritSect(CRITSECT *pcritsect)
{
int critSects = pcritsect->cEnter - 1;
pcritsect->cEnter = critSects;
if (critSects == 0) {
pcritsect->thread = -1;
SignalSema(pcritsect->sema);
}
}
INCLUDE_ASM(const s32, "P2/thread", func_001E2390);
void StartupThread()
{
ThreadParam tp;
g_athread.cEnter = GetThreadId();
ChangeThreadPriority(g_athread.cEnter, 4);
memset(&tp, 0, sizeof(ThreadParam));
tp.stackSize = 0x20000;
tp.stack = g_abRenderLoopStack;
tp.initPriority = 2;
tp.gpReg = &_gpReg;
tp.entry = FrameRenderLoop;
g_athread.thread = CreateThread(&tp);
}