261 lines
9.1 KiB
C++
261 lines
9.1 KiB
C++
#pragma once
|
|
#include "../jabyengine_defines.hpp"
|
|
|
|
/*
|
|
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 BIOS {
|
|
struct Version {
|
|
enum Type {
|
|
Unkown,
|
|
Devboard,
|
|
PS1,
|
|
PS2,
|
|
PS3,
|
|
PSCompatible, // internal usage only
|
|
No$psx,
|
|
XEBRA
|
|
};
|
|
|
|
struct {
|
|
uint8_t day;
|
|
uint8_t month;
|
|
uint16_t year;
|
|
} date;
|
|
Type type;
|
|
const char* kernel_maker;
|
|
const char* version_str;
|
|
const char* gui_version;
|
|
const char* copyright;
|
|
};
|
|
|
|
extern const Version version;
|
|
}
|
|
|
|
struct TCB {
|
|
uint32_t status;
|
|
uint32_t unused;
|
|
uint32_t reg[32];
|
|
uint32_t epc;
|
|
uint32_t hi;
|
|
uint32_t lo;
|
|
uint32_t sr;
|
|
uint32_t cause;
|
|
uint32_t unused2[9];
|
|
};
|
|
|
|
struct PCB {
|
|
TCB* current_tcb;
|
|
};
|
|
|
|
struct ToT {
|
|
using ExCB = void;
|
|
using EvCB = void;
|
|
using FCB = void;
|
|
|
|
ExCB* exception_chain;
|
|
uint32_t exception_chain_size;
|
|
PCB* processes;
|
|
uint32_t processes_size;
|
|
TCB* threads;
|
|
uint32_t threads_size;
|
|
uint32_t reserved_0;
|
|
uint32_t reserved_1;
|
|
EvCB* events;
|
|
uint32_t events_size;
|
|
uint32_t reserved_2;
|
|
uint32_t reserved_3;
|
|
uint32_t reserved_4;
|
|
uint32_t reserved_5;
|
|
uint32_t reserved_6;
|
|
uint32_t reserved_7;
|
|
FCB* files;
|
|
uint32_t files_size;
|
|
uint32_t reserved_8;
|
|
uint32_t reserved_9;
|
|
};
|
|
|
|
extern ToT table_of_tables;
|
|
|
|
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);
|
|
using ThreadHandle = 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 uint32_t* get_gp() {
|
|
uint32_t* gp;
|
|
__asm__("sw $gp, %0" : "=m"(gp));
|
|
return gp;
|
|
}
|
|
|
|
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 ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) {
|
|
register uint32_t FuncID asm("t1") = 0x0E;
|
|
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
|
|
|
return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp);
|
|
}
|
|
|
|
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 int32_t TestEvent(uint32_t event) {
|
|
register uint32_t FuncID asm("t1") = 0x0B;
|
|
|
|
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
|
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
|
}
|
|
|
|
static __always_inline int32_t EnableEvent(uint32_t event) {
|
|
register uint32_t FuncID asm("t1") = 0x0C;
|
|
|
|
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
|
return __syscall_function_cast(Table_B, int32_t (*)(uint32_t))(event);
|
|
}
|
|
|
|
static __always_inline const uint16_t* Krom2RawAdd(uint16_t sjis_code) {
|
|
register uint32_t FuncID asm("t1") = 0x51;
|
|
|
|
__asm__ volatile("" : "=r"(FuncID) : "r"(FuncID));
|
|
return __syscall_function_cast(Table_B, const uint16_t* (*)(uint16_t))(sjis_code);
|
|
}
|
|
|
|
void printf(const char* txt, ...);
|
|
}
|
|
} |