jabyengine/include/PSX/System/syscalls.hpp

167 lines
6.3 KiB
C++

#pragma once
#include "../jabyengine_defines.h"
/*
R0 zr Constant Zero
R1 at Reserved for the assembler
R2-R3 v0-v1 Values for results and expression evaluation
R4-R7 a0-a3 Arguments
R8-R15 t0-t7 Temporaries (not preserved across call)
R16-R23 s0-s7 Saved (preserved across call)
R24-R25 t8-t9 More temporaries (not preserved across call)
R26-R27 k0-k1 Reserved for OS Kernel
R28 gp Global Pointer
R29 sp Stack Pointer
R30 fp Frame Pointer
R31 ra Return address (set by function call)
*/
namespace JabyEngine {
namespace SysCall {
static constexpr const uint32_t Table_A = 0xA0;
static constexpr const uint32_t Table_B = 0xB0;
static constexpr const uint32_t Table_C = 0xC0;
enum struct Priority {
CdromDmaIrq = 0,
CdromIoIrq = 0,
SyscallException = 0,
CardSpecificIrq = 1,
VblankIrq = 1,
Timer2Irq = 1,
Timer1Irq = 1,
Timer0Irq = 1,
PadCardIrq = 2,
DefInt = 3
};
enum InterruptVerifierResult {
SkipHandler = 0,
ExecuteHandler = 1
};
typedef InterruptVerifierResult (*InterruptVerifier)();
typedef uint32_t (*InterruptHandler)(uint32_t);
#pragma pack(push, 1)
struct InterrupCallback {
struct InterrupCallback* next;
InterruptHandler handler_function;
InterruptVerifier verifier_function;
uint32_t notUsed;
};
#pragma pack(pop)
#define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table)
static __always_inline void* memcpy(void *dst, const void *src, size_t len) {
register uint32_t FuncID asm("t1") = 0x2A;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len);
}
static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) {
register uint32_t FuncID asm("t1") = 0x12;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize);
}
static __always_inline void StartPad() {
register uint32_t FuncID asm("t1") = 0x13;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())();
}
static __always_inline void StopPad() {
register uint32_t FuncID asm("t1") = 0x14;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())();
}
static __always_inline void ChangeClearPad(int32_t _reserved) {
register uint32_t FuncID asm("t1") = 0x5B;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)(int32_t))(_reserved);
}
static __always_inline void [[noreturn]] ReturnFromException() {
register uint32_t FuncID asm("t1") = 0x17;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void(*)())();
}
static __always_inline int SysEnqIntRP(Priority prio, InterrupCallback* interElm) {
register uint32_t FuncID asm("t1") = 0x02;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm);
}
static __always_inline int SysDeqIntRP(Priority prio, InterrupCallback *interElm) {
register uint32_t FuncID asm("t1") = 0x03;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm);
}
static __always_inline uint32_t EnterCriticalSection() {
register uint32_t FuncID asm("a0") = 0x01;
register uint32_t returnValue asm("v0");
__asm__ volatile("syscall" : "=r"(FuncID), "=r"(returnValue) : "r"(FuncID) : "at", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory");
return returnValue;
}
static __always_inline void ExitCriticalSection() {
register uint32_t FuncID asm("a0") = 0x02;
__asm__ volatile("syscall" : "=r"(FuncID) : "r"(FuncID) : "at", "v0", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory");
}
static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) {
register uint32_t FuncID asm("t1") = 0x07;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
__syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec);
}
static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) {
register uint32_t FuncID asm("t1") = 0x08;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler);
}
static __always_inline int CloseEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x09;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event);
}
static __always_inline int TestEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x0B;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, int (*)(uint32_t))(event);
}
static __always_inline int EnableEvent(uint32_t event) {
register uint32_t FuncID asm("t1") = 0x0C;
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
return __syscall_function_cast(Table_B, int (*)(uint32_t))(event);
}
void printf(const char* txt, ...);
}
}