summaryrefslogtreecommitdiff
path: root/include/dolphin/os
diff options
context:
space:
mode:
Diffstat (limited to 'include/dolphin/os')
-rw-r--r--include/dolphin/os/OSAlarm.h39
-rw-r--r--include/dolphin/os/OSArena.h13
-rw-r--r--include/dolphin/os/OSBootInfo.h39
-rw-r--r--include/dolphin/os/OSCache.h37
-rw-r--r--include/dolphin/os/OSContext.h170
-rw-r--r--include/dolphin/os/OSError.h39
-rw-r--r--include/dolphin/os/OSException.h56
-rw-r--r--include/dolphin/os/OSExpansion.h79
-rw-r--r--include/dolphin/os/OSFastCast.h48
-rw-r--r--include/dolphin/os/OSFont.h56
-rw-r--r--include/dolphin/os/OSInterrupt.h115
-rw-r--r--include/dolphin/os/OSMemory.h26
-rw-r--r--include/dolphin/os/OSMessage.h34
-rw-r--r--include/dolphin/os/OSModule.h115
-rw-r--r--include/dolphin/os/OSMutex.h35
-rw-r--r--include/dolphin/os/OSPriv.h18
-rw-r--r--include/dolphin/os/OSReboot.h10
-rw-r--r--include/dolphin/os/OSReset.h48
-rw-r--r--include/dolphin/os/OSResetSW.h22
-rw-r--r--include/dolphin/os/OSSerial.h69
-rw-r--r--include/dolphin/os/OSThread.h113
21 files changed, 1181 insertions, 0 deletions
diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h
new file mode 100644
index 0000000..a0c9d38
--- /dev/null
+++ b/include/dolphin/os/OSAlarm.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSALARM
+#define _DOLPHIN_OSALARM
+
+#include <dolphin/os/OSContext.h>
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OSAlarm OSAlarm;
+typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context);
+
+struct OSAlarm {
+ OSAlarmHandler handler;
+ u32 tag;
+ OSTime fire;
+ OSAlarm* prev;
+ OSAlarm* next;
+ OSTime period;
+ OSTime start;
+};
+
+void OSInitAlarm(void);
+void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler);
+void OSSetAlarmTag(OSAlarm* alarm, u32 tag);
+void OSSetAbsAlarm(OSAlarm* alarm, OSTime time, OSAlarmHandler handler);
+void OSSetPeriodicAlarm(OSAlarm* alarm, OSTime start, OSTime period, OSAlarmHandler handler);
+void OSCreateAlarm(OSAlarm* alarm);
+void OSCancelAlarm(OSAlarm* alarm);
+void OSCancelAlarms(u32 tag);
+
+BOOL OSCheckAlarmQueue(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSALARM
diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h
new file mode 100644
index 0000000..9dc1570
--- /dev/null
+++ b/include/dolphin/os/OSArena.h
@@ -0,0 +1,13 @@
+#ifndef _DOLPHIN_OSARENA
+#define _DOLPHIN_OSARENA
+
+#include <dolphin/types.h>
+
+void* OSGetArenaHi(void);
+void* OSGetArenaLo(void);
+void OSSetArenaHi(void* addr);
+void OSSetArenaLo(void* addr);
+void* OSAllocFromArenaLo(u32 size, u32 align);
+void* OSAllocFromArenaLo(u32 size, u32 align);
+
+#endif // _DOLPHIN_OSARENA
diff --git a/include/dolphin/os/OSBootInfo.h b/include/dolphin/os/OSBootInfo.h
new file mode 100644
index 0000000..e52a4ac
--- /dev/null
+++ b/include/dolphin/os/OSBootInfo.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSBOOTINFO
+#define _DOLPHIN_OSBOOTINFO
+
+typedef struct OSBootInfo {
+ DVDDiskID DVDDiskID;
+ u32 magic;
+ u32 version;
+ u32 memorySize;
+ u32 consoleType;
+ void* arenaLo;
+ void* arenaHi;
+ void* FSTLocation;
+ u32 FSTMaxLength;
+} OSBootInfo;
+
+typedef struct {
+ BOOL valid;
+ u32 restartCode;
+ u32 bootDol;
+ void* regionStart;
+ void* regionEnd;
+ BOOL argsUseDefault;
+ void* argsAddr; // valid only when argsUseDefault = FALSE
+
+} OSExecParams;
+
+typedef struct BI2Debug {
+ s32 debugMonSize; // 0x0
+ s32 simMemSize; // 0x4
+ u32 argOffset; // 0x8
+ u32 debugFlag; // 0xC
+ int trackLocation; // 0x10
+ int trackSize; // 0x14
+ u32 countryCode; // 0x18
+ u8 unk[8]; // 0x1C
+ u32 padSpec; // 0x24
+} BI2Debug;
+
+#endif // _DOLPHIN_OSBOOTINFO
diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h
new file mode 100644
index 0000000..b3dd94a
--- /dev/null
+++ b/include/dolphin/os/OSCache.h
@@ -0,0 +1,37 @@
+#ifndef _DOLPHIN_OSCACHE
+#define _DOLPHIN_OSCACHE
+
+#include "dolphin/types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void DCInvalidateRange(void* addr, u32 nBytes);
+void DCFlushRange(void* addr, u32 nBytes);
+void DCStoreRange(void* addr, u32 nBytes);
+void DCFlushRangeNoSync(void* addr, u32 nBytes);
+void DCStoreRangeNoSync(void* addr, u32 nBytes);
+void DCZeroRange(void* addr, u32 nBytes);
+void DCTouchRange(void* addr, u32 nBytes);
+void ICInvalidateRange(void* addr, u32 nBytes);
+
+#define LC_BASE_PREFIX 0xE000
+#define LC_BASE (LC_BASE_PREFIX << 16)
+#define LCGetBase() ((void*)LC_BASE)
+
+void LCEnable();
+void LCDisable(void);
+void LCLoadBlocks(void* destTag, void* srcAddr, u32 numBlocks);
+void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks);
+u32 LCLoadData(void* destAddr, void* srcAddr, u32 nBytes);
+u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes);
+u32 LCQueueLength(void);
+void LCQueueWait(u32 len);
+void LCFlushQueue(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSCACHE
diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h
new file mode 100644
index 0000000..bbd0aaa
--- /dev/null
+++ b/include/dolphin/os/OSContext.h
@@ -0,0 +1,170 @@
+#ifndef _DOLPHIN_OSCONTEXT
+#define _DOLPHIN_OSCONTEXT
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __OS_CONTEXT_FRAME 768
+
+#define OS_CONTEXT_R0 0
+#define OS_CONTEXT_R1 4
+#define OS_CONTEXT_R2 8
+#define OS_CONTEXT_R3 12
+#define OS_CONTEXT_R4 16
+#define OS_CONTEXT_R5 20
+#define OS_CONTEXT_R6 24
+#define OS_CONTEXT_R7 28
+#define OS_CONTEXT_R8 32
+#define OS_CONTEXT_R9 36
+#define OS_CONTEXT_R10 40
+#define OS_CONTEXT_R11 44
+#define OS_CONTEXT_R12 48
+#define OS_CONTEXT_R13 52
+#define OS_CONTEXT_R14 56
+#define OS_CONTEXT_R15 60
+#define OS_CONTEXT_R16 64
+#define OS_CONTEXT_R17 68
+#define OS_CONTEXT_R18 72
+#define OS_CONTEXT_R19 76
+#define OS_CONTEXT_R20 80
+#define OS_CONTEXT_R21 84
+#define OS_CONTEXT_R22 88
+#define OS_CONTEXT_R23 92
+#define OS_CONTEXT_R24 96
+#define OS_CONTEXT_R25 100
+#define OS_CONTEXT_R26 104
+#define OS_CONTEXT_R27 108
+#define OS_CONTEXT_R28 112
+#define OS_CONTEXT_R29 116
+#define OS_CONTEXT_R30 120
+#define OS_CONTEXT_R31 124
+
+#define OS_CONTEXT_CR 128
+#define OS_CONTEXT_LR 132
+#define OS_CONTEXT_CTR 136
+#define OS_CONTEXT_XER 140
+
+#define OS_CONTEXT_FPR0 144
+#define OS_CONTEXT_FPR1 152
+#define OS_CONTEXT_FPR2 160
+#define OS_CONTEXT_FPR3 168
+#define OS_CONTEXT_FPR4 176
+#define OS_CONTEXT_FPR5 184
+#define OS_CONTEXT_FPR6 192
+#define OS_CONTEXT_FPR7 200
+#define OS_CONTEXT_FPR8 208
+#define OS_CONTEXT_FPR9 216
+#define OS_CONTEXT_FPR10 224
+#define OS_CONTEXT_FPR11 232
+#define OS_CONTEXT_FPR12 240
+#define OS_CONTEXT_FPR13 248
+#define OS_CONTEXT_FPR14 256
+#define OS_CONTEXT_FPR15 264
+#define OS_CONTEXT_FPR16 272
+#define OS_CONTEXT_FPR17 280
+#define OS_CONTEXT_FPR18 288
+#define OS_CONTEXT_FPR19 296
+#define OS_CONTEXT_FPR20 304
+#define OS_CONTEXT_FPR21 312
+#define OS_CONTEXT_FPR22 320
+#define OS_CONTEXT_FPR23 328
+#define OS_CONTEXT_FPR24 336
+#define OS_CONTEXT_FPR25 344
+#define OS_CONTEXT_FPR26 352
+#define OS_CONTEXT_FPR27 360
+#define OS_CONTEXT_FPR28 368
+#define OS_CONTEXT_FPR29 376
+#define OS_CONTEXT_FPR30 384
+#define OS_CONTEXT_FPR31 392
+
+#define OS_CONTEXT_FPSCR 400
+
+#define OS_CONTEXT_SRR0 408
+#define OS_CONTEXT_SRR1 412
+
+#define OS_CONTEXT_MODE 416
+#define OS_CONTEXT_STATE 418
+
+#define OS_CONTEXT_GQR0 420
+#define OS_CONTEXT_GQR1 424
+#define OS_CONTEXT_GQR2 428
+#define OS_CONTEXT_GQR3 432
+#define OS_CONTEXT_GQR4 436
+#define OS_CONTEXT_GQR5 440
+#define OS_CONTEXT_GQR6 444
+#define OS_CONTEXT_GQR7 448
+#define __OSCONTEXT_PADDING 452
+
+#define OS_CONTEXT_PSF0 456
+#define OS_CONTEXT_PSF1 464
+#define OS_CONTEXT_PSF2 472
+#define OS_CONTEXT_PSF3 480
+#define OS_CONTEXT_PSF4 488
+#define OS_CONTEXT_PSF5 496
+#define OS_CONTEXT_PSF6 504
+#define OS_CONTEXT_PSF7 512
+#define OS_CONTEXT_PSF8 520
+#define OS_CONTEXT_PSF9 528
+#define OS_CONTEXT_PSF10 536
+#define OS_CONTEXT_PSF11 544
+#define OS_CONTEXT_PSF12 552
+#define OS_CONTEXT_PSF13 560
+#define OS_CONTEXT_PSF14 568
+#define OS_CONTEXT_PSF15 576
+#define OS_CONTEXT_PSF16 584
+#define OS_CONTEXT_PSF17 592
+#define OS_CONTEXT_PSF18 600
+#define OS_CONTEXT_PSF19 608
+#define OS_CONTEXT_PSF20 616
+#define OS_CONTEXT_PSF21 624
+#define OS_CONTEXT_PSF22 632
+#define OS_CONTEXT_PSF23 640
+#define OS_CONTEXT_PSF24 648
+#define OS_CONTEXT_PSF25 656
+#define OS_CONTEXT_PSF26 664
+#define OS_CONTEXT_PSF27 672
+#define OS_CONTEXT_PSF28 680
+#define OS_CONTEXT_PSF29 688
+#define OS_CONTEXT_PSF30 696
+#define OS_CONTEXT_PSF31 704
+#define OS_CONTEXT_STATE_EXC 0x02u
+
+#define OS_CONTEXT_STATE_FPSAVED 0x01u
+
+typedef struct OSContext {
+ u32 gpr[32];
+ u32 cr;
+ u32 lr;
+ u32 ctr;
+ u32 xer;
+
+ f64 fpr[32];
+
+ u32 fpscr_pad;
+ u32 fpscr;
+
+ u32 srr0;
+ u32 srr1;
+
+ u16 mode;
+ u16 state;
+
+ u32 gqr[8];
+ u32 psf_pad;
+ f64 psf[32];
+
+} OSContext;
+
+u32 OSSaveContext(OSContext* context);
+void OSClearContext(OSContext* context);
+OSContext* OSGetCurrentContext();
+void OSSetCurrentContext(OSContext* context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSCONTEXT
diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h
new file mode 100644
index 0000000..8764fbe
--- /dev/null
+++ b/include/dolphin/os/OSError.h
@@ -0,0 +1,39 @@
+#ifndef _DOLPHIN_OSERROR
+#define _DOLPHIN_OSERROR
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_ERROR_SYSTEM_RESET 0
+#define OS_ERROR_MACHINE_CHECK 1
+#define OS_ERROR_DSI 2
+#define OS_ERROR_ISI 3
+#define OS_ERROR_EXTERNAL_INTERRUPT 4
+#define OS_ERROR_ALIGNMENT 5
+#define OS_ERROR_PROGRAM 6
+#define OS_ERROR_FLOATING_POINT 7
+#define OS_ERROR_DECREMENTER 8
+#define OS_ERROR_SYSTEM_CALL 9
+#define OS_ERROR_TRACE 10
+#define OS_ERROR_PERFORMACE_MONITOR 11
+#define OS_ERROR_BREAKPOINT 12
+#define OS_ERROR_SYSTEM_INTERRUPT 13
+#define OS_ERROR_THERMAL_INTERRUPT 14
+#define OS_ERROR_PROTECTION 15
+#define OS_ERROR_FPE 16
+
+#define OS_ERROR_MAX (OS_ERROR_FPE + 1)
+
+typedef u16 OSError;
+typedef void (*OSErrorHandler)( OSError error, OSContext* context, ... );
+
+OSErrorHandler OSSetErrorHandler(OSError code, OSErrorHandler handler);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSERROR
diff --git a/include/dolphin/os/OSException.h b/include/dolphin/os/OSException.h
new file mode 100644
index 0000000..f342369
--- /dev/null
+++ b/include/dolphin/os/OSException.h
@@ -0,0 +1,56 @@
+
+#ifndef _DOLPHIN_OSEXCEPTION
+#define _DOLPHIN_OSEXCEPTION
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define __OS_EXCEPTION_SYSTEM_RESET 0
+#define __OS_EXCEPTION_MACHINE_CHECK 1
+#define __OS_EXCEPTION_DSI 2
+#define __OS_EXCEPTION_ISI 3
+#define __OS_EXCEPTION_EXTERNAL_INTERRUPT 4
+#define __OS_EXCEPTION_ALIGNMENT 5
+#define __OS_EXCEPTION_PROGRAM 6
+#define __OS_EXCEPTION_FLOATING_POINT 7
+#define __OS_EXCEPTION_DECREMENTER 8
+#define __OS_EXCEPTION_SYSTEM_CALL 9
+#define __OS_EXCEPTION_TRACE 10
+#define __OS_EXCEPTION_PERFORMACE_MONITOR 11
+#define __OS_EXCEPTION_BREAKPOINT 12
+#define __OS_EXCEPTION_SYSTEM_INTERRUPT 13
+#define __OS_EXCEPTION_THERMAL_INTERRUPT 14
+#define __OS_EXCEPTION_MAX \
+ (__OS_EXCEPTION_THERMAL_INTERRUPT+1)
+
+typedef u8 __OSException;
+typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context);
+
+#define OS_EXCEPTION_SAVE_GPRS(context) \
+ stw r0, OS_CONTEXT_R0(context); \
+ stw r1, OS_CONTEXT_R1(context); \
+ stw r2, OS_CONTEXT_R2(context); \
+ stmw r6, OS_CONTEXT_R6(context); \
+ mfspr r0, GQR1; \
+ stw r0, OS_CONTEXT_GQR1(context); \
+ mfspr r0, GQR2; \
+ stw r0, OS_CONTEXT_GQR2(context); \
+ mfspr r0, GQR3; \
+ stw r0, OS_CONTEXT_GQR3(context); \
+ mfspr r0, GQR4; \
+ stw r0, OS_CONTEXT_GQR4(context); \
+ mfspr r0, GQR5; \
+ stw r0, OS_CONTEXT_GQR5(context); \
+ mfspr r0, GQR6; \
+ stw r0, OS_CONTEXT_GQR6(context); \
+ mfspr r0, GQR7; \
+ stw r0, OS_CONTEXT_GQR7(context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSEXCEPTION
diff --git a/include/dolphin/os/OSExpansion.h b/include/dolphin/os/OSExpansion.h
new file mode 100644
index 0000000..6e848b8
--- /dev/null
+++ b/include/dolphin/os/OSExpansion.h
@@ -0,0 +1,79 @@
+#ifndef _DOLPHIN_OSEXPANSION
+#define _DOLPHIN_OSEXPANSION
+
+#include <dolphin/os.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXI_MEMORY_CARD_59 0x00000004
+#define EXI_MEMORY_CARD_123 0x00000008
+#define EXI_MEMORY_CARD_251 0x00000010
+#define EXI_MEMORY_CARD_507 0x00000020
+
+#define EXI_MEMORY_CARD_1019 0x00000040
+#define EXI_MEMORY_CARD_2043 0x00000080
+
+#define EXI_MEMORY_CARD_1019A 0x00000140
+#define EXI_MEMORY_CARD_1019B 0x00000240
+#define EXI_MEMORY_CARD_1019C 0x00000340
+#define EXI_MEMORY_CARD_1019D 0x00000440
+#define EXI_MEMORY_CARD_1019E 0x00000540
+#define EXI_MEMORY_CARD_1019F 0x00000640
+#define EXI_MEMORY_CARD_1019G 0x00000740
+
+#define EXI_MEMORY_CARD_2043A 0x00000180
+#define EXI_MEMORY_CARD_2043B 0x00000280
+#define EXI_MEMORY_CARD_2043C 0x00000380
+#define EXI_MEMORY_CARD_2043D 0x00000480
+#define EXI_MEMORY_CARD_2043E 0x00000580
+#define EXI_MEMORY_CARD_2043F 0x00000680
+#define EXI_MEMORY_CARD_2043G 0x00000780
+
+#define EXI_USB_ADAPTER 0x01010000
+#define EXI_NPDP_GDEV 0x01020000
+
+#define EXI_MODEM 0x02020000
+#define EXI_ETHER 0x04020200
+#define EXI_ETHER_VIEWER 0x04220001
+#define EXI_STREAM_HANGER 0x04130000
+
+#define EXI_MARLIN 0x03010000
+
+#define EXI_IS_VIEWER 0x05070000
+
+#define EXI_FREQ_1M 0
+#define EXI_FREQ_2M 1
+#define EXI_FREQ_4M 2
+#define EXI_FREQ_8M 3
+#define EXI_FREQ_16M 4
+#define EXI_FREQ_32M 5
+
+#define EXI_READ 0
+#define EXI_WRITE 1
+
+#define EXI_STATE_IDLE 0x00
+#define EXI_STATE_DMA 0x01
+#define EXI_STATE_IMM 0x02
+#define EXI_STATE_BUSY (EXI_STATE_DMA | EXI_STATE_IMM)
+#define EXI_STATE_SELECTED 0x04
+#define EXI_STATE_ATTACHED 0x08
+#define EXI_STATE_LOCKED 0x10
+
+BOOL EXIProbe(s32 chan);
+s32 EXIProbeEx(s32 chan);
+
+s32 EXIGetType(s32 chan, u32 dev, u32* type);
+char* EXIGetTypeString(u32 type);
+u32 EXIClearInterrupts(s32 chan, BOOL exi, BOOL tc, BOOL ext);
+s32 EXIGetID(s32 chan, u32 dev, u32* id);
+
+typedef void (*EXICallback)(s32 chan, OSContext* context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSEXPANSION
diff --git a/include/dolphin/os/OSFastCast.h b/include/dolphin/os/OSFastCast.h
new file mode 100644
index 0000000..b6ca50d
--- /dev/null
+++ b/include/dolphin/os/OSFastCast.h
@@ -0,0 +1,48 @@
+#ifndef _DOLPHIN_OSFASTCAST
+#define _DOLPHIN_OSFASTCAST
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_GQR_F32 0x0000
+#define OS_GQR_U8 0x0004
+#define OS_GQR_U16 0x0005
+#define OS_GQR_S8 0x0006
+#define OS_GQR_S16 0x0007
+
+#define OS_FASTCAST_U8 2
+#define OS_FASTCAST_U16 3
+#define OS_FASTCAST_S16 5
+// clang-format off
+static inline void OSInitFastCast(void) {
+#ifdef __MWERKS__
+ asm
+ {
+ li r3, OS_GQR_U8
+ oris r3, r3, OS_GQR_U8
+ mtspr GQR2, r3
+
+ li r3, OS_GQR_U16
+ oris r3, r3, OS_GQR_U16
+ mtspr GQR3, r3
+
+ li r3, OS_GQR_S8
+ oris r3, r3, OS_GQR_S8
+ mtspr GQR4, r3
+
+ li r3, OS_GQR_S16
+ oris r3, r3, OS_GQR_S16
+ mtspr GQR5, r3
+ }
+#else
+
+#endif
+}
+// clang-format off
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSFASTCAST
diff --git a/include/dolphin/os/OSFont.h b/include/dolphin/os/OSFont.h
new file mode 100644
index 0000000..35ddced
--- /dev/null
+++ b/include/dolphin/os/OSFont.h
@@ -0,0 +1,56 @@
+#ifndef RVL_SDK_OS_FONT_H
+#define RVL_SDK_OS_FONT_H
+#include <types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Documentation from:
+ * https://www.gc-forever.com/yagcd/chap16.html#sec16.1.3
+ */
+
+typedef enum {
+ OS_FONT_ENCODE_ANSI,
+ OS_FONT_ENCODE_SJIS,
+ OS_FONT_ENCODE_2,
+ OS_FONT_ENCODE_UTF8,
+ OS_FONT_ENCODE_UTF16,
+ OS_FONT_ENCODE_UTF32,
+ OS_FONT_ENCODE_MAX
+} OSFontEncode;
+
+typedef struct OSFontData {
+ u16 type; // at 0x0
+ u16 firstChar; // at 0x2
+ u16 lastChar; // at 0x4
+ u16 invalidChar; // at 0x6
+ u16 ascent; // at 0x8
+ u16 descent; // at 0xA
+ u16 charWidth; // at 0xC
+ u16 lineFeed; // at 0xE
+ u16 cellWidth; // at 0x10
+ u16 cellHeight; // at 0x12
+ u32 texSize; // at 0x14
+ u16 texFmt; // at 0x18
+ u16 texNumCol; // at 0x1A
+ u16 texNumRow; // at 0x1C
+ u16 texWidth; // at 0x1E
+ u16 texHeight; // at 0x20
+ u16 charWidthTblOfs; // at 0x22
+ u32 fontSheetOfs; // at 0x24
+ u32 fontSheetSize; // at 0x28
+} OSFontData;
+
+u16 OSGetFontEncode(void);
+u16 OSSetFontEncode(u16);
+u32 OSLoadFont(OSFontData*, void*);
+const char* OSGetFontTexel(const char*, void*, s32, s32, u32*);
+BOOL OSInitFont(OSFontData*);
+const char* OSGetFontTexture(const char*, void**, u32*, u32*, u32*);
+const char* OSGetFontWidth(const char*, u32*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h
new file mode 100644
index 0000000..9e5d2aa
--- /dev/null
+++ b/include/dolphin/os/OSInterrupt.h
@@ -0,0 +1,115 @@
+#ifndef _DOLPHIN_OSINTERRUPT
+#define _DOLPHIN_OSINTERRUPT
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __OS_INTERRUPT_MEM_0 0
+#define __OS_INTERRUPT_MEM_1 1
+#define __OS_INTERRUPT_MEM_2 2
+#define __OS_INTERRUPT_MEM_3 3
+#define __OS_INTERRUPT_MEM_ADDRESS 4
+#define __OS_INTERRUPT_DSP_AI 5
+#define __OS_INTERRUPT_DSP_ARAM 6
+#define __OS_INTERRUPT_DSP_DSP 7
+#define __OS_INTERRUPT_AI_AI 8
+#define __OS_INTERRUPT_EXI_0_EXI 9
+#define __OS_INTERRUPT_EXI_0_TC 10
+#define __OS_INTERRUPT_EXI_0_EXT 11
+#define __OS_INTERRUPT_EXI_1_EXI 12
+#define __OS_INTERRUPT_EXI_1_TC 13
+#define __OS_INTERRUPT_EXI_1_EXT 14
+#define __OS_INTERRUPT_EXI_2_EXI 15
+#define __OS_INTERRUPT_EXI_2_TC 16
+#define __OS_INTERRUPT_PI_CP 17
+#define __OS_INTERRUPT_PI_PE_TOKEN 18
+#define __OS_INTERRUPT_PI_PE_FINISH 19
+#define __OS_INTERRUPT_PI_SI 20
+#define __OS_INTERRUPT_PI_DI 21
+#define __OS_INTERRUPT_PI_RSW 22
+#define __OS_INTERRUPT_PI_ERROR 23
+#define __OS_INTERRUPT_PI_VI 24
+#define __OS_INTERRUPT_PI_DEBUG 25
+#define __OS_INTERRUPT_PI_HSP 26
+#define __OS_INTERRUPT_MAX 32
+
+#define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt))
+
+#define OS_INTERRUPTMASK_MEM_0 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_0)
+#define OS_INTERRUPTMASK_MEM_1 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_1)
+#define OS_INTERRUPTMASK_MEM_2 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_2)
+#define OS_INTERRUPTMASK_MEM_3 OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_3)
+#define OS_INTERRUPTMASK_MEM_ADDRESS OS_INTERRUPTMASK(__OS_INTERRUPT_MEM_ADDRESS)
+#define OS_INTERRUPTMASK_MEM \
+ (OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | \
+ OS_INTERRUPTMASK_MEM_3 | OS_INTERRUPTMASK_MEM_ADDRESS)
+#define OS_INTERRUPTMASK_DSP_AI OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_AI)
+#define OS_INTERRUPTMASK_DSP_ARAM OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_ARAM)
+#define OS_INTERRUPTMASK_DSP_DSP OS_INTERRUPTMASK(__OS_INTERRUPT_DSP_DSP)
+#define OS_INTERRUPTMASK_DSP \
+ (OS_INTERRUPTMASK_DSP_AI | OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP)
+#define OS_INTERRUPTMASK_AI_AI OS_INTERRUPTMASK(__OS_INTERRUPT_AI_AI)
+#define OS_INTERRUPTMASK_AI (OS_INTERRUPTMASK_AI_AI)
+#define OS_INTERRUPTMASK_EXI_0_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXI)
+#define OS_INTERRUPTMASK_EXI_0_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_TC)
+#define OS_INTERRUPTMASK_EXI_0_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_0_EXT)
+#define OS_INTERRUPTMASK_EXI_0 \
+ (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT)
+#define OS_INTERRUPTMASK_EXI_1_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXI)
+#define OS_INTERRUPTMASK_EXI_1_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_TC)
+#define OS_INTERRUPTMASK_EXI_1_EXT OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_1_EXT)
+#define OS_INTERRUPTMASK_EXI_1 \
+ (OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT)
+#define OS_INTERRUPTMASK_EXI_2_EXI OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_EXI)
+#define OS_INTERRUPTMASK_EXI_2_TC OS_INTERRUPTMASK(__OS_INTERRUPT_EXI_2_TC)
+#define OS_INTERRUPTMASK_EXI_2 (OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC)
+#define OS_INTERRUPTMASK_EXI \
+ (OS_INTERRUPTMASK_EXI_0_EXI | OS_INTERRUPTMASK_EXI_0_TC | OS_INTERRUPTMASK_EXI_0_EXT | \
+ OS_INTERRUPTMASK_EXI_1_EXI | OS_INTERRUPTMASK_EXI_1_TC | OS_INTERRUPTMASK_EXI_1_EXT | \
+ OS_INTERRUPTMASK_EXI_2_EXI | OS_INTERRUPTMASK_EXI_2_TC)
+#define OS_INTERRUPTMASK_PI_PE_TOKEN OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_TOKEN)
+#define OS_INTERRUPTMASK_PI_PE_FINISH OS_INTERRUPTMASK(__OS_INTERRUPT_PI_PE_FINISH)
+#define OS_INTERRUPTMASK_PI_PE (OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH)
+#define OS_INTERRUPTMASK_PI_CP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_CP)
+#define OS_INTERRUPTMASK_PI_SI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_SI)
+#define OS_INTERRUPTMASK_PI_DI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DI)
+#define OS_INTERRUPTMASK_PI_RSW OS_INTERRUPTMASK(__OS_INTERRUPT_PI_RSW)
+#define OS_INTERRUPTMASK_PI_ERROR OS_INTERRUPTMASK(__OS_INTERRUPT_PI_ERROR)
+#define OS_INTERRUPTMASK_PI_VI OS_INTERRUPTMASK(__OS_INTERRUPT_PI_VI)
+#define OS_INTERRUPTMASK_PI_DEBUG OS_INTERRUPTMASK(__OS_INTERRUPT_PI_DEBUG)
+#define OS_INTERRUPTMASK_PI_HSP OS_INTERRUPTMASK(__OS_INTERRUPT_PI_HSP)
+#define OS_INTERRUPTMASK_PI \
+ (OS_INTERRUPTMASK_PI_CP | OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI | \
+ OS_INTERRUPTMASK_PI_RSW | OS_INTERRUPTMASK_PI_ERROR | OS_INTERRUPTMASK_PI_VI | \
+ OS_INTERRUPTMASK_PI_PE_TOKEN | OS_INTERRUPTMASK_PI_PE_FINISH | OS_INTERRUPTMASK_PI_DEBUG | \
+ OS_INTERRUPTMASK_PI_HSP)
+
+typedef s16 __OSInterrupt;
+typedef void (*__OSInterruptHandler)(__OSInterrupt interrupt, OSContext* context);
+
+typedef u32 OSInterruptMask;
+
+extern volatile __OSInterrupt __OSLastInterrupt;
+extern volatile u32 __OSLastInterruptSrr0;
+extern volatile OSTime __OSLastInterruptTime;
+
+__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler);
+
+__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt);
+
+void __OSDispatchInterrupt(__OSException exception, OSContext* context);
+
+OSInterruptMask OSGetInterruptMask(void);
+OSInterruptMask OSSetInterruptMask(OSInterruptMask mask);
+OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask);
+OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSINTERRUPT
diff --git a/include/dolphin/os/OSMemory.h b/include/dolphin/os/OSMemory.h
new file mode 100644
index 0000000..00c6ab0
--- /dev/null
+++ b/include/dolphin/os/OSMemory.h
@@ -0,0 +1,26 @@
+#ifndef _DOLPHIN_OSMEMORY
+#define _DOLPHIN_OSMEMORY
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_PROTECT_CHAN0 0
+#define OS_PROTECT_CHAN1 1
+#define OS_PROTECT_CHAN2 2
+#define OS_PROTECT_CHAN3 3
+
+#define OS_PROTECT_CONTROL_NONE 0x00
+#define OS_PROTECT_CONTROL_READ 0x01
+#define OS_PROTECT_CONTROL_WRITE 0x02
+#define OS_PROTECT_CONTROL_RDWR (OS_PROTECT_CONTROL_READ | OS_PROTECT_CONTROL_WRITE)
+
+void OSProtectRange(u32 chan, void* addr, u32 nBytes, u32 control);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMEMORY
diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h
new file mode 100644
index 0000000..f67a84e
--- /dev/null
+++ b/include/dolphin/os/OSMessage.h
@@ -0,0 +1,34 @@
+#ifndef _DOLPHIN_OSMESSAGE
+#define _DOLPHIN_OSMESSAGE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dolphin/os/OSThread.h>
+typedef struct OSMessageQueue OSMessageQueue;
+typedef void* OSMessage;
+
+struct OSMessageQueue {
+ OSThreadQueue queueSend;
+ OSThreadQueue queueReceive;
+ OSMessage* msgArray;
+ s32 msgCount;
+ s32 firstIndex;
+ s32 usedCount;
+};
+
+// Flags to turn blocking on/off when sending/receiving message
+#define OS_MESSAGE_NOBLOCK 0
+#define OS_MESSAGE_BLOCK 1
+
+void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount);
+BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags);
+BOOL OSJamMessage(OSMessageQueue* mq, OSMessage msg, s32 flags);
+BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMESSAGE
diff --git a/include/dolphin/os/OSModule.h b/include/dolphin/os/OSModule.h
new file mode 100644
index 0000000..7baf2a9
--- /dev/null
+++ b/include/dolphin/os/OSModule.h
@@ -0,0 +1,115 @@
+#ifndef _DOLPHIN_OSMODULE
+#define _DOLPHIN_OSMODULE
+
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_MODULE_VERSION 2
+typedef struct OSModuleHeader OSModuleHeader;
+
+typedef u32 OSModuleID;
+typedef struct OSModuleQueue OSModuleQueue;
+typedef struct OSModuleLink OSModuleLink;
+typedef struct OSModuleInfo OSModuleInfo;
+typedef struct OSSectionInfo OSSectionInfo;
+typedef struct OSImportInfo OSImportInfo;
+typedef struct OSRel OSRel;
+
+struct OSModuleQueue {
+ OSModuleInfo* head;
+ OSModuleInfo* tail;
+};
+
+struct OSModuleLink {
+ OSModuleInfo* next;
+ OSModuleInfo* prev;
+};
+
+struct OSModuleInfo {
+ OSModuleID id; // unique identifier for the module
+ OSModuleLink link; // doubly linked list of modules
+ u32 numSections; // # of sections
+ u32 sectionInfoOffset; // offset to section info table
+ u32 nameOffset; // offset to module name
+ u32 nameSize; // size of module name
+ u32 version; // version number
+};
+
+struct OSModuleHeader {
+ // CAUTION: info must be the 1st member
+ OSModuleInfo info;
+
+ // OS_MODULE_VERSION == 1
+ u32 bssSize; // total size of bss sections in bytes
+ u32 relOffset;
+ u32 impOffset;
+ u32 impSize; // size in bytes
+ u8 prologSection; // section # for prolog function
+ u8 epilogSection; // section # for epilog function
+ u8 unresolvedSection; // section # for unresolved function
+ u8 bssSection; // section # for bss section (set at run-time)
+ u32 prolog; // prolog function offset
+ u32 epilog; // epilog function offset
+ u32 unresolved; // unresolved function offset
+
+ // OS_MODULE_VERSION == 2
+#if (2 <= OS_MODULE_VERSION)
+ u32 align; // module alignment constraint
+ u32 bssAlign; // bss alignment constraint
+#endif
+
+ // OS_MODULE_VERSION == 3
+#if (3 <= OS_MODULE_VERSION)
+ u32 fixSize;
+#endif
+};
+
+#define OSGetSectionInfo(module) ((OSSectionInfo*)(((OSModuleInfo*)(module))->sectionInfoOffset))
+
+struct OSSectionInfo {
+ u32 offset;
+ u32 size;
+};
+
+// OSSectionInfo.offset bit
+#define OS_SECTIONINFO_EXEC 0x1
+#define OS_SECTIONINFO_OFFSET(offset) ((offset) & ~0x1)
+
+struct OSImportInfo {
+ OSModuleID id; // external module id
+ u32 offset; // offset to OSRel instructions
+};
+
+struct OSRel {
+ u16 offset; // byte offset from the previous entry
+ u8 type;
+ u8 section;
+ u32 addend;
+};
+
+#define R_DOLPHIN_NOP 201 // C9h current offset += OSRel.offset
+#define R_DOLPHIN_SECTION 202 // CAh current section = OSRel.section
+#define R_DOLPHIN_END 203 // CBh
+#define R_DOLPHIN_MRKREF 204 // CCh
+
+void OSSetStringTable(const void* stringTable);
+BOOL OSLink(OSModuleInfo* newModule, void* bss);
+#if (3 <= OS_MODULE_VERSION)
+BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss);
+#endif
+BOOL OSUnlink(OSModuleInfo* oldModule);
+
+OSModuleInfo* OSSearchModule(void* ptr, u32* section, u32* offset);
+
+// debugger notification
+void OSNotifyLink(OSModuleInfo* module);
+void OSNotifyUnlink(OSModuleInfo* module);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMODULE
diff --git a/include/dolphin/os/OSMutex.h b/include/dolphin/os/OSMutex.h
new file mode 100644
index 0000000..9ee6ffe
--- /dev/null
+++ b/include/dolphin/os/OSMutex.h
@@ -0,0 +1,35 @@
+#ifndef _DOLPHIN_OSMUTEX
+#define _DOLPHIN_OSMUTEX
+
+#include "types.h"
+
+#include "dolphin/os/OSThread.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct OSMutex {
+ OSThreadQueue queue;
+ OSThread* thread; // the current owner
+ s32 count; // lock count
+ OSMutexLink link; // for OSThread.queueMutex
+};
+
+struct OSCond {
+ OSThreadQueue queue;
+};
+
+void OSInitMutex(OSMutex* mutex);
+void OSLockMutex(OSMutex* mutex);
+void OSUnlockMutex(OSMutex* mutex);
+BOOL OSTryLockMutex(OSMutex* mutex);
+void OSInitCond(OSCond* cond);
+void OSWaitCond(OSCond* cond, OSMutex* mutex);
+void OSSignalCond(OSCond* cond);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSMUTEX
diff --git a/include/dolphin/os/OSPriv.h b/include/dolphin/os/OSPriv.h
new file mode 100644
index 0000000..b3db327
--- /dev/null
+++ b/include/dolphin/os/OSPriv.h
@@ -0,0 +1,18 @@
+#ifndef _DOLPHIN_OSPRIV
+#define _DOLPHIN_OSPRIV
+
+#include "dolphin/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__OSExceptionHandler __OSGetExceptionHandler(__OSException exception);
+OSTime __OSGetSystemTime();
+OSTime __OSTimeToSystemTime(OSTime);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#endif // _DOLPHIN_OSPRIV
diff --git a/include/dolphin/os/OSReboot.h b/include/dolphin/os/OSReboot.h
new file mode 100644
index 0000000..837de88
--- /dev/null
+++ b/include/dolphin/os/OSReboot.h
@@ -0,0 +1,10 @@
+#ifndef DOLPHIN_OS_OSREBOOT_H
+#define DOLPHIN_OS_OSREBOOT_H
+typedef void (*Event)(void);
+
+void __OSReboot(u32 resetCode, BOOL forceMenu);
+
+void Run(Event);
+//void __OSReboot(u32 resetCode, BOOL forceMenu);
+
+#endif
diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h
new file mode 100644
index 0000000..6c1e33b
--- /dev/null
+++ b/include/dolphin/os/OSReset.h
@@ -0,0 +1,48 @@
+#ifndef _DOLPHIN_OSRESET
+#define _DOLPHIN_OSRESET
+
+#include <types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_RESETCODE_RESTART 0x80000000
+#define OS_RESETCODE_SYSTEM 0x40000000
+
+#define OS_RESETCODE_EXEC 0xC0000000
+#define OS_RESETCODE_NETCONFIG 0xC0010000
+
+#define OS_RESET_TIMEOUT OSMillisecondsToTicks(1000)
+
+#define OS_RESET_RESTART 0
+#define OS_RESET_HOTRESET 1
+#define OS_RESET_SHUTDOWN 2
+
+#define OS_RESET_PRIO_SO 110
+#define OS_RESET_PRIO_IP 111
+#define OS_RESET_PRIO_CARD 127
+#define OS_RESET_PRIO_PAD 127
+#define OS_RESET_PRIO_GX 127
+#define OS_RESET_PRIO_ALARM 4294967295
+
+typedef BOOL (*OSResetFunction)(BOOL final);
+typedef struct OSResetFunctionInfo OSResetFunctionInfo;
+
+struct OSResetFunctionInfo {
+ // public
+ OSResetFunction func;
+ u32 priority;
+
+ // private
+ OSResetFunctionInfo* next;
+ OSResetFunctionInfo* prev;
+};
+
+void __OSDoHotReset(s32 arg0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSRESET
diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h
new file mode 100644
index 0000000..5551f68
--- /dev/null
+++ b/include/dolphin/os/OSResetSW.h
@@ -0,0 +1,22 @@
+#ifndef _DOLPHIN_OSRESETSW
+#define _DOLPHIN_OSRESETSW
+
+#include <dolphin/os/OSContext.h>
+#include <dolphin/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*OSResetCallback)(void);
+
+BOOL OSGetResetButtonState(void);
+
+BOOL OSGetResetSwitchState(void);
+OSResetCallback OSSetResetCallback(OSResetCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSRESETSW
diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h
new file mode 100644
index 0000000..f0a6a4d
--- /dev/null
+++ b/include/dolphin/os/OSSerial.h
@@ -0,0 +1,69 @@
+#ifndef _DOLPHIN_OSSERIAL
+#define _DOLPHIN_OSSERIAL
+
+#include <types.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)
+
+u32 SIProbe(s32 chan);
+char* SIGetTypeString(u32 type);
+void SIRefreshSamplingRate(void);
+void SISetSamplingRate(u32 msec);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _DOLPHIN_OSSERIAL
diff --git a/include/dolphin/os/OSThread.h b/include/dolphin/os/OSThread.h
new file mode 100644
index 0000000..7464e68
--- /dev/null
+++ b/include/dolphin/os/OSThread.h
@@ -0,0 +1,113 @@
+#ifndef _DOLPHIN_OSTHREAD
+#define _DOLPHIN_OSTHREAD
+
+#include <dolphin/os/OSContext.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define OS_THREAD_SPECIFIC_MAX 2
+
+typedef struct OSThread OSThread;
+typedef struct OSThreadQueue OSThreadQueue;
+typedef struct OSThreadLink OSThreadLink;
+typedef s32 OSPriority; // 0 highest, 31 lowest
+
+typedef struct OSMutex OSMutex;
+typedef struct OSMutexQueue OSMutexQueue;
+typedef struct OSMutexLink OSMutexLink;
+typedef struct OSCond OSCond;
+
+typedef void (*OSIdleFunction)(void* param);
+typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to);
+
+struct OSThreadQueue {
+ OSThread* head;
+ OSThread* tail;
+};
+
+struct OSThreadLink {
+ OSThread* next;
+ OSThread* prev;
+};
+
+struct OSMutexQueue {
+ OSMutex* head;
+ OSMutex* tail;
+};
+
+struct OSMutexLink {
+ OSMutex* next;
+ OSMutex* prev;
+};
+
+struct OSThread {
+ OSContext context;
+ u16 state;
+ u16 attr;
+ s32 suspend;
+ OSPriority priority;
+ OSPriority base;
+ void* val;
+ OSThreadQueue* queue;
+ OSThreadLink link;
+ OSThreadQueue queueJoin;
+ OSMutex* mutex;
+ OSMutexQueue queueMutex;
+ OSThreadLink linkActive;
+ u8* stackBase;
+ u32* stackEnd;
+ s32 error;
+ void* specific[OS_THREAD_SPECIFIC_MAX];
+};
+
+enum OS_THREAD_STATE {
+ OS_THREAD_STATE_READY = 1,
+ OS_THREAD_STATE_RUNNING = 2,
+ OS_THREAD_STATE_WAITING = 4,
+ OS_THREAD_STATE_MORIBUND = 8
+};
+
+#define OS_THREAD_ATTR_DETACH 0x0001u
+
+#define OS_THREAD_STACK_MAGIC 0xDEADBABE
+
+#define OS_PRIORITY_MIN 0 // highest
+#define OS_PRIORITY_MAX 31 // lowest
+#define OS_PRIORITY_IDLE OS_PRIORITY_MAX
+
+
+void OSInitThreadQueue(OSThreadQueue* queue);
+OSThread* OSGetCurrentThread(void);
+BOOL OSIsThreadSuspended(OSThread* thread);
+BOOL OSIsThreadTerminated(OSThread* thread);
+s32 OSDisableScheduler(void);
+s32 OSEnableScheduler(void);
+void OSYieldThread(void);
+BOOL OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize,
+ OSPriority priority, u16 attr);
+void OSExitThread(void* val);
+void OSCancelThread(OSThread* thread);
+BOOL OSJoinThread(OSThread* thread, void** val);
+void OSDetachThread(OSThread* thread);
+s32 OSResumeThread(OSThread* thread);
+s32 OSSuspendThread(OSThread* thread);
+BOOL OSSetThreadPriority(OSThread* thread, OSPriority priority);
+OSPriority OSGetThreadPriority(OSThread* thread);
+void OSSleepThread(OSThreadQueue* queue);
+void OSWakeupThread(OSThreadQueue* queue);
+
+void* OSGetThreadSpecific(s32 index);
+void OSSetThreadSpecific(s32 index, void* ptr);
+
+OSThread* OSSetIdleFunction(OSIdleFunction idleFunction, void* param, void* stack, u32 stackSize);
+OSThread* OSGetIdleFunction(void);
+void OSClearStack(u8 val);
+long OSCheckActiveThreads(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DOLPHIN_OSTHREAD