diff --git a/Makefile b/Makefile index 58afde4..956f66d 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,9 @@ include obj_files.mk MWCC_VERSION := GC/1.1 +# revision build year, 2002 for MQ, 2003 for CE +DOLPHIN_REVISION := 2003 + # Programs ifeq ($(WINDOWS),1) WINE := @@ -51,6 +54,9 @@ MWCC_DIR := tools/mwcc_compiler/$(MWCC_VERSION) CC := $(WINE) $(MWCC_DIR)/mwcceppc.exe LD := $(WINE) $(MWCC_DIR)/mwldeppc.exe +DOLPHIN_MWCC_DIR := tools/mwcc_compiler/GC/1.2.5n +DOLPHIN_CC := $(WINE) $(DOLPHIN_MWCC_DIR)/mwcceppc.exe + SHA1SUM := sha1sum PYTHON := python3 ELF2DOL := tools/elf2dol/elf2dol @@ -61,20 +67,24 @@ ASM_PROCESSOR := $(ASM_PROCESSOR_DIR)/compile.sh POSTPROC := tools/postprocess.py # Options -INCLUDES := -Iinclude +INCLUDES := -Iinclude -Ilibc # Assembler Flags -ASFLAGS := -mgekko -I include +ASFLAGS := -mgekko -I include -I libc # Linker Flags -LDFLAGS := -map $(MAP) -fp hard -nodefaults -w off +LDFLAGS := -map $(MAP) -fp hardware -nodefaults -warn off # Compiler Flags -CFLAGS := -Cpp_exceptions off -proc gekko -fp hard -fp_contract on -enum int -O4,p -inline auto,deferred -sym on -nodefaults -msgstyle gcc $(INCLUDES) +CFLAGS := -Cpp_exceptions off -proc gekko -fp hardware -fp_contract on -enum int -O4,p -sym on -nodefaults -msgstyle gcc $(INCLUDES) -DDOLPHIN_REV=$(DOLPHIN_REVISION) + ifneq ($(NON_MATCHING),0) CFLAGS += -DNON_MATCHING endif +DOLPHIN_CFLAGS := $(CFLAGS) -align powerpc -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte -inline auto +EMULATOR_CFLAGS := $(CFLAGS) -inline auto,deferred + # elf2dol needs to know these in order to calculate sbss correctly. SDATA_PDHR := 9 SBSS_PDHR := 10 @@ -136,8 +146,8 @@ $(DOL): $(ELF) $(BUILD_DIR)/%.o: %.s $(AS) $(ASFLAGS) -o $@ $< -$(BUILD_DIR)/%.o: %.c - $(ASM_PROCESSOR) "$(CC) $(CFLAGS)" "$(AS) $(ASFLAGS)" $@ $< +$(BUILD_DIR)/src/dolphin/%.o: src/dolphin/%.c + $(ASM_PROCESSOR) "$(DOLPHIN_CC) $(DOLPHIN_CFLAGS)" "$(AS) $(ASFLAGS)" $@ $< -$(BUILD_DIR)/%.o: %.cpp - $(CC) $(CFLAGS) -c -o $@ $< +$(BUILD_DIR)/src/emulator/%.o: src/emulator/%.c + $(ASM_PROCESSOR) "$(CC) $(EMULATOR_CFLAGS)" "$(AS) $(ASFLAGS)" $@ $< diff --git a/include/__ppc_eabi_linker.h b/include/__ppc_eabi_linker.h new file mode 100644 index 0000000..dcbd3fa --- /dev/null +++ b/include/__ppc_eabi_linker.h @@ -0,0 +1,72 @@ +#ifndef __PPC_EABI_LINKER +#define __PPC_EABI_LINKER + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _stack_end[]; +__declspec(section ".init") extern char _heap_addr[]; +__declspec(section ".init") extern char _heap_end[]; +__declspec(section ".init") extern const char _fextabindex_rom[]; +__declspec(section ".init") extern char _fextabindex[]; +__declspec(section ".init") extern char _eextabindex[]; + +__declspec(section ".init") extern char _SDA_BASE_[]; + +__declspec(section ".init") extern char _SDA2_BASE_[]; + +typedef struct __rom_copy_info { + char* rom; + char* addr; + unsigned int size; +} __rom_copy_info; + +__declspec(section ".init") extern __rom_copy_info _rom_copy_info[]; + +typedef struct __bss_init_info { + char* addr; + unsigned int size; +} __bss_init_info; + +__declspec(section ".init") extern __bss_init_info _bss_init_info[]; + +typedef struct __eti_init_info { + void* eti_start; + void* eti_end; + void* code_start; + unsigned long code_size; +} __eti_init_info; + +__declspec(section ".init") extern __eti_init_info _eti_init_info[]; +__declspec(section ".init") extern const char _f_init_rom[]; +__declspec(section ".init") extern char _f_init[]; +__declspec(section ".init") extern char _e_init[]; +__declspec(section ".init") extern const char _f_text_rom[]; +__declspec(section ".init") extern char _f_text[]; +__declspec(section ".init") extern char _e_text[]; +__declspec(section ".init") extern const char _f_rodata_rom[]; +__declspec(section ".init") extern char _f_rodata[]; +__declspec(section ".init") extern char _e_rodata[]; +__declspec(section ".init") extern const char _fextab_rom[]; +__declspec(section ".init") extern char _fextab[]; +__declspec(section ".init") extern char _eextab[]; +__declspec(section ".init") extern const char _f_data_rom[]; +__declspec(section ".init") extern char _f_data[]; +__declspec(section ".init") extern char _e_data[]; +__declspec(section ".init") extern char _f_bss[]; +__declspec(section ".init") extern char _e_bss[]; +__declspec(section ".init") extern const char _f_sdata_rom[]; +__declspec(section ".init") extern char _f_sdata[]; +__declspec(section ".init") extern char _e_sdata[]; +__declspec(section ".init") extern char _f_sbss[]; +__declspec(section ".init") extern char _e_sbss[]; +__declspec(section ".init") extern const char _f_sdata2_rom[]; +__declspec(section ".init") extern char _f_sdata2[]; +__declspec(section ".init") extern char _e_sdata2[]; +__declspec(section ".init") extern char _f_sbss2[]; +__declspec(section ".init") extern char _e_sbss2[]; +__declspec(section ".init") extern const char _f_PPC_EMB_sdata0_rom[]; +__declspec(section ".init") extern char _f_PPC_EMB_sdata0[]; +__declspec(section ".init") extern char _e_PPC_EMB_sdata0[]; +__declspec(section ".init") extern char _f_PPC_EMB_sbss0[]; +__declspec(section ".init") extern char _e_PPC_EMB_sbss0[]; + +#endif // __PPC_EABI_LINKER diff --git a/include/dolphin/DVDPriv.h b/include/dolphin/DVDPriv.h new file mode 100644 index 0000000..c3e58dd --- /dev/null +++ b/include/dolphin/DVDPriv.h @@ -0,0 +1,50 @@ +#ifndef _DOLPHIN_DVDPRIV +#define _DOLPHIN_DVDPRIV + +#include "dolphin/dvd.h" +#include "dolphin/hw_regs.h" +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DVDDriveInfo { + u16 revisionLevel; + u16 deviceCode; + u32 releaseDate; + u8 padding[24]; +} DVDDriveInfo; + +typedef struct DVDBB1 { + u32 appLoaderLength; + void* appLoaderFunc1; + void* appLoaderFunc2; + void* appLoaderFunc3; +} DVDBB1; + +typedef struct DVDBB2 { + u32 bootFilePosition; + u32 FSTPosition; + u32 FSTLength; + u32 FSTMaxLength; + void* FSTAddress; + u32 userPosition; + u32 userLength; + + u32 padding0; +} DVDBB2; + +typedef void (*DVDOptionalCommandChecker)(DVDCommandBlock* block, void (*cb)(u32 intType)); +typedef void (*DVDLowCallback)(u32 intType); +extern DVDDiskID* DVDGetCurrentDiskID(); +DVDLowCallback DVDLowClearCallback(); +BOOL DVDLowSeek(u32 offset, DVDLowCallback callback); +void __DVDLowSetWAType(u32 type, u32 location); +DVDCommandBlock* __DVDPopWaitingQueue(); + +#ifdef __cplusplus +} +#endif // _DOLPHIN_DVDPRIV + +#endif __DVDPRIV_H__ diff --git a/include/dolphin/OSRtcPriv.h b/include/dolphin/OSRtcPriv.h new file mode 100644 index 0000000..aa5ca62 --- /dev/null +++ b/include/dolphin/OSRtcPriv.h @@ -0,0 +1,34 @@ +#ifndef _DOLPHIN_OSRTCPRIV +#define _DOLPHIN_OSRTCPRIV + +#include "dolphin/types.h" + +typedef struct OSSram { + u16 checkSum; + u16 checkSumInv; + u32 ead0; + u32 ead1; + u32 counterBias; + s8 displayOffsetH; + u8 ntd; + u8 language; + u8 flags; +} OSSram; + +typedef struct OSSramEx { + u8 flashID[2][12]; + u32 wirelessKeyboardID; + u16 wirelessPadID[4]; + u8 dvdErrorCode; + u8 _padding0; + u8 flashIDCheckSum[2]; + u16 gbs; + u8 _padding1[2]; +} OSSramEx; + +OSSram* __OSLockSram(); +OSSramEx* __OSLockSramEx(); +void OSSetWirelessID(s32 chan, u16 id); +u16 OSGetWirelessID(s32 chan); + +#endif // _DOLPHIN_OSRTCPRIV diff --git a/include/dolphin/__ppc_eabi_init.h b/include/dolphin/__ppc_eabi_init.h new file mode 100644 index 0000000..3b178fd --- /dev/null +++ b/include/dolphin/__ppc_eabi_init.h @@ -0,0 +1,22 @@ +#ifndef _DOLPHIN__PPC_EABI_INIT +#define _DOLPHIN__PPC_EABI_INIT + +#include "dolphin/types.h" +#include "macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +INIT void __init_hardware(void); +INIT void __flush_cache(register void* address, register unsigned int size); + +void __init_user(void); +void __init_cpp(void); +extern void __OSFPRInit(void); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN__PPC_EABI_INIT diff --git a/include/dolphin/__start.h b/include/dolphin/__start.h new file mode 100644 index 0000000..3c02522 --- /dev/null +++ b/include/dolphin/__start.h @@ -0,0 +1,43 @@ +#ifndef _DOLPHIN__START +#define _DOLPHIN__START + +#include "dolphin/db.h" +#include "dolphin/types.h" + +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_RESET_RESTART 0 +#define EXCEPTIONMASK_ADDR 0x80000044 +#define BOOTINFO2_ADDR 0x800000F4 +#define OS_BI2_DEBUGFLAG_OFFSET 0xC +#define ARENAHI_ADDR 0x80000034 +#define DEBUGFLAG_ADDR 0x800030E8 +#define DVD_DEVICECODE_ADDR 0x800030E6 + +#define MSR_FP 0x2000 + +extern void InitMetroTRK(); + +u16 Pad3Button : PAD3_BUTTON_ADDR; +static u8 Debug_BBA = 0; + +extern void memset(void*, int, int); +extern int main(int argc, char* argv[]); +extern void exit(int); +extern void __init_user(void); +extern void InitMetroTRK_BBA(); +extern void OSInit(void); +extern void DBInit(void); +extern void OSResetSystem(BOOL reset, u32 resetCode, BOOL forceMenu); +extern void __OSCacheInit(void); +extern void __OSPSInit(void); + +__declspec(section ".init") extern void __check_pad3(void); +__declspec(section ".init") extern void __start(void); +__declspec(section ".init") extern void __init_registers(void); +__declspec(section ".init") extern void __init_data(void); + +__declspec(section ".init") extern char _stack_addr[]; +__declspec(section ".init") extern char _SDA_BASE_[]; +__declspec(section ".init") extern char _SDA2_BASE_[]; + +#endif // _DOLPHIN__START diff --git a/include/dolphin/base/PPCArch.h b/include/dolphin/base/PPCArch.h index 3d9b385..2a76431 100644 --- a/include/dolphin/base/PPCArch.h +++ b/include/dolphin/base/PPCArch.h @@ -1,48 +1,492 @@ -#ifndef _DOLPHIN_BASE_PPCARCH_H_ -#define _DOLPHIN_BASE_PPCARCH_H_ +#ifndef _DOLPHIN_BASE_PPCARCH_H +#define _DOLPHIN_BASE_PPCARCH_H #include "dolphin/types.h" -// GEKKO registers -#define GQR0 0x390 -#define GQR1 0x391 -#define GQR2 0x392 -#define GQR3 0x393 -#define GQR4 0x394 -#define GQR5 0x395 -#define GQR6 0x396 -#define GQR7 0x397 +#ifdef __cplusplus +extern "C" { +#endif -u32 PPCMfmsr(void); -void PPCMtmsr(u32 newMsr); +#define CTR 9 +#define XER 1 +#define LR 8 -u32 PPCMfhid0(void); -void PPCMthid0(u32 newHid0); +#define UPMC1 937 +#define UPMC2 938 +#define UPMC3 941 +#define UPMC4 942 -u32 PPCMfl2cr(void); +#define USIA 939 + +#define UMMCR0 936 +#define UMMCR1 940 + +#define HID0 1008 +#define HID1 1009 + +#define PVR 287 + +#define IBAT0U 528 +#define IBAT0L 529 +#define IBAT1U 530 +#define IBAT1L 531 +#define IBAT2U 532 +#define IBAT2L 533 +#define IBAT3U 534 +#define IBAT3L 535 + +#define DBAT0U 536 +#define DBAT0L 537 +#define DBAT1U 538 +#define DBAT1L 539 +#define DBAT2U 540 +#define DBAT2L 541 +#define DBAT3U 542 +#define DBAT3L 543 + +#define SDR1 25 + +#define SPRG0 272 +#define SPRG1 273 +#define SPRG2 274 +#define SPRG3 275 + +#define DAR 19 +#define DSISR 18 + +#define SRR0 26 +#define SRR1 27 + +#define EAR 282 + +#define DABR 1013 + +#define TBL 284 +#define TBU 285 + +#define L2CR 1017 + +#define DEC 22 + +#define IABR 1010 + +#define PMC1 953 +#define PMC2 954 +#define PMC3 957 +#define PMC4 958 + +#define SIA 955 + +#define MMCR0 952 +#define MMCR1 956 + +#define THRM1 1020 +#define THRM2 1021 +#define THRM3 1022 + +#define ICTC 1019 + +#define GQR0 912 +#define GQR1 913 +#define GQR2 914 +#define GQR3 915 +#define GQR4 916 +#define GQR5 917 +#define GQR6 918 +#define GQR7 919 + +#define HID2 920 + +#define WPAR 921 + +#define DMA_U 922 +#define DMA_L 923 + +#define MSR_POW 0x00040000 // Power Management +#define MSR_ILE 0x00010000 // Interrupt Little Endian +#define MSR_EE 0x00008000 // external interrupt +#define MSR_PR 0x00004000 // privilege level(should be 0) +#define MSR_FP 0x00002000 // floating point available +#define MSR_ME 0x00001000 // machine check enable +#define MSR_FE0 0x00000800 // floating point exception enable +#define MSR_SE 0x00000400 // single step trace enable +#define MSR_BE 0x00000200 // branch trace enable +#define MSR_FE1 0x00000100 // floating point exception enable +#define MSR_IP 0x00000040 // Exception prefix +#define MSR_IR 0x00000020 // instruction relocate +#define MSR_DR 0x00000010 // data relocate +#define MSR_PM 0x00000004 // Performance monitor marked mode +#define MSR_RI 0x00000002 // Recoverable interrupt +#define MSR_LE 0x00000001 // Little Endian + +#define MSR_POW_BIT 13 // Power Management +#define MSR_ILE_BIT 15 // Interrupt Little Endian +#define MSR_EE_BIT 16 // external interrupt +#define MSR_PR_BIT 17 // privilege level (should be 0) +#define MSR_FP_BIT 18 // floating point available +#define MSR_ME_BIT 19 // machine check enable +#define MSR_FE0_BIT 20 // floating point exception enable +#define MSR_SE_BIT 21 // single step trace enable +#define MSR_BE_BIT 22 // branch trace enable +#define MSR_FE1_BIT 23 // floating point exception enable +#define MSR_IP_BIT 25 // Exception prefix +#define MSR_IR_BIT 26 // instruction relocate +#define MSR_DR_BIT 27 // data relocate +#define MSR_PM_BIT 29 // Performance monitor marked mode +#define MSR_RI_BIT 30 // Recoverable interrupt +#define MSR_LE_BIT 31 // Little Endian + +/*---------------------------------------------------------------------------* + HID0 bits + *---------------------------------------------------------------------------*/ +#define HID0_EMCP 0x80000000 // Enable MCP +#define HID0_DBP 0x40000000 // Enable 60x bus address and data parity chk +#define HID0_EBA 0x20000000 // Enable 60x address parity checking +#define HID0_EBD 0x10000000 // Enable 60x data parity checking +#define HID0_BCLK 0x08000000 // CLK_OUT output enable and clk selection +#define HID0_ECLK 0x02000000 // CLK_OUT output enable and clk selection +#define HID0_PAR 0x01000000 // Disable !ARTRY precharge +#define HID0_DOZE 0x00800000 // Doze mode enable +#define HID0_NAP 0x00400000 // Nap mode enable +#define HID0_SLEEP 0x00200000 // Sleep mode enable +#define HID0_DPM 0x00100000 // Dynamic power management enable +#define HID0_NHR 0x00010000 // Not hard reset (0 hard reset if s/w set it) +#define HID0_ICE 0x00008000 // Instruction cache enable +#define HID0_DCE 0x00004000 // Data cache enable +#define HID0_ILOCK 0x00002000 // ICache lock +#define HID0_DLOCK 0x00001000 // DCache lock +#define HID0_ICFI 0x00000800 // ICache flash invalidate +#define HID0_DCFI 0x00000400 // DCache flash invalidate +#define HID0_SPD 0x00000200 // Speculative cache access enable (0 enable) +#define HID0_IFEM 0x00000100 // Enable M bit on bus for Ifetch +#define HID0_SGE 0x00000080 // Store gathering enable +#define HID0_DCFA 0x00000040 // DCache flush assist - set before a flush +#define HID0_BTIC 0x00000020 // Branch target icache enable +#define HID0_ABE 0x00000008 // Address bcast enable +#define HID0_BHT 0x00000004 // Branch history table enable +#define HID0_NOOPTI 0x00000001 // No-op Dcache touch instructions + +#define HID0_ICE_BIT 16 // Instruction cache enable +#define HID0_DCE_BIT 17 // Data cache enable +#define HID0_ILOCK_BIT 18 // ICache lock +#define HID0_DLOCK_BIT 19 // DCache lock + +#define HID2_LSQE 0x80000000 // L/S quantize enable +#define HID2_WPE 0x40000000 // Write pipe enable +#define HID2_PSE 0x20000000 // Paired single enable +#define HID2_LCE 0x10000000 // Locked cache enable + +#define HID2_DCHERR 0x00800000 // ERROR: dcbz_l cache hit +#define HID2_DNCERR 0x00400000 // ERROR: DMA access to normal cache +#define HID2_DCMERR 0x00200000 // ERROR: DMA cache miss error +#define HID2_DQOERR 0x00100000 // ERROR: DMA queue overflow +#define HID2_DCHEE 0x00080000 // dcbz_l cache hit error enable +#define HID2_DNCEE 0x00040000 // DMA access to normal cache error enable +#define HID2_DCMEE 0x00020000 // DMA cache miss error error enable +#define HID2_DQOEE 0x00010000 // DMA queue overflow error enable + +#define HID2_DMAQL_MASK 0x0F000000 // DMA queue length mask +#define HID2_DMAQL_SHIFT 24 // DMA queue shift + +#define HID2_LSQE_BIT 0 +#define HID2_WPE_BIT 1 +#define HID2_PSE_BIT 2 +#define HID2_LCE_BIT 3 + +#define HID2_DCHERR_BIT 8 +#define HID2_DNCERR_BIT 9 +#define HID2_DCMERR_BIT 10 +#define HID2_DQOERR_BIT 11 +#define HID2_DCHEE_BIT 12 +#define HID2_DNCEE_BIT 13 +#define HID2_DCMEE_BIT 14 +#define HID2_DQOEE_BIT 15 + +#define GQR_LOAD_SCALE_MASK 0x3F000000 // load scale field +#define GQR_LOAD_TYPE_MASK 0x00070000 // load type field +#define GQR_STORE_SCALE_MASK 0x00003F00 // store scale field +#define GQR_STORE_TYPE_MASK 0x00000007 // store type field + +typedef struct { + u32 _pad0 : 2; + u32 loadScale : 6; + u32 _pad1 : 5; + u32 loadType : 3; + u32 _pad2 : 2; + u32 storeScale : 6; + u32 _pad3 : 5; + u32 storeType : 3; +} PPC_GQR_t; + +typedef union { + u32 val; + PPC_GQR_t f; +} PPC_GQR_u; + +#define DMA_U_ADDR_MASK 0xFFFFFFE0 // Start addr in memory +#define DMA_U_LEN_U_MASK 0x0000001F // lines to transfer (U) + +#define DMA_L_LC_ADDR_MASK 0xFFFFFFE0 // Start addr in LC +#define DMA_L_LOAD 0x00000010 // 0 - store, 1 - load +#define DMA_L_STORE 0x00000000 // 0 - store, 1 - load +#define DMA_L_LEN_MASK 0x0000000C // lines to transfer (L) +#define DMA_L_TRIGGER 0x00000002 // 0 - cmd inactive, 1 - cmd rdy +#define DMA_L_FLUSH 0x00000001 // 1 - Flush DMA queue + +typedef struct { + u32 memAddr : 27; + u32 dmaLenU : 5; +} PPC_DMA_U_t; + +typedef union { + u32 val; + PPC_DMA_U_t f; +} PPC_DMA_U_u; + +typedef struct { + u32 lcAddr : 27; + u32 dmaLd : 1; + u32 dmaLenL : 2; + u32 dmaTrigger : 1; + u32 dmaFlush : 1; +} PPC_DMA_L_t; + +typedef union { + u32 val; + PPC_DMA_L_t f; +} PPC_DMA_L_u; + +#define WPAR_ADDR 0xFFFFFFE0 // 32byte gather address +#define WPAR_BNE 0x00000001 // Buffer not empty (R) + +#define SRR1_DMA_BIT 0x00200000 +#define SRR1_L2DP_BIT 0x00100000 + +#define L2CR_L2E 0x80000000 // L2 Enable +#define L2CR_L2PE 0x40000000 // L2 data parity generation and checking enable + +#define L2CR_L2SIZ_256K 0x10000000 // L2 size 256K +#define L2CR_L2SIZ_512K 0x20000000 // L2 size 512 +#define L2CR_L2SIZ_1M 0x30000000 // L2 size 1M + +#define L2CR_L2CLK_1_0 0x02000000 // L2 clock ratio 1 +#define L2CR_L2CLK_1_5 0x04000000 // L2 clock ratio 1.5 +#define L2CR_L2CLK_2_0 0x08000000 // L2 clock ratio 2 +#define L2CR_L2CLK_2_5 0x0A000000 // L2 clock ratio 2.5 +#define L2CR_L2CLK_3_0 0x0C000000 // L2 clock ratio 3 + +#define L2CR_RAM_FLOW_THRU_BURST 0x00000000 // L2 RAM type flow-through sync. burst SRAM +#define L2CR_RAM_PIPELINE_BURST 0x01000000 // L2 RAM type pipelined sync. burst SRAM +#define L2CR_RAM_PIPELINE_LATE 0x01800000 // L2 RAM type pipelined sync. late-write SRAM + +#define L2CR_L2DO 0x00400000 // Data only +#define L2CR_L2I 0x00200000 // Global invalidate +#define L2CR_L2CTL 0x00100000 // ZZ enable +#define L2CR_L2WT 0x00080000 // L2 write through +#define L2CR_L2TS 0x00040000 // L2 test support + +#define L2CR_L2OH_0_5 0x00000000 // L2 output hold 0.5 ns +#define L2CR_L2OH_1_0 0x00010000 // L2 output hold 1.0 ns + +#define L2CR_L2SL 0x00008000 // L2 DLL slow +#define L2CR_L2DF 0x00004000 // L2 differential clock +#define L2CR_L2BYP 0x00002000 // L2 DLL bypass +#define L2CR_L2CS 0x00000200 // L2 clock stop +#define L2CR_L2DRO 0x00000100 // L2 DLL rollover checkstop enable +#define L2CR_L2CTR_MASK 0x000000FE // L2 counter value mask +#define L2CR_L2IP 0x00000001 // L2 global invalidate in progress + +#define MMCR0_DIS 0x80000000 // Disables counting unconditionally +#define MMCR0_DP 0x40000000 // Disables counting while in supervisor mode +#define MMCR0_DU 0x20000000 // Disables counting while in user mode +#define MMCR0_DMS 0x10000000 // Disables counting while MSR[PM] is set +#define MMCR0_DMR 0x08000000 // Disables counting while MSR[PM] is zero +#define MMCR0_ENINT 0x04000000 // Enables performance monitor interrupt signaling +#define MMCR0_DISCOUNT 0x02000000 // Disables counting of PMCn when a performance monitor interrupt is signaled or... +#define MMCR0_RTCSELECT_MASK 0x01800000 // 64-bit time base, bit selection enable +#define MMCR0_RTCSELECT_63 0x00000000 // Pick bit 63 to count +#define MMCR0_RTCSELECT_55 0x00800000 // Pick bit 55 to count +#define MMCR0_RTCSELECT_51 0x01000000 // Pick bit 51 to count +#define MMCR0_RTCSELECT_47 0x01800000 // Pick bit 47 to count +#define MMCR0_INTONBITTRANS 0x00400000 // Causes interrupt signaling on bit transition from off to on +#define MMCR0_THRESHOLD_MASK 0x003F0000 // Threshold value +#define MMCR0_THRESHOLD(n) ((n) << 16) // Threshold value (0 - 63) +#define MMCR0_PMC1INTCONTROL 0x00008000 // Enables interrupt signaling due to PMC1 counter overflow +#define MMCR0_PMC2INTCONTROL 0x00004000 // Enables interrupt signaling due to PMC2-PMC4 counter overflow +#define MMCR0_PMCTRIGGER 0x00002000 // Can be used to trigger counting of PMC2-PMC4 after PMC1 has overflowed or... +#define MMCR0_PMC1SELECT_MASK 0x00001FC0 // PMC1 input selector +#define MMCR0_PMC2SELECT_MASK 0x0000003F // PMC2 input selector + +#define MMCR1_PMC3SELECT_MASK 0xF8000000 // PMC3 input selector +#define MMCR1_PMC4SELECT_MASK 0x07C00000 // PMC4 input selector + +#define PMC1_OV 0x80000000 // Overflow +#define PMC1_COUNTER 0x7FFFFFFF // Counter value +#define PMC2_OV 0x80000000 // Overflow +#define PMC2_COUNTER 0x7FFFFFFF // Counter value +#define PMC3_OV 0x80000000 // Overflow +#define PMC3_COUNTER 0x7FFFFFFF // Counter value +#define PMC4_OV 0x80000000 // Overflow +#define PMC4_COUNTER 0x7FFFFFFF // Counter value + +/*---------------------------------------------------------------------------* + PMC1 Events + *---------------------------------------------------------------------------*/ +#define MMCR0_PMC1_HOLD 0x00000000 // Register holds current value +#define MMCR0_PMC1_CYCLE 0x00000040 // Processor cycles +#define MMCR0_PMC1_INSTRUCTION 0x00000080 // # of instructions completed. +#define MMCR0_PMC1_TRANSITION 0x000000C0 // # of transitions for 0 to 1 +#define MMCR0_PMC1_DISPATCHED 0x00000100 // # of instructions dispatched +#define MMCR0_PMC1_EIEIO 0x00000140 // # of eieio instructions completed +#define MMCR0_PMC1_ITLB_CYCLE 0x00000180 // # of cycles spent performing table search op. for the ITLB +#define MMCR0_PMC1_L2_HIT 0x000001C0 // # of access that hit the L2. +#define MMCR0_PMC1_EA 0x00000200 // # of valid instruction EAs delivered to the memory subsystem +#define MMCR0_PMC1_IABR 0x00000240 // # of time the address of an instruction matches the IABR +#define MMCR0_PMC1_L1_MISS 0x00000280 // # of loads that miss the L1 +#define MMCR0_PMC1_Bx_UNRESOLVED 0x000002C0 // # of branches that are unresolved when processed +#define MMCR0_PMC1_Bx_STALL_CYCLE \ + 0x00000300 // # of cycles that dispatcher stalls due to a second + // unresolved branch in the instruction stream +#define MMCR0_PMC1_IC_FETCH_MISS 0x00000340 // # of times an instruction fetch missed the L1 Icache +#define MMCR0_PMC2_HOLD 0x00000000 // Register holds current value +#define MMCR0_PMC2_CYCLE 0x00000001 // Processor cycles +#define MMCR0_PMC2_INSTRUCTION 0x00000002 // # of instructions completed +#define MMCR0_PMC2_TRANSITION 0x00000003 // # of time-base (lower) bit transitions +#define MMCR0_PMC2_DISPATCHED 0x00000004 // # of instructions dispatched +#define MMCR0_PMC2_IC_MISS 0x00000005 // # of L1 instruction cache misses +#define MMCR0_PMC2_ITLB_MISS 0x00000006 // # of ITLB misses +#define MMCR0_PMC2_L2_I_MISS 0x00000007 // # of L2 instruction misses +#define MMCR0_PMC2_Bx_FALL_TROUGH 0x00000008 // # of fall-through branches +#define MMCR0_PMC2_PR_SWITCH 0x00000009 // # of MSR[PR] bit toggles +#define MMCR0_PMC2_RESERVED_LOAD 0x0000000A // # of reserved loads completed +#define MMCR0_PMC2_LOAD_STORE 0x0000000B // # of completed loads and stores +#define MMCR0_PMC2_SNOOP 0x0000000C // # of snoops +#define MMCR0_PMC2_L1_CASTOUT 0x0000000D // # of L1 castouts to L2 +#define MMCR0_PMC2_SYSTEM 0x0000000E // # of completed system unit instructions +#define MMCR0_PMC2_IC_FETCH_MISS 0x0000000F // # of instruction fetch misses in the L1 +#define MMCR0_PMC2_Bx_OUT_OF_ORDER 0x00000010 // # of branches allowing out-of-order execution + +/*---------------------------------------------------------------------------* + PMC3 Events + *---------------------------------------------------------------------------*/ +#define MMCR1_PMC3_HOLD 0x00000000 // Register holds current value +#define MMCR1_PMC3_CYCLE 0x08000000 // Processor cycles +#define MMCR1_PMC3_INSTRUCTION 0x10000000 // # of instructions completed +#define MMCR1_PMC3_TRANSITION 0x18000000 // # of time-base (lower) bit transitions +#define MMCR1_PMC3_DISPATCHED 0x20000000 // # of instructions dispatched +#define MMCR1_PMC3_DC_MISS 0x28000000 // # of L1 data cache misses +#define MMCR1_PMC3_DTLB_MISS 0x30000000 // # of DTLB misses +#define MMCR1_PMC3_L2_D_MISS 0x38000000 // # of L2 data misses +#define MMCR1_PMC3_Bx_TAKEN 0x40000000 // # predicted branches that were taken +#define MMCR1_PMC3_PM_SWITCH 0x48000000 // # of transitions between marked and unmarked processes +#define MMCR1_PMC3_COND_STORE 0x50000000 // # of store conditional instructions completed +#define MMCR1_PMC3_FPU 0x58000000 // # of instructions completed from the FPU +#define MMCR1_PMC3_L2_SNOOP_CASTOUT 0x60000000 // # of L2 castout caused by snoops to modified lines +#define MMCR1_PMC3_L2_HIT 0x68000000 // # of cache operations that hit in the L2 cache +#define MMCR1_PMC3_L1_MISS_CYCLE 0x78000000 // # of cycles generated by L1 load misses +#define MMCR1_PMC3_Bx_SECOND \ + 0x80000000 // # of branches in the second speculative branch + // resolved correctly +#define MMCR1_PMC3_BPU_LR_CR \ + 0x88000000 // # of cycles the BPU stalls due to LR or CR unresolved + // dependencies + +#define MMCR1_PMC4_HOLD 0x00000000 // Register holds current value +#define MMCR1_PMC4_CYCLE 0x00400000 // Processor cycles +#define MMCR1_PMC4_INSTRUCTION 0x00800000 // # of instructions completed +#define MMCR1_PMC4_TRANSITION 0x00C00000 // # of time-base (lower) bit transitions +#define MMCR1_PMC4_DISPATCHED 0x01000000 // # of instructions dispatched +#define MMCR1_PMC4_L2_CASTOUT 0x01400000 // # of L2 castouts +#define MMCR1_PMC4_DTLB_CYCLE 0x01800000 // # of cycles spent performing table searches for DTLB accesses +#define MMCR1_PMC4_Bx_MISSED 0x02000000 // # of mispredicted branches +#define MMCR1_PMC4_COND_STORE_INT \ + 0x02800000 // # of store conditional instructions completed + // with reservation intact +#define MMCR1_PMC4_SYNC 0x02C00000 // # of completed sync instructions +#define MMCR1_PMC4_SNOOP_RETRY 0x03000000 // # of snoop request retries +#define MMCR1_PMC4_INTEGER 0x03400000 // # of completed integer operations +#define MMCR1_PMC4_BPU_THIRD \ + 0x03800000 // # of cycles the BPU cannot process new branches + // due to having two unresolved branches +#define MMCR1_PMC4_DC_MISS 0x07C00000 // # of L1 data cache misses + +/*---------------------------------------------------------------------------* + FPSCR bits + *---------------------------------------------------------------------------*/ +#ifndef FPSCR_FX +#define FPSCR_FX 0x80000000 // Exception summary +#define FPSCR_FEX 0x40000000 // Enabled exception summary +#define FPSCR_VX 0x20000000 // Invalid operation +#define FPSCR_OX 0x10000000 // Overflow exception +#define FPSCR_UX 0x08000000 // Underflow exception +#define FPSCR_ZX 0x04000000 // Zero divide exception +#define FPSCR_XX 0x02000000 // Inexact exception +#define FPSCR_VXSNAN 0x01000000 // SNaN +#define FPSCR_VXISI 0x00800000 // Infinity - Infinity +#define FPSCR_VXIDI 0x00400000 // Infinity / Infinity +#define FPSCR_VXZDZ 0x00200000 // 0 / 0 +#define FPSCR_VXIMZ 0x00100000 // Infinity * 0 +#define FPSCR_VXVC 0x00080000 // Invalid compare +#define FPSCR_FR 0x00040000 // Fraction rounded +#define FPSCR_FI 0x00020000 // Fraction inexact +#define FPSCR_VXSOFT 0x00000400 // Software request +#define FPSCR_VXSQRT 0x00000200 // Invalid square root +#define FPSCR_VXCVI 0x00000100 // Invalid integer convert +#define FPSCR_VE 0x00000080 // Invalid operation exception enable +#define FPSCR_OE 0x00000040 // Overflow exception enable +#define FPSCR_UE 0x00000020 // Underflow exception enable +#define FPSCR_ZE 0x00000010 // Zero divide exception enable +#define FPSCR_XE 0x00000008 // Inexact exception enable +#define FPSCR_NI 0x00000004 // Non-IEEE mode +#endif + +#ifndef FPSCR_FX_BIT +#define FPSCR_FX_BIT 0 // Exception summary +#define FPSCR_FEX_BIT 1 // Enabled exception summary +#define FPSCR_VX_BIT 2 // Invalid operation +#define FPSCR_OX_BIT 3 // Overflow exception +#define FPSCR_UX_BIT 4 // Underflow exception +#define FPSCR_ZX_BIT 5 // Zero divide exception +#define FPSCR_XX_BIT 6 // Inexact exception +#define FPSCR_VXSNAN_BIT 7 // SNaN +#define FPSCR_VXISI_BIT 8 // Infinity - Infinity +#define FPSCR_VXIDI_BIT 9 // Infinity / Infinity +#define FPSCR_VXZDZ_BIT 10 // 0 / 0 +#define FPSCR_VXIMZ_BIT 11 // Infinity * 0 +#define FPSCR_VXVC_BIT 12 // Invalid compare +#define FPSCR_FR_BIT 13 // Fraction rounded +#define FPSCR_FI_BIT 14 // Fraction inexact +#define FPSCR_VXSOFT_BIT 21 // Software request +#define FPSCR_VXSQRT_BIT 22 // Invalid square root +#define FPSCR_VXCVI_BIT 23 // Invalid integer convert +#define FPSCR_VE_BIT 24 // Invalid operation exception enable +#define FPSCR_OE_BIT 25 // Overflow exception enable +#define FPSCR_UE_BIT 26 // Underflow exception enable +#define FPSCR_ZE_BIT 27 // Zero divide exception enable +#define FPSCR_XE_BIT 28 // Inexact exception enable +#define FPSCR_NI_BIT 29 // Non-IEEE mode +#endif + +u32 PPCMfmsr(); +void PPCMtmsr(u32 newMSR); +u32 PPCMfhid0(); +void PPCMthid0(u32 newHID0); +u32 PPCMfl2cr(); void PPCMtl2cr(u32 newL2cr); +void PPCMtdec(u32 newDec); +void PPCSync(); +void PPCHalt(); +u32 PPCMffpscr(); +void PPCMtfpscr(u32 newFPSCR); +u32 PPCMfhid2(); +void PPCMthid2(u32 newhid2); +void PPCMtwpar(u32 newwpar); +void PPCEnableSpeculation(); +void PPCDisableSpeculation(); +void PPCSetFpNonIEEEMode(); -u32 PPCMtdec(u32 newDec); - -void PPCSync(void); -void PPCHalt(void); - -void PPCMtmmcr0(u32 newMmcr0); -void PPCMtmmcr1(u32 newMmcr1); -void PPCMtpmc1(u32 newPmc1); -void PPCMtpmc2(u32 newPmc2); -void PPCMtpmc3(u32 newPmc3); -void PPCMtpmc4(u32 newPmc4); - -u32 PPCMffpscr(void); -void PPCMtfpscr(u32 newFpscr); - -u32 PPCMfhid2(void); -void PPCMthid2(u32 newHid2); - -void PPCMtwpar(u32 newWpar); - -void PPCDisableSpeculation(void); -void PPCSetFpNonIEEEMode(void); +#ifdef __cplusplus +} +#endif #endif diff --git a/include/dolphin/db.h b/include/dolphin/db.h index a4e3d7a..2c463d1 100644 --- a/include/dolphin/db.h +++ b/include/dolphin/db.h @@ -1,6 +1,8 @@ #ifndef _DOLPHIN_DBINTERFACE_H_ #define _DOLPHIN_DBINTERFACE_H_ +#define OS_DBINTERFACE_ADDR 0x00000040 + void DBInit(void); void DBPrintf(char* str, ...); diff --git a/include/dolphin/hw_regs.h b/include/dolphin/hw_regs.h new file mode 100644 index 0000000..3347092 --- /dev/null +++ b/include/dolphin/hw_regs.h @@ -0,0 +1,234 @@ +#ifndef _DOLPHIN_HW_REGS +#define _DOLPHIN_HW_REGS + +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MWERKS__ + +vu16 __VIRegs[59] : 0xCC002000; + +// offsets for __VIRegs[i] +#define VI_VERT_TIMING (0) +#define VI_DISP_CONFIG (1) +#define VI_HORIZ_TIMING_0L (2) +#define VI_HORIZ_TIMING_0U (3) +#define VI_HORIZ_TIMING_1L (4) +#define VI_HORIZ_TIMING_1U (5) +#define VI_VERT_TIMING_ODD (6) +#define VI_VERT_TIMING_ODD_U (7) +#define VI_VERT_TIMING_EVEN (8) +#define VI_VERT_TIMING_EVEN_U (9) + +#define VI_BBI_ODD (10) // burst blanking interval +#define VI_BBI_ODD_U (11) // burst blanking interval +#define VI_BBI_EVEN (12) // burst blanking interval +#define VI_BBI_EVEN_U (13) // burst blanking interval + +#define VI_TOP_FIELD_BASE_LEFT (14) // top in 2d, top of left pic in 3d +#define VI_TOP_FIELD_BASE_LEFT_U (15) // top in 2d, top of left pic in 3d + +#define VI_TOP_FIELD_BASE_RIGHT (16) // top of right pic in 3d +#define VI_TOP_FIELD_BASE_RIGHT_U (17) // top of right pic in 3d + +#define VI_BTTM_FIELD_BASE_LEFT (18) // bottom in 2d, bottom of left pic in 3d +#define VI_BTTM_FIELD_BASE_LEFT_U (19) // bottom in 2d, bottom of left pic in 3d + +#define VI_BTTM_FIELD_BASE_RIGHT (20) // bottom of right pic in 3d +#define VI_BTTM_FIELD_BASE_RIGHT_U (21) // bottom of right pic in 3d + +#define VI_VERT_COUNT (22) // vertical display position +#define VI_HORIZ_COUNT (23) // horizontal display position + +#define VI_DISP_INT_0 (24) // display interrupt 0L +#define VI_DISP_INT_0U (25) // display interrupt 0U +#define VI_DISP_INT_1 (26) // display interrupt 1L +#define VI_DISP_INT_1U (27) // display interrupt 1U +#define VI_DISP_INT_2 (28) // display interrupt 2L +#define VI_DISP_INT_2U (29) // display interrupt 2U +#define VI_DISP_INT_3 (30) // display interrupt 3L +#define VI_DISP_INT_3U (31) // display interrupt 3U + +#define VI_HSW (36) // horizontal scaling width +#define VI_HSR (37) // horizontal scaling register + +#define VI_FCT_0 (38) // filter coefficient table 0L +#define VI_FCT_0U (39) // filter coefficient table 0U +#define VI_FCT_1 (40) // filter coefficient table 1L +#define VI_FCT_1U (41) // filter coefficient table 1U +#define VI_FCT_2 (42) // filter coefficient table 2L +#define VI_FCT_2U (43) // filter coefficient table 2U +#define VI_FCT_3 (44) // filter coefficient table 3L +#define VI_FCT_3U (45) // filter coefficient table 3U +#define VI_FCT_4 (46) // filter coefficient table 4L +#define VI_FCT_4U (47) // filter coefficient table 4U +#define VI_FCT_5 (48) // filter coefficient table 5L +#define VI_FCT_5U (49) // filter coefficient table 5U +#define VI_FCT_6 (50) // filter coefficient table 6L +#define VI_FCT_6U (51) // filter coefficient table 6U + +#define VI_CLOCK_SEL (54) // clock select +#define VI_DTV_STAT (55) // DTV status + +#define VI_WIDTH (56) + +vu32 __PIRegs[12] : 0xCC003000; + +// offsets for __PIRegs[i] + +#define PI_INTRPT_SRC (0) // interrupt cause +#define PI_INTRPT_MASK (1) // interrupt mask +#define PI_FIFO_START (3) // FIFO base start +#define PI_FIFO_END (4) // FIFO base end +#define PI_FIFO_PTR (5) // FIFO current write pointer + +#define PI_RESETCODE (9) // reset code, used by OSReset + +// PI Interrupt causes. +#define PI_INTRPT_ERR (0x1) // GP runtime error +#define PI_INTRPT_RSW (0x2) // reset switch +#define PI_INTRPT_DVD (0x4) // DVD/DI interrupt +#define PI_INTRPT_SI (0x8) // serial/controller interrupt +#define PI_INTRPT_EXI (0x10) // external mem interrupt +#define PI_INTRPT_AI (0x20) // audio streaming interrupt +#define PI_INTRPT_DSP (0x40) // digital signal proc interrupt +#define PI_INTRPT_MEM (0x80) // memory interface interrupt +#define PI_INTRPT_VI (0x100) // video interface interrupt +#define PI_INTRPT_PE_TOKEN (0x200) // pixel engine token +#define PI_INTRPT_PE_FINISH (0x400) // pixel engine finish +#define PI_INTRPT_CP (0x800) // command FIFO +#define PI_INTRPT_DEBUG (0x1000) // external debugger +#define PI_INTRPT_HSP (0x2000) // high speed port +#define PI_INTRPT_RSWST (0x10000) // reset switch state (1 when pressed) + +vu16 __MEMRegs[64] : 0xCC004000; + +// offsets for __MEMRegs[i] +#define MEM_PROT_1 (0) // protected region 1 +#define MEM_PROT_2 (2) // protected region 1 +#define MEM_PROT_3 (4) // protected region 1 +#define MEM_PROT_4 (6) // protected region 1 +#define MEM_PROT_TYPE (8) // protection type + +#define MEM_INTRPT_MASK (14) // interrupt mask +#define MEM_INTRPT_SRC (15) // interrupt cause +#define MEM_INTRPT_FLAG (16) // set when interrupt happens +#define MEM_INTRPT_ADDR_LO (17) // address that caused interrupt +#define MEM_INTRPT_ADDR_HI (18) // address that caused interrupt + +#define MEM_UNK_FLAG (20) // unknown memory flag, set in __OSInitMemoryProtection + +vu16 __DSPRegs[32] : 0xCC005000; + +// offsets for __DSPRegs[i] +#define DSP_MAILBOX_IN_HI (0) +#define DSP_MAILBOX_IN_LO (1) +#define DSP_MAILBOX_OUT_HI (2) +#define DSP_MAILBOX_OUT_LO (3) +#define DSP_CONTROL_STATUS (5) + +#define DSP_ARAM_SIZE (9) +#define DSP_ARAM_MODE (11) +#define DSP_ARAM_REFRESH (13) +#define DSP_ARAM_DMA_MM_HI (16) // Main mem address +#define DSP_ARAM_DMA_MM_LO (17) +#define DSP_ARAM_DMA_ARAM_HI (18) // ARAM address +#define DSP_ARAM_DMA_ARAM_LO (19) +#define DSP_ARAM_DMA_SIZE_HI (20) // DMA buffer size +#define DSP_ARAM_DMA_SIZE_LO (21) + +#define DSP_DMA_START_HI (24) // DMA start address +#define DSP_DMA_START_LO (25) +#define DSP_DMA_CONTROL_LEN (27) +#define DSP_DMA_BYTES_LEFT (29) + +vu32 __DIRegs[16] : 0xCC006000; + +// offsets for __DIRegs[i] +#define DI_STATUS (0) +#define DI_COVER_STATUS (1) // cover status - 0=normal, 1=interrupt/open +#define DI_CMD_BUF_0 (2) // command buffer 0 +#define DI_CMD_BUF_1 (3) // command buffer 1 +#define DI_CMD_BUF_2 (4) // command buffer 2 +#define DI_DMA_MEM_ADDR (5) // DMA address +#define DI_DMA_LENGTH (6) // transfer length address +#define DI_CONTROL (7) +#define DI_MM_BUF (8) // Main memory buffer +#define DI_CONFIG (9) + +vu32 __SIRegs[64] : 0xCC006400; + +// offsets for __SIRegs[i] +// Channel 0/Joy-channel 1 +#define SI_CHAN_0_BUF (0) // output buffer +#define SI_CHAN_0_BTN_1 (1) // button 1 +#define SI_CHAN_0_BTN_2 (2) // button 2 +// Channel 1/Joy-channel 2 +#define SI_CHAN_1_BUF (3) // output buffer +#define SI_CHAN_1_BTN_1 (4) // button 1 +#define SI_CHAN_1_BTN_2 (5) // button 2 +// Channel 2/Joy-channel 3 +#define SI_CHAN_2_BUF (6) // output buffer +#define SI_CHAN_2_BTN_1 (7) // button 1 +#define SI_CHAN_2_BTN_2 (8) // button 2 +// Channel 3/Joy-channel 4 +#define SI_CHAN_3_BUF (9) // output buffer +#define SI_CHAN_3_BTN_1 (10) // button 1 +#define SI_CHAN_3_BTN_2 (11) // button 2 + +#define SI_POLL (12) +#define SI_CC_STAT (13) // communication control status +#define SI_STAT (14) +#define SI_EXI_LOCK (15) // exi clock lock + +#define SI_IO_BUFFER (32) // start of buffer (32 to 63) + +vu32 __EXIRegs[16] : 0xCC006800; + +// offsets for __EXIRegs[i] +// Channel 0 +#define EXI_CHAN_0_STAT (0) // parameters/status +#define EXI_CHAN_0_DMA_ADDR (1) // DMA start address +#define EXI_CHAN_0_LEN (2) // DMA transfer length +#define EXI_CHAN_0_CONTROL (3) // control register +#define EXI_CHAN_0_IMM (4) // immediate data +// Channel 1 +#define EXI_CHAN_1_STAT (5) // parameters/status +#define EXI_CHAN_1_DMA_ADDR (6) // DMA start address +#define EXI_CHAN_1_LEN (7) // DMA transfer length +#define EXI_CHAN_1_CONTROL (8) // control register +#define EXI_CHAN_1_IMM (9) // immediate data +// Channel 2 +#define EXI_CHAN_2_STAT (10) // parameters/status +#define EXI_CHAN_2_DMA_ADDR (11) // DMA start address +#define EXI_CHAN_2_LEN (12) // DMA transfer length +#define EXI_CHAN_2_CONTROL (13) // control register +#define EXI_CHAN_2_IMM (14) // immediate data + +vu32 __AIRegs[8] : 0xCC006C00; + +// offsets for __AIRegs[i] +#define AI_CONTROL (0) // control +#define AI_VOLUME (1) // volume +#define AI_SAMPLE_COUNTER (2) // number of stereo samples output +#define AI_INTRPT_TIMING (3) // interrupt timing + +#else +#define __VIRegs ((vu16*)0xCC002000) +#define __PIRegs ((vu32*)0xCC003000) +#define __MEMRegs ((vu16*)0xCC004000) +#define __DSPRegs ((vu16*)0xCC005000) +#define __DIRegs ((vu32*)0xCC006000) +#define __SIRegs ((vu32*)0xCC006400) +#define __EXIRegs ((vu32*)0xCC006800) +#define __AIRegs ((vu32*)0xCC006C00) +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_HW_REGS diff --git a/include/dolphin/os.h b/include/dolphin/os.h index 7f55a75..35c918f 100644 --- a/include/dolphin/os.h +++ b/include/dolphin/os.h @@ -1,94 +1,230 @@ -#ifndef _DOLPHIN_OS_H_ -#define _DOLPHIN_OS_H_ +#ifndef _DOLPHIN_OS_H +#define _DOLPHIN_OS_H + +#include "dolphin/gx.h" +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Upper words of the masks, since UIMM is only 16 bits +#define OS_CACHED_REGION_PREFIX 0x8000 +#define OS_UNCACHED_REGION_PREFIX 0xC000 +#define OS_PHYSICAL_MASK 0x3FFF + +#define OS_BASE_CACHED (OS_CACHED_REGION_PREFIX << 16) +#define OS_BASE_UNCACHED (OS_UNCACHED_REGION_PREFIX << 16) + +#ifdef __MWERKS__ +#define AT_ADDRESS(xyz) : (xyz) +#else +#define AT_ADDRESS(xyz) +#endif +typedef s64 OSTime; +typedef u32 OSTick; +u32 __OSBusClock AT_ADDRESS(OS_BASE_CACHED | 0x00F8); // sync with OSLoMem.h +u32 __OSCoreClock AT_ADDRESS(OS_BASE_CACHED | 0x00FC); // sync with OSLoMem.h +#define OS_BUS_CLOCK (u32) __OSBusClock +#define OS_CORE_CLOCK __OSCoreClock +#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) + +#ifndef _DEBUG +#define OSPhysicalToCached(paddr) ((void*)((u32)(paddr) + OS_BASE_CACHED)) +#define OSPhysicalToUncached(paddr) ((void*)((u32)(paddr) + OS_BASE_UNCACHED)) +#define OSCachedToPhysical(caddr) ((u32)((u8*)(caddr)-OS_BASE_CACHED)) +#define OSUncachedToPhysical(ucaddr) ((u32)((u8*)(ucaddr)-OS_BASE_UNCACHED)) +#define OSCachedToUncached(caddr) ((void*)((u8*)(caddr) + (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#define OSUncachedToCached(ucaddr) ((void*)((u8*)(ucaddr) - (OS_BASE_UNCACHED - OS_BASE_CACHED))) +#else +u32 OSPhysicalToCached(void* paddr); +u32 OSPhysicalToUncached(void* paddr); +u32 OSCachedToPhysical(void* caddr); +u32 OSUncachedToPhysical(void* ucaddr); +u32 OSCachedToUncached(void* caddr); +u32 OSUncachedToCached(void* ucaddr); +#endif + +#define OSTicksToCycles(ticks) (((ticks) * ((OS_CORE_CLOCK * 2) / OS_TIMER_CLOCK)) / 2) +#define OSTicksToSeconds(ticks) ((ticks) / OS_TIMER_CLOCK) +#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK / 1000)) +#define OSTicksToMicroseconds(ticks) (((ticks)*8) / (OS_TIMER_CLOCK / 125000)) +#define OSTicksToNanoseconds(ticks) (((ticks)*8000) / (OS_TIMER_CLOCK / 125000)) +#define OSSecondsToTicks(sec) ((sec)*OS_TIMER_CLOCK) +#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000)) +#define OSMicrosecondsToTicks(usec) (((usec) * (OS_TIMER_CLOCK / 125000)) / 8) +#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000) + +#define OSDiffTick(tick1, tick0) ((s32)(tick1) - (s32)(tick0)) + +#define OSRoundUp32B(v) (((u32)(v) + 31) & ~31) +#define OSRoundDown32B(x) (((u32)(x)) & ~(0x1F)) + +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* newHi); +void OSSetArenaLo(void* newLo); + +void OSInit(); + +OSTime OSGetTime(); +OSTick OSGetTick(); + +typedef struct OSCalendarTime { + int sec; // seconds after the minute [0, 61] + int min; // minutes after the hour [0, 59] + int hour; // hours since midnight [0, 23] + int mday; // day of the month [1, 31] + int mon; // month since January [0, 11] + int year; // years in AD [1, ...] + int wday; // days since Sunday [0, 6] + int yday; // days since January 1 [0, 365] + + int msec; // milliseconds after the second [0,999] + int usec; // microseconds after the millisecond [0,999] +} OSCalendarTime; + +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td); + +#define OS_CONSOLE_MASK 0xf0000000 +#define OS_CONSOLE_RETAIL 0x00000000 +#define OS_CONSOLE_DEVELOPMENT 0x10000000 +#define OS_CONSOLE_TDEV 0x20000000 + +#define OS_CONSOLE_RETAIL4 0x00000004 +#define OS_CONSOLE_RETAIL3 0x00000003 +#define OS_CONSOLE_RETAIL2 0x00000002 +#define OS_CONSOLE_RETAIL1 0x00000001 +#define OS_CONSOLE_TDEVHW4 0x20000007 +#define OS_CONSOLE_TDEVHW3 0x20000006 +#define OS_CONSOLE_TDEVHW2 0x20000005 +#define OS_CONSOLE_TDEVHW1 0x20000004 +#define OS_CONSOLE_DEVHW4 0x10000007 +#define OS_CONSOLE_DEVHW3 0x10000006 +#define OS_CONSOLE_DEVHW2 0x10000005 +#define OS_CONSOLE_DEVHW1 0x10000004 +#define OS_CONSOLE_MINNOW 0x10000003 +#define OS_CONSOLE_ARTHUR 0x10000002 +#define OS_CONSOLE_PC_EMULATOR 0x10000001 +#define OS_CONSOLE_EMULATOR 0x10000000 + +u32 OSGetConsoleType(); + +#define OS_SOUND_MODE_MONO 0u +#define OS_SOUND_MODE_STEREO 1u + +u32 OSGetSoundMode(void); +void OSSetSoundMode(u32 mode); + +#define OS_PROGRESSIVE_MODE_OFF 0u +#define OS_PROGRESSIVE_MODE_ON 1u + +#define OS_LANG_ENGLISH 0u +#define OS_LANG_GERMAN 1u +#define OS_LANG_FRENCH 2u +#define OS_LANG_SPANISH 3u +#define OS_LANG_ITALIAN 4u +#define OS_LANG_DUTCH 5u + +#define OS_EURGB60_OFF 0u +#define OS_EURGB60_ON 1u + +void OSRegisterVersion(const char* id); + +BOOL OSDisableInterrupts(void); +BOOL OSEnableInterrupts(void); +BOOL OSRestoreInterrupts(BOOL level); + +#define OSHalt(msg) OSPanic(__FILE__, __LINE__, msg) + +volatile int __OSTVMode AT_ADDRESS(OS_BASE_CACHED | 0xCC); + +#ifdef _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) (void)((exp) || (OSPanic(__FILE__, __LINE__, "Failed assertion " #exp), 0)) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || defined(__SN__) +#define ASSERTMSG(exp, ...) (void)((exp) || (OSPanic(__FILE__, __LINE__, __VA_ARGS__), 0)) +#else +#define ASSERTMSG(exp, msg) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg)), 0)) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1)), 0)) +#endif + +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2)), 0)) +#endif + +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3)), 0)) +#endif + +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) \ + (void)((exp) || (OSPanic(__FILE__, __LINE__, (msg), (param1), (param2), (param3), (param4)), 0)) +#endif + +#else // _DEBUG + +#ifndef ASSERT +#define ASSERT(exp) ((void)0) +#endif + +#ifndef ASSERTMSG +#if defined(__STDC_VERSION__) && (199901L <= __STDC_VERSION__) || defined(__MWERKS__) || defined(__SN__) +#define ASSERTMSG(exp, ...) ((void)0) +#else +#define ASSERTMSG(exp, msg) ((void)0) +#endif +#endif + +#ifndef ASSERTMSG1 +#define ASSERTMSG1(exp, msg, param1) ((void)0) +#endif +#ifndef ASSERTMSG2 +#define ASSERTMSG2(exp, msg, param1, param2) ((void)0) +#endif +#ifndef ASSERTMSG3 +#define ASSERTMSG3(exp, msg, param1, param2, param3) ((void)0) +#endif +#ifndef ASSERTMSG4 +#define ASSERTMSG4(exp, msg, param1, param2, param3, param4) ((void)0) +#endif + +#endif // _DEBUG + +void OSReport(const char* msg, ...); +void OSPanic(const char* file, int line, const char* msg, ...); + +#ifdef __cplusplus +} +#endif #include "dolphin/os/OSAlarm.h" #include "dolphin/os/OSAlloc.h" +#include "dolphin/os/OSArena.h" #include "dolphin/os/OSCache.h" #include "dolphin/os/OSContext.h" #include "dolphin/os/OSError.h" +#include "dolphin/os/OSException.h" +#include "dolphin/os/OSExpansion.h" +#include "dolphin/os/OSFastCast.h" #include "dolphin/os/OSFont.h" #include "dolphin/os/OSInterrupt.h" +#include "dolphin/os/OSMemory.h" #include "dolphin/os/OSMessage.h" #include "dolphin/os/OSModule.h" #include "dolphin/os/OSMutex.h" #include "dolphin/os/OSReset.h" #include "dolphin/os/OSResetSW.h" -#include "dolphin/os/OSRtc.h" +#include "dolphin/os/OSSerial.h" #include "dolphin/os/OSThread.h" -#include "dolphin/os/OSTime.h" - -#define OS_BASE_CACHED 0x80000000 -#define OS_BASE_UNCACHED 0xC0000000 - -#ifdef __MWERKS__ -u32 __OSBusClock : (OS_BASE_CACHED | 0x00F8); -u32 __OSCoreClock : (OS_BASE_CACHED | 0x00FC); -OSThread* __gUnkThread1 : (OS_BASE_CACHED | 0x00D8); -OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); -OSThread* __gCurrentThread : (OS_BASE_CACHED | 0x00E4); -#else -#define __OSBusClock (*(u32*)(OS_BASE_CACHED | 0x00F8)) -#define __OSCoreClock (*(u32*)(OS_BASE_CACHED | 0x00FC)) -#endif -#define OS_BUS_CLOCK __OSBusClock -#define OS_CORE_CLOCK __OSCoreClock -#define OS_TIMER_CLOCK (OS_BUS_CLOCK / 4) - -#define OSTicksToSeconds(ticks) ((ticks) / (OS_TIMER_CLOCK)) -#define OSTicksToMilliseconds(ticks) ((ticks) / (OS_TIMER_CLOCK / 1000)) -#define OSTicksToMicroseconds(ticks) ((ticks)*8 / (OS_TIMER_CLOCK / 125000)) -#define OSSecondsToTicks(sec) ((sec) * (OS_TIMER_CLOCK)) -#define OSMillisecondsToTicks(msec) ((msec) * (OS_TIMER_CLOCK / 1000)) -#define OSNanosecondsToTicks(nsec) (((nsec) * (OS_TIMER_CLOCK / 125000)) / 8000) - -void OSInit(void); - -void* OSGetArenaHi(void); -void* OSGetArenaLo(void); -void OSSetArenaHi(void*); -void OSSetArenaLo(void*); - -typedef u8 __OSException; -typedef void (*__OSExceptionHandler)(__OSException exception, OSContext* context); - -__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); -__OSExceptionHandler __OSGetExceptionHandler(__OSException exception); - -u32 OSGetConsoleType(void); -void __OSPSInit(void); -void __OSFPRInit(void); -void OSRegisterVersion(const char* id); - -typedef struct OSCalendarTime { - /* 0x00 */ s32 sec; - /* 0x04 */ s32 min; - /* 0x08 */ s32 hour; - /* 0x0C */ s32 mday; - /* 0x10 */ s32 mon; - /* 0x14 */ s32 year; - /* 0x18 */ s32 wday; - /* 0x1C */ s32 yday; - /* 0x20 */ s32 msec; - /* 0x24 */ s32 usec; -} OSCalendarTime; - -OSTick OSGetTick(void); -OSTime OSGetTime(void); -void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td); -BOOL OSEnableInterrupts(void); -BOOL OSDisableInterrupts(void); -BOOL OSRestoreInterrupts(BOOL level); - -#define OS_SOUND_MODE_MONO 0 -#define OS_SOUND_MODE_STEREO 1 - -u32 OSGetSoundMode(void); -void OSSetSoundMode(u32 mode); - -void OSReport(char*, ...); -void OSPanic(char* file, s32 line, char* msg, ...); - -#define OSRoundUp32B(x) (((u32)(x) + 32 - 1) & ~(32 - 1)) -#define OSRoundDown32B(x) (((u32)(x)) & ~(32 - 1)) - #endif diff --git a/include/dolphin/os/OSAlarm.h b/include/dolphin/os/OSAlarm.h index b81298b..d73ed3e 100644 --- a/include/dolphin/os/OSAlarm.h +++ b/include/dolphin/os/OSAlarm.h @@ -1,8 +1,12 @@ -#ifndef _DOLPHIN_OS_OSALARM_H_ -#define _DOLPHIN_OS_OSALARM_H_ +#ifndef _DOLPHIN_OSALARM +#define _DOLPHIN_OSALARM #include "dolphin/os/OSContext.h" -#include "dolphin/os/OSTime.h" +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif typedef struct OSAlarm OSAlarm; typedef void (*OSAlarmHandler)(OSAlarm* alarm, OSContext* context); @@ -22,4 +26,10 @@ void OSCreateAlarm(OSAlarm* alarm); void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler); void OSCancelAlarm(OSAlarm* alarm); +BOOL OSCheckAlarmQueue(void); + +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSALARM diff --git a/include/dolphin/os/OSAlloc.h b/include/dolphin/os/OSAlloc.h index 1c40a5e..d512cd5 100644 --- a/include/dolphin/os/OSAlloc.h +++ b/include/dolphin/os/OSAlloc.h @@ -1,20 +1,29 @@ -#ifndef _DOLPHIN_OS_OSALLOC_H_ -#define _DOLPHIN_OS_OSALLOC_H_ +#ifndef _DOLPHIN_OSALLOC +#define _DOLPHIN_OSALLOC #include "dolphin/types.h" -typedef s32 OSHeapHandle; +#ifdef __cplusplus +extern "C" { +#endif + +typedef int OSHeapHandle; +typedef void (*OSAllocVisitor)(void* obj, u32 size); + +void* OSAllocFromHeap(OSHeapHandle heap, u32 size); +void OSFreeToHeap(OSHeapHandle heap, void* ptr); +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap); +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps); +OSHeapHandle OSCreateHeap(void* start, void* end); +long OSCheckHeap(OSHeapHandle heap); extern volatile OSHeapHandle __OSCurrHeap; -void* OSInitAlloc(void*, void*, s32); -OSHeapHandle OSCreateHeap(void*, void*); -OSHeapHandle OSSetCurrentHeap(OSHeapHandle); -void* OSAllocFromHeap(OSHeapHandle, u32); -s32 OSCheckHeap(OSHeapHandle); -void OSFreeToHeap(OSHeapHandle heap, void* ptr); - #define OSAlloc(size) OSAllocFromHeap(__OSCurrHeap, (size)) #define OSFree(ptr) OSFreeToHeap(__OSCurrHeap, (ptr)) +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSALLOC diff --git a/include/dolphin/os/OSArena.h b/include/dolphin/os/OSArena.h new file mode 100644 index 0000000..7d0d363 --- /dev/null +++ b/include/dolphin/os/OSArena.h @@ -0,0 +1,11 @@ +#ifndef _DOLPHIN_OSARENA +#define _DOLPHIN_OSARENA + +#include "dolphin/types.h" + +void* OSGetArenaHi(void); +void* OSGetArenaLo(void); +void OSSetArenaHi(void* addr); +void OSSetArenaLo(void* addr); + +#endif // _DOLPHIN_OSARENA diff --git a/include/dolphin/os/OSBootInfo.h b/include/dolphin/os/OSBootInfo.h new file mode 100644 index 0000000..1727eb9 --- /dev/null +++ b/include/dolphin/os/OSBootInfo.h @@ -0,0 +1,50 @@ +#ifndef _DOLPHIN_OSBOOTINFO +#define _DOLPHIN_OSBOOTINFO + +#include "dolphin/DVDPriv.h" +#include "dolphin/types.h" + +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; + +// Magic number defines. +#define OS_BOOTINFO_MAGIC 0x0D15EA5E +#define OS_BOOTINFO_MAGIC_JTAG 0xE5207C22 +#define OS_DVD_MAGIC_NINTENDO 0xC2339F3D +#define OS_THREAD_STACK_MAGIC 0xDEADBABE + +#define OS_BOOTROM_ADDR 0x81300000 + +#endif // _DOLPHIN_OSBOOTINFO diff --git a/include/dolphin/os/OSCache.h b/include/dolphin/os/OSCache.h index 10f6fff..6d2d1ae 100644 --- a/include/dolphin/os/OSCache.h +++ b/include/dolphin/os/OSCache.h @@ -1,23 +1,31 @@ -#ifndef _DOLPHIN_OS_OSCACHE_H_ -#define _DOLPHIN_OS_OSCACHE_H_ +#ifndef _DOLPHIN_OSCACHE +#define _DOLPHIN_OSCACHE #include "dolphin/types.h" -void DCEnable(void); +#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 DCZeroRange(void* addr, u32 nBytes); void ICInvalidateRange(void* addr, u32 nBytes); -void ICFlashInvalidate(void); -void ICEnable(void); -void LCEnable(void); + +#define LC_BASE_PREFIX 0xE000 +#define LC_BASE (LC_BASE_PREFIX << 16) +#define LCGetBase() ((void*)LC_BASE) + +void LCEnable(); void LCDisable(void); void LCStoreBlocks(void* destAddr, void* srcTag, u32 numBlocks); u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes); void LCQueueWait(u32 len); -void L2GlobalInvalidate(void); -void __OSCacheInit(void); +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSCACHE diff --git a/include/dolphin/os/OSContext.h b/include/dolphin/os/OSContext.h index 833c8f3..4062d37 100644 --- a/include/dolphin/os/OSContext.h +++ b/include/dolphin/os/OSContext.h @@ -1,35 +1,176 @@ -#ifndef _DOLPHIN_OS_OSCONTEXT_H_ -#define _DOLPHIN_OS_OSCONTEXT_H_ +#ifndef _DOLPHIN_OSCONTEXT +#define _DOLPHIN_OSCONTEXT #include "dolphin/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 { - /* 0x000 */ u32 gpr[32]; - /* 0x080 */ u32 cr; - /* 0x084 */ u32 lr; - /* 0x088 */ u32 ctr; - /* 0x08C */ u32 xer; - /* 0x090 */ f64 fpr[32]; - /* 0x190 */ u32 fpscr_pad; - /* 0x194 */ u32 fpscr; - /* 0x198 */ u32 srr0; - /* 0x19C */ u32 srr1; - /* 0x1A0 */ u16 mode; - /* 0x1A2 */ u16 state; - /* 0x1A4 */ u32 gqr[8]; - /* 0x1C4 */ f64 psf[32]; + 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; -void OSSaveFPUContext(OSContext* context); -void OSSetCurrentContext(OSContext* context); +void OSSaveFPUContext(register OSContext* fpuContext); +void OSSetCurrentContext(register OSContext* context); OSContext* OSGetCurrentContext(void); -u32 OSSaveContext(OSContext* context); -void OSLoadContext(OSContext* context); -u32 OSGetStackPointer(void); -void OSClearContext(OSContext* context); -void OSInitContext(OSContext* context, u32 pc, u32 sp); +u32 OSSaveContext(register OSContext* context); +void OSLoadContext(register OSContext* context); +u32 OSGetStackPointer(); +void OSClearContext(register OSContext* context); +void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp); void OSDumpContext(OSContext* context); +void __OSContextInit(void); +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSCONTEXT diff --git a/include/dolphin/os/OSError.h b/include/dolphin/os/OSError.h index a7ce231..61657e3 100644 --- a/include/dolphin/os/OSError.h +++ b/include/dolphin/os/OSError.h @@ -1,10 +1,12 @@ -#ifndef _DOLPHIN_OS_OSERROR_H_ -#define _DOLPHIN_OS_OSERROR_H_ +#ifndef _DOLPHIN_OSERROR +#define _DOLPHIN_OSERROR -#include "dolphin/os/OSContext.h" +#include "dolphin/os/OSException.h" +#include "dolphin/types.h" -typedef u16 OSError; -typedef void (*OSErrorHandler)(OSError error, OSContext* context, ...); +#ifdef __cplusplus +extern "C" { +#endif #define OS_ERROR_SYSTEM_RESET 0 #define OS_ERROR_MACHINE_CHECK 1 @@ -21,8 +23,21 @@ typedef void (*OSErrorHandler)(OSError error, OSContext* context, ...); #define OS_ERROR_BREAKPOINT 12 #define OS_ERROR_SYSTEM_INTERRUPT 13 #define OS_ERROR_THERMAL_INTERRUPT 14 -#define OS_ERROR_MAX (OS_ERROR_THERMAL_INTERRUPT + 1) +#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, ...); + +void OSReport(const char* msg, ...); +void OSPanic(const char* file, int line, const char* msg, ...); OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler); +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +#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..d5e069f --- /dev/null +++ b/include/dolphin/os/OSException.h @@ -0,0 +1,55 @@ + +#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..2eaa1d5 --- /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 index 98a4e82..8de5f00 100644 --- a/include/dolphin/os/OSFont.h +++ b/include/dolphin/os/OSFont.h @@ -1,11 +1,65 @@ -#ifndef _DOLPHIN_OS_OSFONT_H_ -#define _DOLPHIN_OS_OSFONT_H_ +#ifndef _DOLPHIN_OSFONT +#define _DOLPHIN_OSFONT #include "dolphin/types.h" -#define OS_FONT_ENCODE_ANSI 0u -#define OS_FONT_ENCODE_SJIS 1u - -u16 OSGetFontEncode(void); - +#ifdef __cplusplus +extern "C" { #endif + +// Struct for holding font information (size 0x30). +typedef struct OSFontHeader { + u16 fontType; // _00 + u16 firstChar; // _02, first char code defined in font. + u16 lastChar; // _04, last char code defined in font. + u16 invalChar; // _06, code to sub for invalid chars. + u16 ascent; // _08 + u16 descent; // _0A + u16 width; // _0C, max width. + u16 leading; // _0E + u16 cellWidth; // _10 + u16 cellHeight; // _12 + u32 sheetSize; // _14 + u16 sheetFormat; // _18, see GX_TF_* part of GXTexFmt enum + u16 sheetColumn; // _1A + u16 sheetRow; // _1C + u16 sheetWidth; // _1E + u16 sheetHeight; // _20 + u16 widthTable; // _22 + u32 sheetImage; // _24 + u32 sheetFullSize; // _28 + u8 c0; // _2C, font color components? + u8 c1; // _2D + u8 c2; // _2E + u8 c3; // _2F +} OSFontHeader; + +typedef enum { + OS_FONT_ENCODE_NULL = -1, // -1 + OS_FONT_ENCODE_ANSI, // 0 + OS_FONT_ENCODE_SJIS, // 1 + OS_FONT_ENCODE_2, // 2 + OS_FONT_ENCODE_UTF8, // 3 + OS_FONT_ENCODE_UTF16, // 4 + OS_FONT_ENCODE_UTF32, // 5 + OS_FONT_ENCODE_MAX, // 6 +} OSFontEncode; + +#define OS_FONT_SIZE_ANSI (288 + 131072) // 9 sheets +#define OS_FONT_SIZE_SJIS (3840 + 1179648) // 1 sheet +#define OS_FONT_ROM_SIZE_ANSI 12288 // 0x03000 +#define OS_FONT_ROM_SIZE_SJIS 315392 // 0x4D000 +#define OS_FONT_DATA_SIZE_ANSI 65824 +#define OS_FONT_DATA_SIZE_SJIS 593636 +#define OS_FONT_ENCODE_VOID 0xFFFF + +#define OS_FONT_PROPORTIONAL FALSE +#define OS_FONT_FIXED TRUE + +u16 OSGetFontEncode(); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSFONT diff --git a/include/dolphin/os/OSInterrupt.h b/include/dolphin/os/OSInterrupt.h index 4f91242..b65097c 100644 --- a/include/dolphin/os/OSInterrupt.h +++ b/include/dolphin/os/OSInterrupt.h @@ -1,11 +1,12 @@ -#ifndef _DOLPHIN_OS_OSINTERRUPT_H_ -#define _DOLPHIN_OS_OSINTERRUPT_H_ +#ifndef _DOLPHIN_OSINTERRUPT +#define _DOLPHIN_OSINTERRUPT #include "dolphin/os/OSContext.h" #include "dolphin/types.h" -typedef s16 __OSInterrupt; -typedef u32 OSInterruptMask; +#ifdef __cplusplus +extern "C" { +#endif #define __OS_INTERRUPT_MEM_0 0 #define __OS_INTERRUPT_MEM_1 1 @@ -36,16 +37,74 @@ typedef u32 OSInterruptMask; #define __OS_INTERRUPT_PI_HSP 26 #define __OS_INTERRUPT_MAX 32 -#define OS_INTERRUPTMASK_DSP_DSP (0x80000000u >> __OS_INTERRUPT_DSP_DSP) +#define OS_INTERRUPTMASK(interrupt) (0x80000000u >> (interrupt)) -typedef void (*__OSInterruptHandler)(__OSInterrupt intr, OSContext* ctx); +#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; BOOL OSDisableInterrupts(void); -BOOL OSEnableInterrupts(void); -BOOL OSRestoreInterrupts(BOOL level); +BOOL OSRestoreInterrupts(register BOOL level); __OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler); __OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt); -OSInterruptMask __OSMaskInterrupts(OSInterruptMask mask); -OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask mask); +void __OSInterruptInit(void); +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current); +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global); +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global); +void __OSDispatchInterrupt(__OSException exception, OSContext* context); +#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..7603f95 --- /dev/null +++ b/include/dolphin/os/OSMemory.h @@ -0,0 +1,29 @@ +#ifndef _DOLPHIN_OSMEMORY +#define _DOLPHIN_OSMEMORY + +#include "dolphin/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 Config24MB(); +void Config48MB(); +void RealMode(register u32 addr); +void __OSInitMemoryProtection(); + +#ifdef __cplusplus +} +#endif + +#endif // _DOLPHIN_OSMEMORY diff --git a/include/dolphin/os/OSMessage.h b/include/dolphin/os/OSMessage.h index ccc488f..1166f28 100644 --- a/include/dolphin/os/OSMessage.h +++ b/include/dolphin/os/OSMessage.h @@ -1,21 +1,33 @@ -#ifndef _DOLOPHIN_OS_OSMESSAGE_H_ -#define _DOLOPHIN_OS_OSMESSAGE_H_ +#ifndef _DOLPHIN_OSMESSAGE +#define _DOLPHIN_OSMESSAGE + +#ifdef __cplusplus +extern "C" { +#endif #include "dolphin/os/OSThread.h" - +typedef struct OSMessageQueue OSMessageQueue; typedef void* OSMessage; -typedef struct OSMessageQueue { - /* 0x00 */ OSThreadQueue queueSend; - /* 0x08 */ OSThreadQueue queueReceive; - /* 0x10 */ OSMessage* msgArray; - /* 0x14 */ s32 msgCount; - /* 0x18 */ s32 firstIndex; - /* 0x1C */ s32 usedCount; -} OSMessageQueue; +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 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 index 8211b01..3b481b6 100644 --- a/include/dolphin/os/OSModule.h +++ b/include/dolphin/os/OSModule.h @@ -1,8 +1,115 @@ -#ifndef _DOLPHIN_OS_OSMODULE_H_ -#define _DOLPHIN_OS_OSMODULE_H_ +#ifndef _DOLPHIN_OSMODULE +#define _DOLPHIN_OSMODULE #include "dolphin/types.h" -void __OSModuleInit(void); - +#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 index 2b9032f..cfa44d8 100644 --- a/include/dolphin/os/OSMutex.h +++ b/include/dolphin/os/OSMutex.h @@ -1,6 +1,28 @@ -#ifndef _DOLPHIN_OS_OSMUTEX_H_ -#define _DOLPHIN_OS_OSMUTEX_H_ +#ifndef _DOLPHIN_OSMUTEX +#define _DOLPHIN_OSMUTEX #include "dolphin/os/OSThread.h" +#include "dolphin/types.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 __OSUnlockAllMutex(OSThread* thread); + +#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..8b914f2 --- /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 +} +#endif + +#endif // _DOLPHIN_OSPRIV diff --git a/include/dolphin/os/OSReset.h b/include/dolphin/os/OSReset.h index e715a06..45b0152 100644 --- a/include/dolphin/os/OSReset.h +++ b/include/dolphin/os/OSReset.h @@ -1,30 +1,46 @@ -#ifndef _DOLPHIN_OS_OSRESET_H_ -#define _DOLPHIN_OS_OSRESET_H_ +#ifndef _DOLPHIN_OSRESET +#define _DOLPHIN_OSRESET + +#include "dolphin/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 -#include "dolphin/types.h" - -typedef BOOL (*OSResetFunction)(BOOL); +#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; }; -typedef struct OSResetFunctionQueue { - OSResetFunctionInfo* head; - OSResetFunctionInfo* tail; -} OSResetFunctionQueue; - -void OSRegisterResetFunction(OSResetFunctionInfo* info); -void OSResetSystem(s32 reset, u32 resetCode, BOOL forceMenu); -u32 OSGetResetCode(void); - +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSRESET diff --git a/include/dolphin/os/OSResetSW.h b/include/dolphin/os/OSResetSW.h index 5fc081a..51018e1 100644 --- a/include/dolphin/os/OSResetSW.h +++ b/include/dolphin/os/OSResetSW.h @@ -1,9 +1,19 @@ -#ifndef _DOLPHIN_OS_OSRESETSW_H_ -#define _DOLPHIN_OS_OSRESETSW_H_ +#ifndef _DOLPHIN_OSRESETSW +#define _DOLPHIN_OSRESETSW +#include "dolphin/os/OSContext.h" #include "dolphin/types.h" -void __OSResetSWInterruptHandler(void); +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*OSResetCallback)(void); + BOOL OSGetResetButtonState(void); +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSRESETSW diff --git a/include/dolphin/os/OSRtc.h b/include/dolphin/os/OSRtc.h index 4166808..5461e45 100644 --- a/include/dolphin/os/OSRtc.h +++ b/include/dolphin/os/OSRtc.h @@ -36,15 +36,18 @@ typedef struct OSSramEx { u8 _padding1[4]; } OSSramEx; -void __OSInitSram(void); -OSSram* __OSLockSram(void); -OSSramEx* __OSLockSramEx(void); -s32 __OSUnlockSram(s32 commit); -s32 __OSUnlockSramEx(s32 commit); -s32 __OSSyncSram(void); -u32 OSGetSoundMode(void); +BOOL WriteSram(void* buffer, u32 offset, u32 size); +void __OSInitSram(); +OSSram* __OSLockSram(); +OSSramEx* __OSLockSramEx(); +BOOL __OSUnlockSram(BOOL commit); +BOOL __OSUnlockSramEx(BOOL commit); +BOOL __OSSyncSram(); +u32 OSGetSoundMode(); void OSSetSoundMode(u32 mode); -u32 OSGetWirelessID(u32 chan); -void OSSetWirelessID(u32 chan, u16 id); +u16 OSGetWirelessID(s32 channel); +void OSSetWirelessID(s32 channel, u16 id); +u16 OSGetGbsMode(); +void OSSetGbsMode(u16 mode); #endif diff --git a/include/dolphin/os/OSSerial.h b/include/dolphin/os/OSSerial.h new file mode 100644 index 0000000..5588c0b --- /dev/null +++ b/include/dolphin/os/OSSerial.h @@ -0,0 +1,68 @@ +#ifndef _DOLPHIN_OSSERIAL +#define _DOLPHIN_OSSERIAL + +#include "dolphin/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 index 7d1c876..9a7ff22 100644 --- a/include/dolphin/os/OSThread.h +++ b/include/dolphin/os/OSThread.h @@ -1,84 +1,93 @@ -#ifndef _DOLPHIN_OS_OSTHREAD_H_ -#define _DOLPHIN_OS_OSTHREAD_H_ +#ifndef _DOLPHIN_OSTHREAD +#define _DOLPHIN_OSTHREAD #include "dolphin/os/OSContext.h" +#ifdef __cplusplus +extern "C" { +#endif + #define OS_THREAD_SPECIFIC_MAX 2 -typedef s32 OSPriority; - -struct OSMutex; -struct OSThread; +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 OSThread OSThread; +typedef struct OSMutexQueue OSMutexQueue; +typedef struct OSMutexLink OSMutexLink; +typedef struct OSCond OSCond; -typedef struct OSThreadQueue { +typedef void (*OSIdleFunction)(void* param); +typedef void (*OSSwitchThreadCallback)(OSThread* from, OSThread* to); + +struct OSThreadQueue { OSThread* head; OSThread* tail; -} OSThreadQueue; +}; -typedef struct OSThreadLink { +struct OSThreadLink { OSThread* next; OSThread* prev; -} OSThreadLink; +}; -typedef struct OSMutexQueue { +struct OSMutexQueue { OSMutex* head; OSMutex* tail; -} OSMutexQueue; +}; -typedef struct OSMutexLink { +struct OSMutexLink { OSMutex* next; OSMutex* prev; -} OSMutexLink; - -struct OSMutex { - OSThreadQueue queue; - OSThread* thread; - s32 count; - OSMutexLink link; }; struct OSThread { - /* 0x000 */ OSContext context; - /* 0x2C8 */ u16 state; - /* 0x2CA */ u16 attr; - /* 0x2CC */ s32 suspend; - /* 0x2D0 */ OSPriority priority; - /* 0x2D4 */ OSPriority base; - /* 0x2D8 */ void* val; - /* 0x2DC */ OSThreadQueue* queue; - /* 0x2E0 */ OSThreadLink link; - /* 0x2E8 */ OSThreadQueue queueJoin; - /* 0x2F0 */ OSMutex* mutex; - /* 0x2F4 */ OSMutexQueue queueMutex; - /* 0x2FC */ OSThreadLink linkActive; - /* 0x304 */ u8* stackBase; - /* 0x308 */ u32* stackEnd; - /* 0x30C */ s32 error; - /* 0x310 */ void* specific[OS_THREAD_SPECIFIC_MAX]; + 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, + OS_THREAD_STATE_MORIBUND = 8 }; -#define OS_PRIORITY_MIN 0 // highest -#define OS_PRIORITY_MAX 31 // lowest -#define OS_PRIORITY_IDLE OS_PRIORITY_MAX - #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 + +OSThread* __OSCurrentThread AT_ADDRESS(OS_BASE_CACHED | 0x00E4); +OSThreadQueue __OSActiveThreadQueue AT_ADDRESS(OS_BASE_CACHED | 0x00DC); +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + +void __OSThreadInit(); void OSInitThreadQueue(OSThreadQueue* queue); -OSThread* OSGetCurrentThread(void); -s32 OSDisableScheduler(void); -s32 OSEnableScheduler(void); +OSThread* OSGetCurrentThread(); +s32 OSDisableScheduler(); +s32 OSEnableScheduler(); +OSPriority __OSGetEffectivePriority(OSThread* thread); +void __OSReschedule(); BOOL OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, OSPriority priority, u16 attr); void OSExitThread(void* val); @@ -89,6 +98,8 @@ void OSSleepThread(OSThreadQueue* queue); void OSWakeupThread(OSThreadQueue* queue); void OSClearStack(u8 val); -#define IsSuspended(suspend) (suspend > 0) - +#ifdef __cplusplus +} #endif + +#endif // _DOLPHIN_OSTHREAD diff --git a/include/dolphin/os/OSTime.h b/include/dolphin/os/OSTime.h index c2e6ad6..957eacb 100644 --- a/include/dolphin/os/OSTime.h +++ b/include/dolphin/os/OSTime.h @@ -34,6 +34,9 @@ typedef u32 OSTick; #define BIAS 0xB2575 -s64 __OSGetSystemTime(void); +OSTime OSGetTime(void); +OSTick OSGetTick(void); +OSTime __OSGetSystemTime(void); +void OSTicksToCalendarTime(OSTime ticks, struct OSCalendarTime* td); #endif diff --git a/include/dolphin/types.h b/include/dolphin/types.h index 0de5f2c..af4150f 100644 --- a/include/dolphin/types.h +++ b/include/dolphin/types.h @@ -10,9 +10,22 @@ typedef unsigned long u32; typedef signed long long int s64; typedef unsigned long long int u64; +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; + +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; + typedef float f32; typedef double f64; +typedef volatile f32 vf32; +typedef volatile f64 vf64; + typedef int BOOL; #define FALSE 0 diff --git a/include/THPPlayer.h b/include/emulator/THPPlayer.h similarity index 98% rename from include/THPPlayer.h rename to include/emulator/THPPlayer.h index 0a1be2a..09fad16 100644 --- a/include/THPPlayer.h +++ b/include/emulator/THPPlayer.h @@ -2,7 +2,7 @@ #define _THPPLAYER_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" typedef struct __anon_0x10576 { /* 0x00 */ char magic[4]; diff --git a/include/THPRead.h b/include/emulator/THPRead.h similarity index 100% rename from include/THPRead.h rename to include/emulator/THPRead.h diff --git a/include/THPRead_jumptables.h b/include/emulator/THPRead_jumptables.h similarity index 100% rename from include/THPRead_jumptables.h rename to include/emulator/THPRead_jumptables.h diff --git a/include/_buildtev.h b/include/emulator/_buildtev.h similarity index 100% rename from include/_buildtev.h rename to include/emulator/_buildtev.h diff --git a/include/audio.h b/include/emulator/audio.h similarity index 96% rename from include/audio.h rename to include/emulator/audio.h index f546f5d..f598db6 100644 --- a/include/audio.h +++ b/include/emulator/audio.h @@ -2,7 +2,7 @@ #define _AUDIO_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x753E7 typedef struct Audio { diff --git a/include/codeGCN.h b/include/emulator/codeGCN.h similarity index 88% rename from include/codeGCN.h rename to include/emulator/codeGCN.h index d2440d8..dbb9088 100644 --- a/include/codeGCN.h +++ b/include/emulator/codeGCN.h @@ -2,7 +2,7 @@ #define _CODEGCN_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x57A1 typedef struct Code { diff --git a/include/cpu.h b/include/emulator/cpu.h similarity index 99% rename from include/cpu.h rename to include/emulator/cpu.h index aea13b5..0f67408 100644 --- a/include/cpu.h +++ b/include/emulator/cpu.h @@ -2,7 +2,7 @@ #define _CPU_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // MIPS instruction encoding: // R-type: opcode (6 bits) | rs (5 bits) | rt (5 bits) | rd (5 bits) | sa (5 bits) | funct (6 bits) diff --git a/include/cpu_jumptable.h b/include/emulator/cpu_jumptable.h similarity index 100% rename from include/cpu_jumptable.h rename to include/emulator/cpu_jumptable.h diff --git a/include/disk.h b/include/emulator/disk.h similarity index 88% rename from include/disk.h rename to include/emulator/disk.h index d5eb252..40cbe1e 100644 --- a/include/disk.h +++ b/include/emulator/disk.h @@ -2,7 +2,7 @@ #define _DISK_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x73B29 typedef struct Disk { diff --git a/include/flash.h b/include/emulator/flash.h similarity index 94% rename from include/flash.h rename to include/emulator/flash.h index bab6206..170cbc8 100644 --- a/include/flash.h +++ b/include/emulator/flash.h @@ -2,7 +2,7 @@ #define _FLASH_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x7428F typedef struct Flash { diff --git a/include/frame.h b/include/emulator/frame.h similarity index 99% rename from include/frame.h rename to include/emulator/frame.h index cec11fa..9bdc895 100644 --- a/include/frame.h +++ b/include/emulator/frame.h @@ -2,7 +2,7 @@ #define _FRAME_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x27B8C typedef enum ViewType { diff --git a/include/library.h b/include/emulator/library.h similarity index 97% rename from include/library.h rename to include/emulator/library.h index 624ba00..5304060 100644 --- a/include/library.h +++ b/include/emulator/library.h @@ -1,9 +1,9 @@ #ifndef _LIBRARY_H #define _LIBRARY_H -#include "cpu.h" #include "dolphin.h" -#include "xlObject.h" +#include "emulator/cpu.h" +#include "emulator/xlObject.h" typedef void (*LibraryFuncImpl)(Cpu*); diff --git a/include/library_jumptables.h b/include/emulator/library_jumptables.h similarity index 100% rename from include/library_jumptables.h rename to include/emulator/library_jumptables.h diff --git a/include/mcardGCN.h b/include/emulator/mcardGCN.h similarity index 100% rename from include/mcardGCN.h rename to include/emulator/mcardGCN.h diff --git a/include/mcardGCN_jumptables.h b/include/emulator/mcardGCN_jumptables.h similarity index 100% rename from include/mcardGCN_jumptables.h rename to include/emulator/mcardGCN_jumptables.h diff --git a/include/mips.h b/include/emulator/mips.h similarity index 97% rename from include/mips.h rename to include/emulator/mips.h index 9644245..9bdb539 100644 --- a/include/mips.h +++ b/include/emulator/mips.h @@ -2,7 +2,7 @@ #define _MIPS_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x39384 typedef enum MipsInterruptType { diff --git a/include/movie.h b/include/emulator/movie.h similarity index 100% rename from include/movie.h rename to include/emulator/movie.h diff --git a/include/peripheral.h b/include/emulator/peripheral.h similarity index 95% rename from include/peripheral.h rename to include/emulator/peripheral.h index f333211..f523c20 100644 --- a/include/peripheral.h +++ b/include/emulator/peripheral.h @@ -2,7 +2,7 @@ #define _PERIPHERAL_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x83D15 typedef struct Peripheral { diff --git a/include/pif.h b/include/emulator/pif.h similarity index 96% rename from include/pif.h rename to include/emulator/pif.h index 4a916ca..79dfb79 100644 --- a/include/pif.h +++ b/include/emulator/pif.h @@ -2,7 +2,7 @@ #define _PIF_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x3C277 typedef enum ControllerType { diff --git a/include/ram.h b/include/emulator/ram.h similarity index 92% rename from include/ram.h rename to include/emulator/ram.h index 6bb9514..6c2522e 100644 --- a/include/ram.h +++ b/include/emulator/ram.h @@ -2,7 +2,7 @@ #define _RAM_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x4BFE7 typedef struct Ram { diff --git a/include/rdb.h b/include/emulator/rdb.h similarity index 92% rename from include/rdb.h rename to include/emulator/rdb.h index ef0290c..d972b4d 100644 --- a/include/rdb.h +++ b/include/emulator/rdb.h @@ -2,7 +2,7 @@ #define _RDB_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x56A0F typedef struct Rdb { diff --git a/include/rdp.h b/include/emulator/rdp.h similarity index 94% rename from include/rdp.h rename to include/emulator/rdp.h index d3837e2..028ff4d 100644 --- a/include/rdp.h +++ b/include/emulator/rdp.h @@ -2,7 +2,7 @@ #define _RDP_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x52CD0 typedef struct Rdp { diff --git a/include/rdp_jumptables.h b/include/emulator/rdp_jumptables.h similarity index 100% rename from include/rdp_jumptables.h rename to include/emulator/rdp_jumptables.h diff --git a/include/rom.h b/include/emulator/rom.h similarity index 97% rename from include/rom.h rename to include/emulator/rom.h index 12bee32..0db01ad 100644 --- a/include/rom.h +++ b/include/emulator/rom.h @@ -2,8 +2,8 @@ #define _ROM_H #include "dolphin.h" -#include "xlFileGCN.h" -#include "xlObject.h" +#include "emulator/xlFileGCN.h" +#include "emulator/xlObject.h" typedef s32 UnknownCallbackFunc(void); typedef s32 ProgressCallbackFunc(f32 progressPercent); diff --git a/include/rsp.h b/include/emulator/rsp.h similarity index 99% rename from include/rsp.h rename to include/emulator/rsp.h index 224773a..49857e8 100644 --- a/include/rsp.h +++ b/include/emulator/rsp.h @@ -2,7 +2,7 @@ #define _RSP_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" typedef enum __anon_0x581E7 { RUT_NOCODE = -1, diff --git a/include/rsp_jumptables.h b/include/emulator/rsp_jumptables.h similarity index 100% rename from include/rsp_jumptables.h rename to include/emulator/rsp_jumptables.h diff --git a/include/serial.h b/include/emulator/serial.h similarity index 90% rename from include/serial.h rename to include/emulator/serial.h index 7336d0d..4d5c1f1 100644 --- a/include/serial.h +++ b/include/emulator/serial.h @@ -2,7 +2,7 @@ #define _SERIAL_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x78791 typedef struct Serial { diff --git a/include/simGCN.h b/include/emulator/simGCN.h similarity index 99% rename from include/simGCN.h rename to include/emulator/simGCN.h index 9f6e544..2572866 100644 --- a/include/simGCN.h +++ b/include/emulator/simGCN.h @@ -2,7 +2,7 @@ #define _SIMGCN_H #include "dolphin.h" -#include "system.h" +#include "emulator/system.h" typedef struct __anon_0xD7D1 { /* 0x00 */ u16 height; diff --git a/include/soundGCN.h b/include/emulator/soundGCN.h similarity index 97% rename from include/soundGCN.h rename to include/emulator/soundGCN.h index c485283..858066b 100644 --- a/include/soundGCN.h +++ b/include/emulator/soundGCN.h @@ -2,7 +2,7 @@ #define _SOUNDGCN_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x20C8D typedef enum SoundBeep { diff --git a/include/sram.h b/include/emulator/sram.h similarity index 88% rename from include/sram.h rename to include/emulator/sram.h index e83e3d3..c477869 100644 --- a/include/sram.h +++ b/include/emulator/sram.h @@ -2,7 +2,7 @@ #define _SRAM_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x74AB9 typedef struct Sram { diff --git a/include/system.h b/include/emulator/system.h similarity index 98% rename from include/system.h rename to include/emulator/system.h index 33b0557..8a9f2fc 100644 --- a/include/system.h +++ b/include/emulator/system.h @@ -1,10 +1,10 @@ #ifndef _SYSTEM_H #define _SYSTEM_H -#include "cpu.h" #include "dolphin.h" -#include "mips.h" -#include "xlObject.h" +#include "emulator/cpu.h" +#include "emulator/mips.h" +#include "emulator/xlObject.h" #define N64_BTN_A (1 << 31) #define N64_BTN_B (1 << 30) diff --git a/include/video.h b/include/emulator/video.h similarity index 97% rename from include/video.h rename to include/emulator/video.h index bd02ec1..69fff86 100644 --- a/include/video.h +++ b/include/emulator/video.h @@ -2,7 +2,7 @@ #define _VIDEO_H #include "dolphin.h" -#include "xlObject.h" +#include "emulator/xlObject.h" // __anon_0x75B37 typedef struct Video { diff --git a/include/xlCoreGCN.h b/include/emulator/xlCoreGCN.h similarity index 100% rename from include/xlCoreGCN.h rename to include/emulator/xlCoreGCN.h diff --git a/include/xlFileGCN.h b/include/emulator/xlFileGCN.h similarity index 100% rename from include/xlFileGCN.h rename to include/emulator/xlFileGCN.h diff --git a/include/xlHeap.h b/include/emulator/xlHeap.h similarity index 100% rename from include/xlHeap.h rename to include/emulator/xlHeap.h diff --git a/include/xlList.h b/include/emulator/xlList.h similarity index 100% rename from include/xlList.h rename to include/emulator/xlList.h diff --git a/include/xlObject.h b/include/emulator/xlObject.h similarity index 100% rename from include/xlObject.h rename to include/emulator/xlObject.h diff --git a/include/xlPostGCN.h b/include/emulator/xlPostGCN.h similarity index 100% rename from include/xlPostGCN.h rename to include/emulator/xlPostGCN.h diff --git a/include/functions.h b/include/functions.h index eb33d88..6d591a9 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1861,7 +1861,8 @@ /* 800CFC30 local */ // extern void round_decimal(decimal* dec, int new_length); /* 800CFD64 local */ // extern char* longlong2str(long long num, char* buff, print_format format); /* 800D0044 local */ // extern char* long2str(long num, char* buff, print_format format); -/* 800D0268 local */ // extern const char* parse_format(const char* format_string, va_list* arg, print_format* format); +/* 800D0268 local */ // extern const char* parse_format(const char* format_string, va_list* arg, print_format* + // format); // ======================= scanf.c ==================================================== /* 800D0740 global */ extern int __StringRead(void* isc, int ch, int Action); // ======================= string.c =================================================== diff --git a/include/macros.h b/include/macros.h index af94360..36ef6f6 100644 --- a/include/macros.h +++ b/include/macros.h @@ -24,4 +24,22 @@ inline void padStack(void) { s32 pad = 0; } #define PAD_STACK() padStack() +#ifdef __MWERKS__ +#define ASM asm +#else +#define ASM +#endif + +#ifdef __MWERKS__ +#define WEAK __declspec(weak) +#else +#define WEAK +#endif + +#ifdef __MWERKS__ +#define INIT __declspec(section ".init") +#else +#define INIT +#endif + #endif diff --git a/include/math.h b/include/math.h deleted file mode 100644 index 0bdbf66..0000000 --- a/include/math.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _MATH_H -#define _MATH_H - -#include "dolphin.h" - -extern u32 __float_nan[]; -extern u32 __float_huge[]; - -#define NAN (*(f32*)__float_nan) -#define INFINITY (*(f32*)__float_huge) - -#define M_PI 3.14159265358979323846 - -f64 floor(f64); -f64 ceil(f64); - -inline f64 fabs(f64 x) { return __fabs(x); } - -inline f64 sqrt(f64 x) { - if (x > 0.0) { - f64 guess = __frsqrte(x); - guess = 0.5 * guess * (3.0 - guess * guess * x); - guess = 0.5 * guess * (3.0 - guess * guess * x); - guess = 0.5 * guess * (3.0 - guess * guess * x); - guess = 0.5 * guess * (3.0 - guess * guess * x); - return x * guess; - } else if (x == 0.0) { - return 0.0; - } else if (x) { - return NAN; - } - - return INFINITY; -} - -f32 cosf(f32); -f32 sinf(f32); - -#endif diff --git a/libc/ansi_files.h b/libc/ansi_files.h new file mode 100644 index 0000000..d0d7333 --- /dev/null +++ b/libc/ansi_files.h @@ -0,0 +1,30 @@ +#ifndef _DOLPHIN_ANSI_FILES_H +#define _DOLPHIN_ANSI_FILES_H +#include "stdio.h" + +#ifdef __cplusplus +extern "C" { +#endif // ifdef __cplusplus + +#define set_eof(file) \ + do { \ + (file)->state.io_state = __neutral; \ + (file)->state.eof = 1; \ + (file)->buffer_len = 0; \ + } while (0) + +#define set_error(file) \ + do { \ + (file)->state.error = 1; \ + (file)->buffer_len = 0; \ + } while (0) + +int __flush_buffer(FILE* file, size_t* length); +void __prep_buffer(FILE* file); +int __flush_all(); + +#ifdef __cplusplus +}; +#endif // ifdef __cplusplus + +#endif diff --git a/libc/assert.h b/libc/assert.h new file mode 100644 index 0000000..32ec1dc --- /dev/null +++ b/libc/assert.h @@ -0,0 +1,20 @@ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if __STDC_VERSION__ >= 201112L +// The C11 way +#define static_assert(cond, msg) _Static_assert(cond, #msg) +#else +// The old, hacky way +#define static_assert(cond, msg) typedef char static_assertion_##msg[(cond) ? 1 : -1] +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/buffer_io.h b/libc/buffer_io.h new file mode 100644 index 0000000..764097d --- /dev/null +++ b/libc/buffer_io.h @@ -0,0 +1,14 @@ +#ifndef _BUFFER_IO +#define _BUFFER_IO + +#include "stdio.h" + +enum { __align_buffer, __dont_align_buffer }; + +void __convert_from_newlines(unsigned char* p, size_t* n); +void __convert_to_newlines(unsigned char* p, size_t* n); +void __prep_buffer(FILE*); +int __load_buffer(FILE*, size_t* bytes_loaded, int alignment); +int __flush_buffer(FILE*, size_t* bytes_flushed); + +#endif // _BUFFER_IO diff --git a/libc/console_io.h b/libc/console_io.h new file mode 100644 index 0000000..2399e98 --- /dev/null +++ b/libc/console_io.h @@ -0,0 +1,17 @@ +#ifndef _CONSOLE_IO +#define _CONSOLE_IO + +#include "stddef.h" +#include "file_struc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int __write_console(__file_handle handle, unsigned char * buffer, size_t * count, __idle_proc idle_proc); + +#ifdef __cplusplus +} +#endif + +#endif // _CONSOLE_IO diff --git a/libc/ctype.h b/libc/ctype.h new file mode 100644 index 0000000..b8f6067 --- /dev/null +++ b/libc/ctype.h @@ -0,0 +1,69 @@ +#ifndef _CTYPE_H_ +#define _CTYPE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// eof.h +#define EOF -1L + +extern unsigned char __ctype_map[]; +extern unsigned char __lower_map[]; +extern unsigned char __upper_map[]; + +#define __control_char 0x01 +#define __motion_char 0x02 +#define __space_char 0x04 +#define __punctuation 0x08 +#define __digit 0x10 +#define __hex_digit 0x20 +#define __lower_case 0x40 +#define __upper_case 0x80 + +#define __letter (__lower_case | __upper_case) +#define __alphanumeric (__letter | __digit) +#define __graphic (__alphanumeric | __punctuation) +#define __printable (__graphic | __space_char) +#define __whitespace (__motion_char | __space_char) +#define __control (__motion_char | __control_char) +#define __zero_fill(c) ((int)(unsigned char)(c)) + +#ifndef _CTYPE_INLINE +#define _CTYPE_INLINE static inline +#endif + +_CTYPE_INLINE +int isalnum(int c) { return __ctype_map[__zero_fill(c)] & __alphanumeric; } +_CTYPE_INLINE +int isalpha(int c) { return __ctype_map[__zero_fill(c)] & __letter; } +_CTYPE_INLINE +int iscntrl(int c) { return __ctype_map[__zero_fill(c)] & __control; } +_CTYPE_INLINE +int isdigit(int c) { return __ctype_map[__zero_fill(c)] & __digit; } +_CTYPE_INLINE +int isgraph(int c) { return __ctype_map[__zero_fill(c)] & __graphic; } +_CTYPE_INLINE +int islower(int c) { return __ctype_map[__zero_fill(c)] & __lower_case; } +_CTYPE_INLINE +int isprint(int c) { return __ctype_map[__zero_fill(c)] & __printable; } +_CTYPE_INLINE +int ispunct(int c) { return __ctype_map[__zero_fill(c)] & __punctuation; } +_CTYPE_INLINE +int isspace(int c) { return __ctype_map[__zero_fill(c)] & __whitespace; } +_CTYPE_INLINE +int isupper(int c) { return __ctype_map[__zero_fill(c)] & __upper_case; } +_CTYPE_INLINE +int isxdigit(int c) { return __ctype_map[__zero_fill(c)] & __hex_digit; } +_CTYPE_INLINE +int tolower(int c) { return ((c == EOF) ? EOF : ((int)__lower_map[__zero_fill(c)])); } +_CTYPE_INLINE +int toupper(int c) { return ((c == EOF) ? EOF : ((int)__upper_map[__zero_fill(c)])); } +_CTYPE_INLINE +int iswblank(int c) { return ((c == (int)L' ') || (c == (int)L'\t')); } + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/errno.h b/libc/errno.h new file mode 100644 index 0000000..f06a661 --- /dev/null +++ b/libc/errno.h @@ -0,0 +1,21 @@ +#ifndef _ERRNO_H_ +#define _ERRNO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int errno; + +#define ENOERR 0 +#define EDOM 33 +#define ERANGE 34 +#define ESIGPARM 36 +#define EFPOS 40 +#define EILSEQ 84 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/file_struc.h b/libc/file_struc.h new file mode 100644 index 0000000..d3ccf8f --- /dev/null +++ b/libc/file_struc.h @@ -0,0 +1,22 @@ +#ifndef _FILE_STRUC +#define _FILE_STRUC + +#include "stddef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long __file_handle; +typedef unsigned long fpos_t; + +typedef void (*__idle_proc)(void); +typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc); +typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count, + __idle_proc idle_proc); +typedef int (*__close_proc)(__file_handle file); + +#ifdef __cplusplus +} +#endif +#endif // _FILE_STRUC diff --git a/libc/float.h b/libc/float.h new file mode 100644 index 0000000..ee8b96b --- /dev/null +++ b/libc/float.h @@ -0,0 +1,18 @@ +#ifndef _FLOAT_H_ +#define _FLOAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define FLT_MAX 3.402823466e+38f +#define FLT_EPSILON 1.192092896e-07f +#define FLT_MIN 1.175494351e-38f + +#define DBL_EPSILON 1.1920929e-07 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/limits.h b/libc/limits.h new file mode 100644 index 0000000..e4bb310 --- /dev/null +++ b/libc/limits.h @@ -0,0 +1,24 @@ +#ifndef _LIMITS_H_ +#define _LIMITS_H_ + +#define SCHAR_MAX 0x7f +#define UCHAR_MAX 0xffU + +#if defined(__MWERKS__) && __option(unsigned_char) +#define CHAR_MIN 0U +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MAX 0x7fff +#define USHRT_MAX 0xffffU + +#define INT_MAX 0x7fffffff +#define UINT_MAX 0xffffffffU + +#define LONG_MAX 0x7fffffffL +#define ULONG_MAX 0xffffffffUL + +#endif diff --git a/libc/locale.h b/libc/locale.h new file mode 100644 index 0000000..ba79c67 --- /dev/null +++ b/libc/locale.h @@ -0,0 +1,39 @@ +#ifndef _LOCALE_H_ +#define _LOCALE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct lconv { + char* decimal_point; + char* thousands_sep; + char* grouping; + char* mon_decimal_point; + char* mon_thousands_sep; + char* mon_grouping; + char* positive_sign; + char* negative_sign; + char* currency_symbol; + char frac_digits; + char p_cs_precedes; + char n_cs_precedes; + char p_sep_by_space; + char n_sep_by_space; + char p_sign_posn; + char n_sign_posn; + char* int_curr_symbol; + char int_frac_digits; + char int_p_cs_precedes; + char int_n_cs_precedes; + char int_p_sep_by_space; + char int_n_sep_by_space; + char int_p_sign_posn; + char int_n_sign_posn; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/math.h b/libc/math.h new file mode 100644 index 0000000..ea4bcc2 --- /dev/null +++ b/libc/math.h @@ -0,0 +1,218 @@ +#ifndef _MATH_H_ +#define _MATH_H_ + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _MATH_INLINE +#define _MATH_INLINE static inline +#endif + +#ifdef __MWERKS__ + +/* Metrowerks */ +#if __option(little_endian) +#define __IEEE_LITTLE_ENDIAN +#else +#define __IEEE_BIG_ENDIAN +#endif + +#else + +/* GCC */ +#ifdef __BIG_ENDIAN__ +#define __IEEE_BIG_ENDIAN +#endif +#ifdef __LITTLE_ENDIAN__ +#define __IEEE_LITTLE_ENDIAN +#endif + +#endif + +#ifndef __IEEE_BIG_ENDIAN +#ifndef __IEEE_LITTLE_ENDIAN +#error Must define endianness +#endif +#endif + +#ifndef _INT32 +typedef int _INT32; +typedef unsigned int _UINT32; +#endif + +int abs(int n); +#ifdef __MWERKS__ +#define abs(n) __abs(n) +#define labs(n) __labs(n) +static inline double fabs(double x) { return __fabs(x); } +#else +// static inline int abs(int n) { +// int mask = n >> 31; +// return (n + mask) ^ mask; +// } +#endif + +extern _INT32 __float_huge[]; +extern _INT32 __float_nan[]; +extern _INT32 __double_huge[]; +extern _INT32 __extended_huge[]; + +#define HUGE_VAL (*(double*)__double_huge) +#define INFINITY (*(float*)__float_huge) +#define NAN (*(float*)__float_nan) +#define HUGE_VALF (*(float*)__float_huge) +#define HUGE_VALL (*(long double*)__extended_huge) +#define M_PI 3.14159265358979323846 + +double fabs(double x); +double fmod(double x, double m); +double sin(double x); +double cos(double x); +double atan(double x); +double atan2(double y, double x); +double tan(double x); +double ceil(double x); + +_MATH_INLINE float fabsf(float x) { return (float)fabs((double)x); } +_MATH_INLINE float sinf(float x) { return (float)sin((double)x); } +_MATH_INLINE float cosf(float x) { return (float)cos((double)x); } +_MATH_INLINE float atan2f(float y, float x) { return (float)atan2((double)y, (double)x); } +_MATH_INLINE float fmodf(float x, float m) { return (float)fmod((double)x, (double)m); } +float tanf(float x); +double asin(double x); +double acos(double x); +float acosf(float x); +double log(double x); +double exp(double x); + +double ldexp(double x, int exp); + +double copysign(double x, double y); + +double floor(double x); +_MATH_INLINE float floorf(float x) { return floor(x); } + +double fabs(double x); +double pow(double x, double y); +_MATH_INLINE float powf(float __x, float __y) { return pow(__x, __y); } + +#ifdef __MWERKS__ +#pragma cplusplus on +#endif + +#ifdef __IEEE_LITTLE_ENDIAN +#define __HI(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x)) +#define __LO(x) (*(_INT32*)&x) +#define __UHI(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x)) +#define __ULO(x) (*(_UINT32*)&x) +#else +#define __LO(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x)) +#define __HI(x) (*(_INT32*)&x) +#define __ULO(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x)) +#define __UHI(x) (*(_UINT32*)&x) +#endif + +#define FP_NAN 1 +#define FP_INFINITE 2 +#define FP_ZERO 3 +#define FP_NORMAL 4 +#define FP_SUBNORMAL 5 + +static inline int __fpclassifyf(float x) { + switch ((*(_INT32*)&x) & 0x7f800000) { + case 0x7f800000: { + if ((*(_INT32*)&x) & 0x007fffff) + return FP_NAN; + else + return FP_INFINITE; + break; + } + case 0: { + if ((*(_INT32*)&x) & 0x007fffff) + return FP_SUBNORMAL; + else + return FP_ZERO; + break; + } + } + return FP_NORMAL; +} + +static inline int __fpclassifyd(double x) { + switch (__HI(x) & 0x7ff00000) { + case 0x7ff00000: { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return FP_NAN; + else + return FP_INFINITE; + break; + } + case 0: { + if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff)) + return FP_SUBNORMAL; + else + return FP_ZERO; + break; + } + } + return FP_NORMAL; +} + +#define fpclassify(x) \ + (sizeof(x) == sizeof(float) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x))) +#define isnormal(x) (fpclassify(x) == FP_NORMAL) +#define isnan(x) (fpclassify(x) == FP_NAN) +#define isinf(x) (fpclassify(x) == FP_INFINITE) +#define isfinite(x) ((fpclassify(x) > FP_INFINITE)) + +extern inline float sqrtf(float x) { + const double _half = .5; + const double _three = 3.0; + volatile float y; + + if (x > 0.0f) { + double guess = __frsqrte((double)x); /* returns an approximation to */ + guess = _half * guess * (_three - guess * guess * x); /* now have 12 sig bits + */ + guess = _half * guess * (_three - guess * guess * x); /* now have 24 sig bits + */ + guess = _half * guess * (_three - guess * guess * x); /* now have 32 sig bits + */ + y = (float)(x * guess); + return y; + } + return x; +} + +_MATH_INLINE double sqrt(double x) { + if (x > 0.0) { + double guess = __frsqrte(x); /* returns an approximation to */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 8 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 16 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have 32 sig bits */ + guess = .5 * guess * (3.0 - guess * guess * x); /* now have > 53 sig bits */ + return x * guess; + } else if (x == 0.0) { + return 0; + } else if (x) { + return NAN; + } + return INFINITY; +} + +static inline float ldexpf(float x, int exp) { return (float)ldexp((double)x, exp); } +static inline double scalbn(double x, int n) { return ldexp(x, n); } +static inline float scalbnf(float x, int n) { return (float)ldexpf(x, n); } + +#ifdef __MWERKS__ +#pragma cplusplus reset +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/mem_funcs.h b/libc/mem_funcs.h new file mode 100644 index 0000000..92f19d4 --- /dev/null +++ b/libc/mem_funcs.h @@ -0,0 +1,22 @@ +#ifndef _MEM_FUNCS_H_ +#define _MEM_FUNCS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define __min_bytes_for_long_copy 32 + +void __copy_mem(void* dst, const void* src, unsigned long n); +void __move_mem(void* dst, const void* src, unsigned long n); +void __copy_longs_aligned(void* dst, const void* src, unsigned long n); +void __copy_longs_rev_aligned(void* dst, const void* src, unsigned long n); +void __copy_longs_unaligned(void* dst, const void* src, unsigned long n); +void __copy_longs_rev_unaligned(void* dst, const void* src, unsigned long n); +void __fill_mem(void* dst, int val, unsigned long n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/stdarg.h b/libc/stdarg.h new file mode 100644 index 0000000..8834b29 --- /dev/null +++ b/libc/stdarg.h @@ -0,0 +1,39 @@ +#ifndef _STDARG_H_ +#define _STDARG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MWERKS__ +typedef struct { + char gpr; + char fpr; + char reserved[2]; + char* input_arg_area; + char* reg_save_area; +} __va_list[1]; +typedef __va_list va_list; + +#ifndef __MWERKS__ +extern void __builtin_va_info(va_list*); +#endif + +void* __va_arg(va_list v_list, unsigned char type); + +#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap)) +#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t)))) +#define va_end(ap) (void)0 + +#else +typedef __builtin_va_list va_list; +#define va_start(v, l) __builtin_va_start(v, l) +#define va_end(v) __builtin_va_end(v) +#define va_arg(v, l) __builtin_va_arg(v, l) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/stddef.h b/libc/stddef.h new file mode 100644 index 0000000..d6b4a8d --- /dev/null +++ b/libc/stddef.h @@ -0,0 +1,23 @@ +#ifndef _STDDEF_H_ +#define _STDDEF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define offsetof(type, member) ((size_t) & (((type*)0)->member)) + +/* These break 1.2.5 */ +//typedef __typeof__(sizeof(0)) size_t; +//typedef __typeof__((char*)0 - (char*)0) ptrdiff_t; +typedef unsigned long size_t; +typedef long ptrdiff_t; +#ifndef NULL +#define NULL 0L +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/stdint.h b/libc/stdint.h new file mode 100644 index 0000000..fd88f2e --- /dev/null +++ b/libc/stdint.h @@ -0,0 +1,14 @@ +#ifndef _STDINT_H_ +#define _STDINT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long int uintptr_t; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/stdio.h b/libc/stdio.h new file mode 100644 index 0000000..01f5a1b --- /dev/null +++ b/libc/stdio.h @@ -0,0 +1,135 @@ +#ifndef _STDIO +#define _STDIO + +#include "dolphin/types.h" +#include "libc/stdarg.h" +#include "libc/stddef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +#define __ungetc_buffer_size 2 + +typedef unsigned long __file_handle; +typedef unsigned long fpos_t; +#ifndef __cplusplus +typedef unsigned short wchar_t; +#endif + +enum __io_modes { + __read = 1, + __write = 2, + __read_write = 3, + __append = 4, +}; +enum __file_kinds { + __closed_file, + __disk_file, + __console_file, + __unavailable_file, +}; +enum __file_orientation { + __unoriented, + __char_oriented, + __wide_oriented, +}; + +enum __io_results { + __no_io_error, + __io_error, + __io_EOF, +}; + +typedef struct { + unsigned int open_mode : 2; + unsigned int io_mode : 3; + unsigned int buffer_mode : 2; + unsigned int file_kind : 3; + unsigned int file_orientation : 2; + unsigned int binary_io : 1; +} __file_modes; + +enum __io_states { + __neutral, + __writing, + __reading, + __rereading, +}; + +typedef struct { + unsigned int io_state : 3; + unsigned int free_buffer : 1; + unsigned char eof; + unsigned char error; +} __file_state; + +typedef void (*__idle_proc)(void); +typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __idle_proc idle_proc); +typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count, + __idle_proc idle_proc); +typedef int (*__close_proc)(__file_handle file); + +typedef struct _IO_FILE { + __file_handle handle; + __file_modes mode; + __file_state state; + unsigned char is_dynamically_allocated; + unsigned char char_buffer; + unsigned char char_buffer_overflow; + unsigned char ungetc_buffer[__ungetc_buffer_size]; + wchar_t ungetwc_buffer[__ungetc_buffer_size]; + unsigned long position; + unsigned char* buffer; + unsigned long buffer_size; + unsigned char* buffer_ptr; + unsigned long buffer_len; + unsigned long buffer_alignment; + unsigned long saved_buffer_len; + unsigned long buffer_pos; + __pos_proc position_proc; + __io_proc read_proc; + __io_proc write_proc; + __close_proc close_proc; + __idle_proc idle_proc; + struct _IO_FILE* next_file_struct; +} FILE; + +typedef struct { + char* CharStr; + size_t MaxCharCount; + size_t CharsWritten; +} __OutStrCtrl; + +typedef struct { + char* NextChar; + int NullCharDetected; +} __InStrCtrl; + +#define EOF -1L + +enum __ReadProcActions { __GetChar, __UngetChar, __CheckForError }; + +#define _IONBF 0 +#define _IOLBF 1 +#define _IOFBF 2 + +int puts(const char* s); +int printf(const char*, ...); +size_t sprintf(char* s, const char* format, ...); +size_t vprintf(const char* format, va_list arg); +size_t vsprintf(char* s, const char* format, va_list arg); +size_t fread(const void*, size_t memb_size, size_t num_memb, FILE*); +size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*); +int fseek(FILE* file, long offset, int mode); +size_t __fwrite(const void*, size_t, size_t, FILE*); + +#ifdef __cplusplus +} +#endif + +#endif // _STDIO diff --git a/libc/stdlib.h b/libc/stdlib.h new file mode 100644 index 0000000..616d6a6 --- /dev/null +++ b/libc/stdlib.h @@ -0,0 +1,26 @@ +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include "stddef.h" +#include "wchar.h" + +#define RAND_MAX 32767 + +#ifdef __cplusplus +extern "C" { +#endif + +void srand(unsigned int seed); +int rand(void); +void exit(int status); +size_t wcstombs(char* dest, const wchar_t* src, size_t max); +int atoi(const char* str); + +typedef int (*_compare_function)(const void*, const void*); +void qsort(void*, size_t, size_t, _compare_function); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/string.h b/libc/string.h new file mode 100644 index 0000000..43cc835 --- /dev/null +++ b/libc/string.h @@ -0,0 +1,27 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#include "stddef.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma section code_type ".init" +void* memcpy(void* dst, const void* src, size_t n); +void* memset(void* dst, int val, size_t n); +void __fill_mem(void* dst, int val, size_t n); +#pragma section code_type + +size_t strlen(const char* s); +char* strcpy(char* dest, const char* src); +char* strncpy(char* dest, const char* src, size_t num); +int strcmp(const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +char* strncat(char* dest, const char* src, size_t n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libc/wchar.h b/libc/wchar.h new file mode 100644 index 0000000..a5caca7 --- /dev/null +++ b/libc/wchar.h @@ -0,0 +1,16 @@ +#ifndef _WCHAR_H_ +#define _WCHAR_H_ + +#include "stdio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int fwide(FILE* stream, int mode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/obj_files.mk b/obj_files.mk index 158ad23..1db96bc 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -1,184 +1,184 @@ # Linker order for every file, passed to the Metrowerks linker. -O_FILES := \ - $(BUILD_DIR)/src/xlCoreGCN.o \ - $(BUILD_DIR)/src/xlPostGCN.o \ - $(BUILD_DIR)/src/xlFileGCN.o \ - $(BUILD_DIR)/src/xlList.o \ - $(BUILD_DIR)/src/xlHeap.o \ - $(BUILD_DIR)/src/xlObject.o \ - $(BUILD_DIR)/src/simGCN.o \ - $(BUILD_DIR)/src/movie.o \ - $(BUILD_DIR)/src/THPPlayer.o \ - $(BUILD_DIR)/src/THPAudioDecode.o \ - $(BUILD_DIR)/src/THPDraw.o \ - $(BUILD_DIR)/src/THPRead.o \ - $(BUILD_DIR)/src/THPVideoDecode.o \ - $(BUILD_DIR)/src/mcardGCN.o \ - $(BUILD_DIR)/src/codeGCN.o \ - $(BUILD_DIR)/src/soundGCN.o \ - $(BUILD_DIR)/asm/frame.o \ - $(BUILD_DIR)/src/system.o \ - $(BUILD_DIR)/src/cpu.o \ - $(BUILD_DIR)/src/pif.o \ - $(BUILD_DIR)/src/ram.o \ - $(BUILD_DIR)/src/rom.o \ - $(BUILD_DIR)/src/rdp.o \ - $(BUILD_DIR)/src/rdb.o \ - $(BUILD_DIR)/src/rsp.o \ - $(BUILD_DIR)/src/mips.o \ - $(BUILD_DIR)/src/disk.o \ - $(BUILD_DIR)/src/flash.o \ - $(BUILD_DIR)/src/sram.o \ - $(BUILD_DIR)/src/audio.o \ - $(BUILD_DIR)/src/video.o \ - $(BUILD_DIR)/src/serial.o \ - $(BUILD_DIR)/src/library.o \ - $(BUILD_DIR)/src/peripheral.o \ - $(BUILD_DIR)/src/_frameGCNcc.o \ - $(BUILD_DIR)/src/_buildtev.o \ - $(BUILD_DIR)/asm/PPCArch.o \ - $(BUILD_DIR)/asm/OS.o \ - $(BUILD_DIR)/asm/OSAlarm.o \ - $(BUILD_DIR)/asm/OSAlloc.o \ - $(BUILD_DIR)/asm/OSArena.o \ - $(BUILD_DIR)/asm/OSAudioSystem.o \ - $(BUILD_DIR)/asm/OSCache.o \ - $(BUILD_DIR)/asm/OSContext.o \ - $(BUILD_DIR)/asm/OSError.o \ - $(BUILD_DIR)/asm/OSFont.o \ - $(BUILD_DIR)/asm/OSInterrupt.o \ - $(BUILD_DIR)/asm/OSLink.o \ - $(BUILD_DIR)/asm/OSMessage.o \ - $(BUILD_DIR)/asm/OSMemory.o \ - $(BUILD_DIR)/asm/OSMutex.o \ - $(BUILD_DIR)/asm/OSReboot.o \ - $(BUILD_DIR)/asm/OSReset.o \ - $(BUILD_DIR)/asm/OSResetSW.o \ - $(BUILD_DIR)/asm/OSRtc.o \ - $(BUILD_DIR)/asm/OSSync.o \ - $(BUILD_DIR)/asm/OSThread.o \ - $(BUILD_DIR)/asm/OSTime.o \ - $(BUILD_DIR)/asm/__start.o \ - $(BUILD_DIR)/asm/__ppc_eabi_init.o \ - $(BUILD_DIR)/asm/EXIBios.o \ - $(BUILD_DIR)/asm/EXIUart.o \ - $(BUILD_DIR)/asm/SIBios.o \ - $(BUILD_DIR)/asm/SISamplingRate.o \ - $(BUILD_DIR)/asm/vi.o \ - $(BUILD_DIR)/asm/db.o \ - $(BUILD_DIR)/asm/mtx.o \ - $(BUILD_DIR)/asm/mtxvec.o \ - $(BUILD_DIR)/asm/mtx44.o \ - $(BUILD_DIR)/asm/GXInit.o \ - $(BUILD_DIR)/asm/GXFifo.o \ - $(BUILD_DIR)/asm/GXAttr.o \ - $(BUILD_DIR)/asm/GXMisc.o \ - $(BUILD_DIR)/asm/GXGeometry.o \ - $(BUILD_DIR)/asm/GXFrameBuf.o \ - $(BUILD_DIR)/asm/GXLight.o \ - $(BUILD_DIR)/asm/GXTexture.o \ - $(BUILD_DIR)/asm/GXBump.o \ - $(BUILD_DIR)/asm/GXTev.o \ - $(BUILD_DIR)/asm/GXPixel.o \ - $(BUILD_DIR)/asm/GXTransform.o \ - $(BUILD_DIR)/asm/GXPerf.o \ - $(BUILD_DIR)/asm/Padclamp.o \ - $(BUILD_DIR)/asm/Pad.o \ - $(BUILD_DIR)/asm/dvdlow.o \ - $(BUILD_DIR)/asm/dvdfs.o \ - $(BUILD_DIR)/asm/dvd.o \ - $(BUILD_DIR)/asm/dvdqueue.o \ - $(BUILD_DIR)/asm/dvderror.o \ - $(BUILD_DIR)/asm/dvdidutils.o \ - $(BUILD_DIR)/asm/dvdFatal.o \ - $(BUILD_DIR)/asm/fstload.o \ - $(BUILD_DIR)/asm/DEMOInit.o \ - $(BUILD_DIR)/asm/DEMOPuts.o \ - $(BUILD_DIR)/asm/DEMOFont.o \ - $(BUILD_DIR)/asm/DEMOPad.o \ - $(BUILD_DIR)/asm/DEMOStats.o \ - $(BUILD_DIR)/asm/ai.o \ - $(BUILD_DIR)/asm/ar.o \ - $(BUILD_DIR)/asm/dsp.o \ - $(BUILD_DIR)/asm/dsp_debug.o \ - $(BUILD_DIR)/asm/dsp_task.o \ - $(BUILD_DIR)/asm/CARDBios.o \ - $(BUILD_DIR)/asm/CARDUnlock.o \ - $(BUILD_DIR)/asm/CARDRdwr.o \ - $(BUILD_DIR)/asm/CARDBlock.o \ - $(BUILD_DIR)/asm/CARDDir.o \ - $(BUILD_DIR)/asm/CARDCheck.o \ - $(BUILD_DIR)/asm/CARDMount.o \ - $(BUILD_DIR)/asm/CARDFormat.o \ - $(BUILD_DIR)/asm/CARDOpen.o \ - $(BUILD_DIR)/asm/CARDCreate.o \ - $(BUILD_DIR)/asm/CARDRead.o \ - $(BUILD_DIR)/asm/CARDWrite.o \ - $(BUILD_DIR)/asm/CARDDelete.o \ - $(BUILD_DIR)/asm/CARDStat.o \ - $(BUILD_DIR)/asm/CARDNet.o \ - $(BUILD_DIR)/asm/THPDec.o \ - $(BUILD_DIR)/asm/THPAudio.o \ - $(BUILD_DIR)/asm/texPalette.o \ - $(BUILD_DIR)/asm/mainloop.o \ - $(BUILD_DIR)/asm/nubevent.o \ - $(BUILD_DIR)/asm/nubinit.o \ - $(BUILD_DIR)/asm/msg.o \ - $(BUILD_DIR)/asm/msgbuf.o \ - $(BUILD_DIR)/asm/serpoll.o \ - $(BUILD_DIR)/asm/usr_put.o \ - $(BUILD_DIR)/asm/dispatch.o \ - $(BUILD_DIR)/asm/msghndlr.o \ - $(BUILD_DIR)/asm/support.o \ - $(BUILD_DIR)/asm/mutex_TRK.o \ - $(BUILD_DIR)/asm/notify.o \ - $(BUILD_DIR)/asm/flush_cache.o \ - $(BUILD_DIR)/asm/mem_TRK.o \ - $(BUILD_DIR)/asm/__exception.o \ - $(BUILD_DIR)/asm/targimpl.o \ - $(BUILD_DIR)/asm/dolphin_trk.o \ - $(BUILD_DIR)/asm/mpc_7xx_603e.o \ - $(BUILD_DIR)/asm/main_TRK.o \ - $(BUILD_DIR)/asm/dolphin_trk_glue.o \ - $(BUILD_DIR)/asm/targcont.o \ - $(BUILD_DIR)/asm/__mem.o \ - $(BUILD_DIR)/asm/__va_arg.o \ - $(BUILD_DIR)/asm/global_destructor_chain.o \ - $(BUILD_DIR)/asm/runtime.o \ - $(BUILD_DIR)/asm/abort_exit.o \ - $(BUILD_DIR)/asm/ansi_files.o \ - $(BUILD_DIR)/asm/ansi_fp.o \ - $(BUILD_DIR)/asm/buffer_io.o \ - $(BUILD_DIR)/asm/critical_regions.ppc_eabi.o \ - $(BUILD_DIR)/asm/ctype.o \ - $(BUILD_DIR)/asm/direct_io.o \ - $(BUILD_DIR)/asm/errno.o \ - $(BUILD_DIR)/asm/mbstring.o \ - $(BUILD_DIR)/asm/mem.o \ - $(BUILD_DIR)/asm/mem_funcs.o \ - $(BUILD_DIR)/asm/misc_io.o \ - $(BUILD_DIR)/asm/printf.o \ - $(BUILD_DIR)/asm/scanf.o \ - $(BUILD_DIR)/asm/string.o \ - $(BUILD_DIR)/asm/strtoul.o \ - $(BUILD_DIR)/asm/uart_console_io.o \ - $(BUILD_DIR)/asm/float.o \ - $(BUILD_DIR)/asm/wchar_io.o \ - $(BUILD_DIR)/asm/e_asin.o \ - $(BUILD_DIR)/asm/e_pow.o \ - $(BUILD_DIR)/asm/fminmaxdim.o \ - $(BUILD_DIR)/asm/s_ceil.o \ - $(BUILD_DIR)/asm/s_copysign.o \ - $(BUILD_DIR)/asm/s_floor.o \ - $(BUILD_DIR)/asm/s_frexp.o \ - $(BUILD_DIR)/asm/s_ldexp.o \ - $(BUILD_DIR)/asm/w_pow.o \ - $(BUILD_DIR)/asm/hyperbolicsf.o \ - $(BUILD_DIR)/asm/log10f.o \ - $(BUILD_DIR)/asm/trigf.o \ - $(BUILD_DIR)/asm/math_inlines.o \ - $(BUILD_DIR)/asm/common_float_tables.o \ - $(BUILD_DIR)/asm/AmcExi2Stubs.o \ - $(BUILD_DIR)/asm/DebuggerDriver.o \ - $(BUILD_DIR)/asm/odenotstub.o \ +O_FILES := \ + $(BUILD_DIR)/src/emulator/xlCoreGCN.o \ + $(BUILD_DIR)/src/emulator/xlPostGCN.o \ + $(BUILD_DIR)/src/emulator/xlFileGCN.o \ + $(BUILD_DIR)/src/emulator/xlList.o \ + $(BUILD_DIR)/src/emulator/xlHeap.o \ + $(BUILD_DIR)/src/emulator/xlObject.o \ + $(BUILD_DIR)/src/emulator/simGCN.o \ + $(BUILD_DIR)/src/emulator/movie.o \ + $(BUILD_DIR)/src/emulator/THPPlayer.o \ + $(BUILD_DIR)/src/emulator/THPAudioDecode.o \ + $(BUILD_DIR)/src/emulator/THPDraw.o \ + $(BUILD_DIR)/src/emulator/THPRead.o \ + $(BUILD_DIR)/src/emulator/THPVideoDecode.o \ + $(BUILD_DIR)/src/emulator/mcardGCN.o \ + $(BUILD_DIR)/src/emulator/codeGCN.o \ + $(BUILD_DIR)/src/emulator/soundGCN.o \ + $(BUILD_DIR)/asm/frame.o \ + $(BUILD_DIR)/src/emulator/system.o \ + $(BUILD_DIR)/src/emulator/cpu.o \ + $(BUILD_DIR)/src/emulator/pif.o \ + $(BUILD_DIR)/src/emulator/ram.o \ + $(BUILD_DIR)/src/emulator/rom.o \ + $(BUILD_DIR)/src/emulator/rdp.o \ + $(BUILD_DIR)/src/emulator/rdb.o \ + $(BUILD_DIR)/src/emulator/rsp.o \ + $(BUILD_DIR)/src/emulator/mips.o \ + $(BUILD_DIR)/src/emulator/disk.o \ + $(BUILD_DIR)/src/emulator/flash.o \ + $(BUILD_DIR)/src/emulator/sram.o \ + $(BUILD_DIR)/src/emulator/audio.o \ + $(BUILD_DIR)/src/emulator/video.o \ + $(BUILD_DIR)/src/emulator/serial.o \ + $(BUILD_DIR)/src/emulator/library.o \ + $(BUILD_DIR)/src/emulator/peripheral.o \ + $(BUILD_DIR)/src/emulator/_frameGCNcc.o \ + $(BUILD_DIR)/src/emulator/_buildtev.o \ + $(BUILD_DIR)/src/dolphin/base/PPCArch.o \ + $(BUILD_DIR)/src/dolphin/os/OS.o \ + $(BUILD_DIR)/src/dolphin/os/OSAlarm.o \ + $(BUILD_DIR)/src/dolphin/os/OSAlloc.o \ + $(BUILD_DIR)/src/dolphin/os/OSArena.o \ + $(BUILD_DIR)/src/dolphin/os/OSAudioSystem.o \ + $(BUILD_DIR)/src/dolphin/os/OSCache.o \ + $(BUILD_DIR)/src/dolphin/os/OSContext.o \ + $(BUILD_DIR)/src/dolphin/os/OSError.o \ + $(BUILD_DIR)/src/dolphin/os/OSFont.o \ + $(BUILD_DIR)/src/dolphin/os/OSInterrupt.o \ + $(BUILD_DIR)/src/dolphin/os/OSLink.o \ + $(BUILD_DIR)/src/dolphin/os/OSMessage.o \ + $(BUILD_DIR)/src/dolphin/os/OSMemory.o \ + $(BUILD_DIR)/src/dolphin/os/OSMutex.o \ + $(BUILD_DIR)/src/dolphin/os/OSReboot.o \ + $(BUILD_DIR)/src/dolphin/os/OSReset.o \ + $(BUILD_DIR)/src/dolphin/os/OSResetSW.o \ + $(BUILD_DIR)/src/dolphin/os/OSRtc.o \ + $(BUILD_DIR)/src/dolphin/os/OSSync.o \ + $(BUILD_DIR)/src/dolphin/os/OSThread.o \ + $(BUILD_DIR)/src/dolphin/os/OSTime.o \ + $(BUILD_DIR)/src/dolphin/os/__start.o \ + $(BUILD_DIR)/src/dolphin/os/__ppc_eabi_init.o \ + $(BUILD_DIR)/asm/EXIBios.o \ + $(BUILD_DIR)/asm/EXIUart.o \ + $(BUILD_DIR)/asm/SIBios.o \ + $(BUILD_DIR)/asm/SISamplingRate.o \ + $(BUILD_DIR)/asm/vi.o \ + $(BUILD_DIR)/asm/db.o \ + $(BUILD_DIR)/asm/mtx.o \ + $(BUILD_DIR)/asm/mtxvec.o \ + $(BUILD_DIR)/asm/mtx44.o \ + $(BUILD_DIR)/asm/GXInit.o \ + $(BUILD_DIR)/asm/GXFifo.o \ + $(BUILD_DIR)/asm/GXAttr.o \ + $(BUILD_DIR)/asm/GXMisc.o \ + $(BUILD_DIR)/asm/GXGeometry.o \ + $(BUILD_DIR)/asm/GXFrameBuf.o \ + $(BUILD_DIR)/asm/GXLight.o \ + $(BUILD_DIR)/asm/GXTexture.o \ + $(BUILD_DIR)/asm/GXBump.o \ + $(BUILD_DIR)/asm/GXTev.o \ + $(BUILD_DIR)/asm/GXPixel.o \ + $(BUILD_DIR)/asm/GXTransform.o \ + $(BUILD_DIR)/asm/GXPerf.o \ + $(BUILD_DIR)/asm/Padclamp.o \ + $(BUILD_DIR)/asm/Pad.o \ + $(BUILD_DIR)/asm/dvdlow.o \ + $(BUILD_DIR)/asm/dvdfs.o \ + $(BUILD_DIR)/asm/dvd.o \ + $(BUILD_DIR)/asm/dvdqueue.o \ + $(BUILD_DIR)/asm/dvderror.o \ + $(BUILD_DIR)/asm/dvdidutils.o \ + $(BUILD_DIR)/asm/dvdFatal.o \ + $(BUILD_DIR)/asm/fstload.o \ + $(BUILD_DIR)/asm/DEMOInit.o \ + $(BUILD_DIR)/asm/DEMOPuts.o \ + $(BUILD_DIR)/asm/DEMOFont.o \ + $(BUILD_DIR)/asm/DEMOPad.o \ + $(BUILD_DIR)/asm/DEMOStats.o \ + $(BUILD_DIR)/asm/ai.o \ + $(BUILD_DIR)/asm/ar.o \ + $(BUILD_DIR)/asm/dsp.o \ + $(BUILD_DIR)/asm/dsp_debug.o \ + $(BUILD_DIR)/asm/dsp_task.o \ + $(BUILD_DIR)/asm/CARDBios.o \ + $(BUILD_DIR)/asm/CARDUnlock.o \ + $(BUILD_DIR)/asm/CARDRdwr.o \ + $(BUILD_DIR)/asm/CARDBlock.o \ + $(BUILD_DIR)/asm/CARDDir.o \ + $(BUILD_DIR)/asm/CARDCheck.o \ + $(BUILD_DIR)/asm/CARDMount.o \ + $(BUILD_DIR)/asm/CARDFormat.o \ + $(BUILD_DIR)/asm/CARDOpen.o \ + $(BUILD_DIR)/asm/CARDCreate.o \ + $(BUILD_DIR)/asm/CARDRead.o \ + $(BUILD_DIR)/asm/CARDWrite.o \ + $(BUILD_DIR)/asm/CARDDelete.o \ + $(BUILD_DIR)/asm/CARDStat.o \ + $(BUILD_DIR)/asm/CARDNet.o \ + $(BUILD_DIR)/asm/THPDec.o \ + $(BUILD_DIR)/asm/THPAudio.o \ + $(BUILD_DIR)/asm/texPalette.o \ + $(BUILD_DIR)/asm/mainloop.o \ + $(BUILD_DIR)/asm/nubevent.o \ + $(BUILD_DIR)/asm/nubinit.o \ + $(BUILD_DIR)/asm/msg.o \ + $(BUILD_DIR)/asm/msgbuf.o \ + $(BUILD_DIR)/asm/serpoll.o \ + $(BUILD_DIR)/asm/usr_put.o \ + $(BUILD_DIR)/asm/dispatch.o \ + $(BUILD_DIR)/asm/msghndlr.o \ + $(BUILD_DIR)/asm/support.o \ + $(BUILD_DIR)/asm/mutex_TRK.o \ + $(BUILD_DIR)/asm/notify.o \ + $(BUILD_DIR)/asm/flush_cache.o \ + $(BUILD_DIR)/asm/mem_TRK.o \ + $(BUILD_DIR)/asm/__exception.o \ + $(BUILD_DIR)/asm/targimpl.o \ + $(BUILD_DIR)/asm/dolphin_trk.o \ + $(BUILD_DIR)/asm/mpc_7xx_603e.o \ + $(BUILD_DIR)/asm/main_TRK.o \ + $(BUILD_DIR)/asm/dolphin_trk_glue.o \ + $(BUILD_DIR)/asm/targcont.o \ + $(BUILD_DIR)/asm/__mem.o \ + $(BUILD_DIR)/asm/__va_arg.o \ + $(BUILD_DIR)/asm/global_destructor_chain.o \ + $(BUILD_DIR)/asm/runtime.o \ + $(BUILD_DIR)/asm/abort_exit.o \ + $(BUILD_DIR)/asm/ansi_files.o \ + $(BUILD_DIR)/asm/ansi_fp.o \ + $(BUILD_DIR)/asm/buffer_io.o \ + $(BUILD_DIR)/asm/critical_regions.ppc_eabi.o \ + $(BUILD_DIR)/asm/ctype.o \ + $(BUILD_DIR)/asm/direct_io.o \ + $(BUILD_DIR)/asm/errno.o \ + $(BUILD_DIR)/asm/mbstring.o \ + $(BUILD_DIR)/asm/mem.o \ + $(BUILD_DIR)/asm/mem_funcs.o \ + $(BUILD_DIR)/asm/misc_io.o \ + $(BUILD_DIR)/asm/printf.o \ + $(BUILD_DIR)/asm/scanf.o \ + $(BUILD_DIR)/asm/string.o \ + $(BUILD_DIR)/asm/strtoul.o \ + $(BUILD_DIR)/asm/uart_console_io.o \ + $(BUILD_DIR)/asm/float.o \ + $(BUILD_DIR)/asm/wchar_io.o \ + $(BUILD_DIR)/asm/e_asin.o \ + $(BUILD_DIR)/asm/e_pow.o \ + $(BUILD_DIR)/asm/fminmaxdim.o \ + $(BUILD_DIR)/asm/s_ceil.o \ + $(BUILD_DIR)/asm/s_copysign.o \ + $(BUILD_DIR)/asm/s_floor.o \ + $(BUILD_DIR)/asm/s_frexp.o \ + $(BUILD_DIR)/asm/s_ldexp.o \ + $(BUILD_DIR)/asm/w_pow.o \ + $(BUILD_DIR)/asm/hyperbolicsf.o \ + $(BUILD_DIR)/asm/log10f.o \ + $(BUILD_DIR)/asm/trigf.o \ + $(BUILD_DIR)/asm/math_inlines.o \ + $(BUILD_DIR)/asm/common_float_tables.o \ + $(BUILD_DIR)/asm/AmcExi2Stubs.o \ + $(BUILD_DIR)/asm/DebuggerDriver.o \ + $(BUILD_DIR)/asm/odenotstub.o \ diff --git a/objdiff.json b/objdiff.json index 9171502..d6f99d3 100644 --- a/objdiff.json +++ b/objdiff.json @@ -15,506 +15,828 @@ ], "units": [ { - "name": "xlCoreGCN", - "target_path": "expected/build/SIM/src/xlCoreGCN.o", - "base_path": "build/SIM/src/xlCoreGCN.o", + "name": "emulator/xlCoreGCN", + "target_path": "expected/build/SIM/src/emulator/xlCoreGCN.o", + "base_path": "build/SIM/src/emulator/xlCoreGCN.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlCoreGCN.ctx", + "ctx_path": "build/SIM/src/emulator/xlCoreGCN.ctx", "build_ctx": true } }, { - "name": "xlPostGCN", - "target_path": "expected/build/SIM/src/xlPostGCN.o", - "base_path": "build/SIM/src/xlPostGCN.o", + "name": "emulator/xlPostGCN", + "target_path": "expected/build/SIM/src/emulator/xlPostGCN.o", + "base_path": "build/SIM/src/emulator/xlPostGCN.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlPostGCN.ctx", + "ctx_path": "build/SIM/src/emulator/xlPostGCN.ctx", "build_ctx": true } }, { - "name": "xlFileGCN", - "target_path": "expected/build/SIM/src/xlFileGCN.o", - "base_path": "build/SIM/src/xlFileGCN.o", + "name": "emulator/xlFileGCN", + "target_path": "expected/build/SIM/src/emulator/xlFileGCN.o", + "base_path": "build/SIM/src/emulator/xlFileGCN.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlFileGCN.ctx", + "ctx_path": "build/SIM/src/emulator/xlFileGCN.ctx", "build_ctx": true } }, { - "name": "xlList", - "target_path": "expected/build/SIM/src/xlList.o", - "base_path": "build/SIM/src/xlList.o", + "name": "emulator/xlList", + "target_path": "expected/build/SIM/src/emulator/xlList.o", + "base_path": "build/SIM/src/emulator/xlList.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlList.ctx", + "ctx_path": "build/SIM/src/emulator/xlList.ctx", "build_ctx": true } }, { - "name": "xlHeap", - "target_path": "expected/build/SIM/src/xlHeap.o", - "base_path": "build/SIM/src/xlHeap.o", + "name": "emulator/xlHeap", + "target_path": "expected/build/SIM/src/emulator/xlHeap.o", + "base_path": "build/SIM/src/emulator/xlHeap.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlHeap.ctx", + "ctx_path": "build/SIM/src/emulator/xlHeap.ctx", "build_ctx": true } }, { - "name": "xlObject", - "target_path": "expected/build/SIM/src/xlObject.o", - "base_path": "build/SIM/src/xlObject.o", + "name": "emulator/xlObject", + "target_path": "expected/build/SIM/src/emulator/xlObject.o", + "base_path": "build/SIM/src/emulator/xlObject.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/xlObject.ctx", + "ctx_path": "build/SIM/src/emulator/xlObject.ctx", "build_ctx": true } }, { - "name": "simGCN", - "target_path": "expected/build/SIM/src/simGCN.o", - "base_path": "build/SIM/src/simGCN.o", + "name": "emulator/simGCN", + "target_path": "expected/build/SIM/src/emulator/simGCN.o", + "base_path": "build/SIM/src/emulator/simGCN.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/simGCN.ctx", + "ctx_path": "build/SIM/src/emulator/simGCN.ctx", "build_ctx": true } }, { - "name": "movie", - "target_path": "expected/build/SIM/src/movie.o", - "base_path": "build/SIM/src/movie.o", + "name": "emulator/movie", + "target_path": "expected/build/SIM/src/emulator/movie.o", + "base_path": "build/SIM/src/emulator/movie.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/movie.ctx", + "ctx_path": "build/SIM/src/emulator/movie.ctx", "build_ctx": true } }, { - "name": "THPPlayer", - "target_path": "expected/build/SIM/src/THPPlayer.o", - "base_path": "build/SIM/src/THPPlayer.o", + "name": "emulator/THPPlayer", + "target_path": "expected/build/SIM/src/emulator/THPPlayer.o", + "base_path": "build/SIM/src/emulator/THPPlayer.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/THPPlayer.ctx", + "ctx_path": "build/SIM/src/emulator/THPPlayer.ctx", "build_ctx": true } }, { - "name": "THPAudioDecode", - "target_path": "expected/build/SIM/src/THPAudioDecode.o", - "base_path": "build/SIM/src/THPAudioDecode.o", + "name": "emulator/THPAudioDecode", + "target_path": "expected/build/SIM/src/emulator/THPAudioDecode.o", + "base_path": "build/SIM/src/emulator/THPAudioDecode.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/THPAudioDecode.ctx", + "ctx_path": "build/SIM/src/emulator/THPAudioDecode.ctx", "build_ctx": true } }, { - "name": "THPDraw", - "target_path": "expected/build/SIM/src/THPDraw.o", - "base_path": "build/SIM/src/THPDraw.o", + "name": "emulator/THPDraw", + "target_path": "expected/build/SIM/src/emulator/THPDraw.o", + "base_path": "build/SIM/src/emulator/THPDraw.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/THPDraw.ctx", + "ctx_path": "build/SIM/src/emulator/THPDraw.ctx", "build_ctx": true } }, { - "name": "THPRead", - "target_path": "expected/build/SIM/src/THPRead.o", - "base_path": "build/SIM/src/THPRead.o", + "name": "emulator/THPRead", + "target_path": "expected/build/SIM/src/emulator/THPRead.o", + "base_path": "build/SIM/src/emulator/THPRead.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/THPRead.ctx", + "ctx_path": "build/SIM/src/emulator/THPRead.ctx", "build_ctx": true } }, { - "name": "THPVideoDecode", - "target_path": "expected/build/SIM/src/THPVideoDecode.o", - "base_path": "build/SIM/src/THPVideoDecode.o", + "name": "emulator/THPVideoDecode", + "target_path": "expected/build/SIM/src/emulator/THPVideoDecode.o", + "base_path": "build/SIM/src/emulator/THPVideoDecode.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/THPVideoDecode.ctx", + "ctx_path": "build/SIM/src/emulator/THPVideoDecode.ctx", "build_ctx": true } }, { - "name": "mcardGCN", - "target_path": "expected/build/SIM/src/mcardGCN.o", - "base_path": "build/SIM/src/mcardGCN.o", + "name": "emulator/mcardGCN", + "target_path": "expected/build/SIM/src/emulator/mcardGCN.o", + "base_path": "build/SIM/src/emulator/mcardGCN.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/mcardGCN.ctx", + "ctx_path": "build/SIM/src/emulator/mcardGCN.ctx", "build_ctx": true } }, { - "name": "codeGCN", - "target_path": "expected/build/SIM/src/codeGCN.o", - "base_path": "build/SIM/src/codeGCN.o", + "name": "emulator/codeGCN", + "target_path": "expected/build/SIM/src/emulator/codeGCN.o", + "base_path": "build/SIM/src/emulator/codeGCN.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/codeGCN.ctx", + "ctx_path": "build/SIM/src/emulator/codeGCN.ctx", "build_ctx": true } }, { - "name": "soundGCN", - "target_path": "expected/build/SIM/src/soundGCN.o", - "base_path": "build/SIM/src/soundGCN.o", + "name": "emulator/soundGCN", + "target_path": "expected/build/SIM/src/emulator/soundGCN.o", + "base_path": "build/SIM/src/emulator/soundGCN.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/soundGCN.ctx", + "ctx_path": "build/SIM/src/emulator/soundGCN.ctx", "build_ctx": true } }, { - "name": "frame", - "target_path": "expected/build/SIM/src/frame.o", - "base_path": "build/SIM/src/frame.o", + "name": "emulator/frame", + "target_path": "expected/build/SIM/src/emulator/frame.o", + "base_path": "build/SIM/src/emulator/frame.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/frame.ctx", + "ctx_path": "build/SIM/src/emulator/frame.ctx", "build_ctx": true } }, { - "name": "system", - "target_path": "expected/build/SIM/src/system.o", - "base_path": "build/SIM/src/system.o", + "name": "emulator/system", + "target_path": "expected/build/SIM/src/emulator/system.o", + "base_path": "build/SIM/src/emulator/system.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/system.ctx", + "ctx_path": "build/SIM/src/emulator/system.ctx", "build_ctx": true } }, { - "name": "cpu", - "target_path": "expected/build/SIM/src/cpu.o", - "base_path": "build/SIM/src/cpu.o", + "name": "emulator/cpu", + "target_path": "expected/build/SIM/src/emulator/cpu.o", + "base_path": "build/SIM/src/emulator/cpu.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/cpu.ctx", + "ctx_path": "build/SIM/src/emulator/cpu.ctx", "build_ctx": true } }, { - "name": "pif", - "target_path": "expected/build/SIM/src/pif.o", - "base_path": "build/SIM/src/pif.o", + "name": "emulator/pif", + "target_path": "expected/build/SIM/src/emulator/pif.o", + "base_path": "build/SIM/src/emulator/pif.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/pif.ctx", + "ctx_path": "build/SIM/src/emulator/pif.ctx", "build_ctx": true } }, { - "name": "ram", - "target_path": "expected/build/SIM/src/ram.o", - "base_path": "build/SIM/src/ram.o", + "name": "emulator/ram", + "target_path": "expected/build/SIM/src/emulator/ram.o", + "base_path": "build/SIM/src/emulator/ram.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/ram.ctx", + "ctx_path": "build/SIM/src/emulator/ram.ctx", "build_ctx": true } }, { - "name": "rom", - "target_path": "expected/build/SIM/src/rom.o", - "base_path": "build/SIM/src/rom.o", + "name": "emulator/rom", + "target_path": "expected/build/SIM/src/emulator/rom.o", + "base_path": "build/SIM/src/emulator/rom.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/rom.ctx", + "ctx_path": "build/SIM/src/emulator/rom.ctx", "build_ctx": true } }, { - "name": "rdp", - "target_path": "expected/build/SIM/src/rdp.o", - "base_path": "build/SIM/src/rdp.o", + "name": "emulator/rdp", + "target_path": "expected/build/SIM/src/emulator/rdp.o", + "base_path": "build/SIM/src/emulator/rdp.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/rdp.ctx", + "ctx_path": "build/SIM/src/emulator/rdp.ctx", "build_ctx": true } }, { - "name": "rdb", - "target_path": "expected/build/SIM/src/rdb.o", - "base_path": "build/SIM/src/rdb.o", + "name": "emulator/rdb", + "target_path": "expected/build/SIM/src/emulator/rdb.o", + "base_path": "build/SIM/src/emulator/rdb.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/rdb.ctx", + "ctx_path": "build/SIM/src/emulator/rdb.ctx", "build_ctx": true } }, { - "name": "rsp", - "target_path": "expected/build/SIM/src/rsp.o", - "base_path": "build/SIM/src/rsp.o", + "name": "emulator/rsp", + "target_path": "expected/build/SIM/src/emulator/rsp.o", + "base_path": "build/SIM/src/emulator/rsp.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/rsp.ctx", + "ctx_path": "build/SIM/src/emulator/rsp.ctx", "build_ctx": true } }, { - "name": "mips", - "target_path": "expected/build/SIM/src/mips.o", - "base_path": "build/SIM/src/mips.o", + "name": "emulator/mips", + "target_path": "expected/build/SIM/src/emulator/mips.o", + "base_path": "build/SIM/src/emulator/mips.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/mips.ctx", + "ctx_path": "build/SIM/src/emulator/mips.ctx", "build_ctx": true } }, { - "name": "disk", - "target_path": "expected/build/SIM/src/disk.o", - "base_path": "build/SIM/src/disk.o", + "name": "emulator/disk", + "target_path": "expected/build/SIM/src/emulator/disk.o", + "base_path": "build/SIM/src/emulator/disk.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/disk.ctx", + "ctx_path": "build/SIM/src/emulator/disk.ctx", "build_ctx": true } }, { - "name": "flash", - "target_path": "expected/build/SIM/src/flash.o", - "base_path": "build/SIM/src/flash.o", + "name": "emulator/flash", + "target_path": "expected/build/SIM/src/emulator/flash.o", + "base_path": "build/SIM/src/emulator/flash.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/flash.ctx", + "ctx_path": "build/SIM/src/emulator/flash.ctx", "build_ctx": true } }, { - "name": "sram", - "target_path": "expected/build/SIM/src/sram.o", - "base_path": "build/SIM/src/sram.o", + "name": "emulator/sram", + "target_path": "expected/build/SIM/src/emulator/sram.o", + "base_path": "build/SIM/src/emulator/sram.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/sram.ctx", + "ctx_path": "build/SIM/src/emulator/sram.ctx", "build_ctx": true } }, { - "name": "audio", - "target_path": "expected/build/SIM/src/audio.o", - "base_path": "build/SIM/src/audio.o", + "name": "emulator/audio", + "target_path": "expected/build/SIM/src/emulator/audio.o", + "base_path": "build/SIM/src/emulator/audio.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/audio.ctx", + "ctx_path": "build/SIM/src/emulator/audio.ctx", "build_ctx": true } }, { - "name": "video", - "target_path": "expected/build/SIM/src/video.o", - "base_path": "build/SIM/src/video.o", + "name": "emulator/video", + "target_path": "expected/build/SIM/src/emulator/video.o", + "base_path": "build/SIM/src/emulator/video.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/video.ctx", + "ctx_path": "build/SIM/src/emulator/video.ctx", "build_ctx": true } }, { - "name": "serial", - "target_path": "expected/build/SIM/src/serial.o", - "base_path": "build/SIM/src/serial.o", + "name": "emulator/serial", + "target_path": "expected/build/SIM/src/emulator/serial.o", + "base_path": "build/SIM/src/emulator/serial.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/serial.ctx", + "ctx_path": "build/SIM/src/emulator/serial.ctx", "build_ctx": true } }, { - "name": "library", - "target_path": "expected/build/SIM/src/library.o", - "base_path": "build/SIM/src/library.o", + "name": "emulator/library", + "target_path": "expected/build/SIM/src/emulator/library.o", + "base_path": "build/SIM/src/emulator/library.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/library.ctx", + "ctx_path": "build/SIM/src/emulator/library.ctx", "build_ctx": true } }, { - "name": "peripheral", - "target_path": "expected/build/SIM/src/peripheral.o", - "base_path": "build/SIM/src/peripheral.o", + "name": "emulator/peripheral", + "target_path": "expected/build/SIM/src/emulator/peripheral.o", + "base_path": "build/SIM/src/emulator/peripheral.o", "reverse_fn_order": true, "complete": true, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/peripheral.ctx", + "ctx_path": "build/SIM/src/emulator/peripheral.ctx", "build_ctx": true } }, { - "name": "_frameGCNcc", - "target_path": "expected/build/SIM/src/_frameGCNcc.o", - "base_path": "build/SIM/src/_frameGCNcc.o", + "name": "emulator/_frameGCNcc", + "target_path": "expected/build/SIM/src/emulator/_frameGCNcc.o", + "base_path": "build/SIM/src/emulator/_frameGCNcc.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/_frameGCNcc.ctx", + "ctx_path": "build/SIM/src/emulator/_frameGCNcc.ctx", "build_ctx": true } }, { - "name": "_buildtev", - "target_path": "expected/build/SIM/src/_buildtev.o", - "base_path": "build/SIM/src/_buildtev.o", + "name": "emulator/_buildtev", + "target_path": "expected/build/SIM/src/emulator/_buildtev.o", + "base_path": "build/SIM/src/emulator/_buildtev.o", "reverse_fn_order": true, "complete": false, "scratch": { "platform": "gc_wii", "compiler": "mwcc_233_159", "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=0 -DNDEBUG=1 -msgstyle gcc -inline auto,deferred", - "ctx_path": "build/SIM/src/_buildtev.ctx", + "ctx_path": "build/SIM/src/emulator/_buildtev.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OS", + "target_path": "expected/build/SIM/src/dolphin/os/OS.o", + "base_path": "build/SIM/src/dolphin/os/OS.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OS.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSAlarm", + "target_path": "expected/build/SIM/src/dolphin/os/OSAlarm.o", + "base_path": "build/SIM/src/dolphin/os/OSAlarm.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSAlarm.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSAlloc", + "target_path": "expected/build/SIM/src/dolphin/os/OSAlloc.o", + "base_path": "build/SIM/src/dolphin/os/OSAlloc.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSAlloc.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSArena", + "target_path": "expected/build/SIM/src/dolphin/os/OSArena.o", + "base_path": "build/SIM/src/dolphin/os/OSArena.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSArena.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSAudioSystem", + "target_path": "expected/build/SIM/src/dolphin/os/OSAudioSystem.o", + "base_path": "build/SIM/src/dolphin/os/OSAudioSystem.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSAudioSystem.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSCache", + "target_path": "expected/build/SIM/src/dolphin/os/OSCache.o", + "base_path": "build/SIM/src/dolphin/os/OSCache.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSCache.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSContext", + "target_path": "expected/build/SIM/src/dolphin/os/OSContext.o", + "base_path": "build/SIM/src/dolphin/os/OSContext.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSContext.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSError", + "target_path": "expected/build/SIM/src/dolphin/os/OSError.o", + "base_path": "build/SIM/src/dolphin/os/OSError.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSError.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSFont", + "target_path": "expected/build/SIM/src/dolphin/os/OSFont.o", + "base_path": "build/SIM/src/dolphin/os/OSFont.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSFont.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSInterrupt", + "target_path": "expected/build/SIM/src/dolphin/os/OSInterrupt.o", + "base_path": "build/SIM/src/dolphin/os/OSInterrupt.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSInterrupt.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSLink", + "target_path": "expected/build/SIM/src/dolphin/os/OSLink.o", + "base_path": "build/SIM/src/dolphin/os/OSLink.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSLink.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSMessage", + "target_path": "expected/build/SIM/src/dolphin/os/OSMessage.o", + "base_path": "build/SIM/src/dolphin/os/OSMessage.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSMessage.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSMemory", + "target_path": "expected/build/SIM/src/dolphin/os/OSMemory.o", + "base_path": "build/SIM/src/dolphin/os/OSMemory.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSMemory.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSMutex", + "target_path": "expected/build/SIM/src/dolphin/os/OSMutex.o", + "base_path": "build/SIM/src/dolphin/os/OSMutex.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSMutex.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSReboot", + "target_path": "expected/build/SIM/src/dolphin/os/OSReboot.o", + "base_path": "build/SIM/src/dolphin/os/OSReboot.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSReboot.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSReset", + "target_path": "expected/build/SIM/src/dolphin/os/OSReset.o", + "base_path": "build/SIM/src/dolphin/os/OSReset.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSReset.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSResetSW", + "target_path": "expected/build/SIM/src/dolphin/os/OSResetSW.o", + "base_path": "build/SIM/src/dolphin/os/OSResetSW.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSResetSW.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSRtc", + "target_path": "expected/build/SIM/src/dolphin/os/OSRtc.o", + "base_path": "build/SIM/src/dolphin/os/OSRtc.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSRtc.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSSync", + "target_path": "expected/build/SIM/src/dolphin/os/OSSync.o", + "base_path": "build/SIM/src/dolphin/os/OSSync.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSSync.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSThread", + "target_path": "expected/build/SIM/src/dolphin/os/OSThread.o", + "base_path": "build/SIM/src/dolphin/os/OSThread.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSThread.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/__start", + "target_path": "expected/build/SIM/src/dolphin/os/__start.o", + "base_path": "build/SIM/src/dolphin/os/__start.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/__start.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/OSTime", + "target_path": "expected/build/SIM/src/dolphin/os/OSTime.o", + "base_path": "build/SIM/src/dolphin/os/OSTime.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/OSTime.ctx", + "build_ctx": true + } + }, + { + "name": "dolphin/os/__ppc_eabi_init", + "target_path": "expected/build/SIM/src/dolphin/os/__ppc_eabi_init.o", + "base_path": "build/SIM/src/dolphin/os/__ppc_eabi_init.o", + "reverse_fn_order": false, + "complete": true, + "scratch": { + "platform": "gc_wii", + "compiler": "mwcc_233_163n", + "c_flags": "-lang=c -nodefaults -proc gekko -enum int -fp hardware -Cpp_exceptions off -O4,p -inline auto -fp_contract on -DVERSION=1 -DDOLPHIN_REV=99 -sym on -DDEBUG=1 -align powerpc -pragma \"cats off\" -pragma \"warn_notinlined off\" -maxerrors 1 -nosyspath -RTTI off -str reuse -multibyte", + "ctx_path": "build/SIM/src/dolphin/os/__ppc_eabi_init.ctx", "build_ctx": true } } diff --git a/src/dolphin/base/PPCArch.c b/src/dolphin/base/PPCArch.c new file mode 100644 index 0000000..4750792 --- /dev/null +++ b/src/dolphin/base/PPCArch.c @@ -0,0 +1,193 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/types.h" +#include "macros.h" + +union FpscrUnion { + f64 f; + struct { + u32 fpscr_pad; + u32 fpscr; + } u; +}; + +void PPCMthid0(u32 newHID0); + +ASM u32 PPCMfmsr(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r3 + blr +#endif // clang-format on +} + +ASM void PPCMtmsr(register u32 newMSR){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtmsr newMSR + blr +#endif // clang-format on +} + +ASM u32 PPCMfhid0(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, HID0 + blr +#endif // clang-format on +} + +ASM void PPCMthid0(register u32 newHID0){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr HID0, newHID0 + blr +#endif // clang-format on +} + +ASM u32 PPCMfl2cr(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, L2CR + blr +#endif // clang-format on +} + +ASM void PPCMtl2cr(register u32 newL2cr){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr L2CR, newL2cr + blr +#endif // clang-format on +} + +WEAK ASM void PPCMtdec(register u32 newDec){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtdec newDec + blr +#endif // clang-format on +} + +ASM void PPCSync(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + sc + blr +#endif // clang-format on +} + +// spins infinitely +WEAK ASM void PPCHalt(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + + sync + +_spin: + nop + li r3, 0 + nop + b _spin + + // NEVER REACHED +#endif // clang-format on +} + +#if DOLPHIN_REV == 2003 +ASM void PPCMtmmcr0(register u32 newMmcr0){ +#ifdef __MWERKS__ // clang-format off + mtspr MMCR0, newMmcr0 +#endif // clang-format on +} + +ASM void PPCMtmmcr1(register u32 newMmcr1){ +#ifdef __MWERKS__ // clang-format off + mtspr MMCR1, newMmcr1 +#endif // clang-format on +} + +ASM void PPCMtpmc1(register u32 newPmc1){ +#ifdef __MWERKS__ // clang-format off + mtspr PMC1, newPmc1 +#endif // clang-format on +} + +ASM void PPCMtpmc2(register u32 newPmc2){ +#ifdef __MWERKS__ // clang-format off + mtspr PMC2, newPmc2 +#endif // clang-format on +} + +ASM void PPCMtpmc3(register u32 newPmc3){ +#ifdef __MWERKS__ // clang-format off + mtspr PMC3, newPmc3 +#endif // clang-format on +} + +ASM void PPCMtpmc4(register u32 newPmc4){ +#ifdef __MWERKS__ // clang-format off + mtspr PMC4, newPmc4 +#endif // clang-format on +} +#endif + +u32 PPCMffpscr(void) { + union FpscrUnion m; + + ASM { +#ifdef __MWERKS__ // clang-format off + mffs fp31 + stfd fp31, m.f; +#endif // clang-format on + } + + return m.u.fpscr; +} + +void PPCMtfpscr(register u32 newFPSCR) { + union FpscrUnion m; + + ASM { +#ifdef __MWERKS__ // clang-format off + li r4, 0 + stw r4, m.u.fpscr_pad; + stw newFPSCR, m.u.fpscr + lfd fp31, m.f + mtfsf 0xff, fp31 +#endif // clang-format on + } +} + +ASM u32 PPCMfhid2(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, HID2 + blr +#endif // clang-format on +} + +ASM void PPCMthid2(register u32 newhid2){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr HID2, newhid2 + blr +#endif // clang-format on +} + +ASM void PPCMtwpar(register u32 newwpar) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mtspr WPAR, newwpar + blr +#endif // clang-format on +} + +void PPCDisableSpeculation(void) { PPCMthid0(PPCMfhid0() | HID0_SPD); } + +ASM void PPCSetFpNonIEEEMode(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mtfsb1 4*7+1 + blr +#endif // clang-format on +} diff --git a/src/dolphin/os/OS.c b/src/dolphin/os/OS.c new file mode 100644 index 0000000..3d883cb --- /dev/null +++ b/src/dolphin/os/OS.c @@ -0,0 +1,652 @@ +#include "dolphin/os.h" +#include "dolphin/DVDPriv.h" +#include "dolphin/db.h" +#include "dolphin/os/OSBootInfo.h" +#include "macros.h" + +extern OSTime __OSGetSystemTime(); + +#if DOLPHIN_REV == 2002 +static const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: Sep 5 2002 05:32:39 (0x2301) >>"; +#else +static const char* __OSVersion = "<< Dolphin SDK - OS\trelease build: Jul 23 2003 11:27:16 (0x2301) >>"; +#endif + +extern char _stack_addr[]; +extern char _db_stack_end[]; + +#define OS_BI2_DEBUG_ADDRESS 0x800000F4 +#define DEBUGFLAG_ADDR 0x800030E8 +#define OS_DEBUG_ADDRESS_2 0x800030E9 +#define OS_CURRENTCONTEXT_PADDR 0x00C0 + +extern char* __OSResetSWInterruptHandler[]; + +vu16 __OSDeviceCode AT_ADDRESS(OS_BASE_CACHED | 0x30E6); +static DVDDriveInfo DriveInfo ATTRIBUTE_ALIGN(32); +static DVDCommandBlock DriveBlock; + +static OSBootInfo* BootInfo; +static u32* BI2DebugFlag; +static u32* BI2DebugFlagHolder; +WEAK BOOL __OSIsGcam = FALSE; +static f64 ZeroF; +static f32 ZeroPS[2]; +static BOOL AreWeInitialized = FALSE; +static __OSExceptionHandler* OSExceptionTable; +OSTime __OSStartTime; +BOOL __OSInIPL; + +extern u8 __ArenaHi[]; +extern u8 __ArenaLo[]; +extern u32 __DVDLongFileNameFlag; +extern u32 __PADSpec; + +#define OS_EXCEPTIONTABLE_ADDR 0x3000 +#define OS_DBJUMPPOINT_ADDR 0x60 +// memory locations for important stuff +#define OS_CACHED_REGION_PREFIX 0x8000 +#define OS_BI2_DEBUG_ADDRESS 0x800000F4 +#define OS_BI2_DEBUGFLAG_OFFSET 0xC +#define PAD3_BUTTON_ADDR 0x800030E4 +#define OS_DVD_DEVICECODE 0x800030E6 +#define DEBUGFLAG_ADDR 0x800030E8 +#define OS_DEBUG_ADDRESS_2 0x800030E9 +#define DB_EXCEPTIONRET_OFFSET 0xC +#define DB_EXCEPTIONDEST_OFFSET 0x8 +#define MSR_RI_BIT 0x1E + +void OSDefaultExceptionHandler(__OSException exception, OSContext* context); +extern BOOL __DBIsExceptionMarked(__OSException); +static void OSExceptionInit(void); + +ASM void __OSFPRInit(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + mfmsr r3 + ori r3, r3, 0x2000 + mtmsr r3 + + mfspr r3, 0x398 + rlwinm. r3, r3, 3, 31, 31 + beq SkipPairedSingles + + lis r3, ZeroPS@ha + addi r3, r3, ZeroPS@l + psq_l fp0, 0(r3), 0, 0 + ps_mr fp1, fp0 + ps_mr fp2, fp0 + ps_mr fp3, fp0 + ps_mr fp4, fp0 + ps_mr fp5, fp0 + ps_mr fp6, fp0 + ps_mr fp7, fp0 + ps_mr fp8, fp0 + ps_mr fp9, fp0 + ps_mr fp10, fp0 + ps_mr fp11, fp0 + ps_mr fp12, fp0 + ps_mr fp13, fp0 + ps_mr fp14, fp0 + ps_mr fp15, fp0 + ps_mr fp16, fp0 + ps_mr fp17, fp0 + ps_mr fp18, fp0 + ps_mr fp19, fp0 + ps_mr fp20, fp0 + ps_mr fp21, fp0 + ps_mr fp22, fp0 + ps_mr fp23, fp0 + ps_mr fp24, fp0 + ps_mr fp25, fp0 + ps_mr fp26, fp0 + ps_mr fp27, fp0 + ps_mr fp28, fp0 + ps_mr fp29, fp0 + ps_mr fp30, fp0 + ps_mr fp31, fp0 + +SkipPairedSingles: + lfd fp0, ZeroF + fmr fp1, fp0 + fmr fp2, fp0 + fmr fp3, fp0 + fmr fp4, fp0 + fmr fp5, fp0 + fmr fp6, fp0 + fmr fp7, fp0 + fmr fp8, fp0 + fmr fp9, fp0 + fmr fp10, fp0 + fmr fp11, fp0 + fmr fp12, fp0 + fmr fp13, fp0 + fmr fp14, fp0 + fmr fp15, fp0 + fmr fp16, fp0 + fmr fp17, fp0 + fmr fp18, fp0 + fmr fp19, fp0 + fmr fp20, fp0 + fmr fp21, fp0 + fmr fp22, fp0 + fmr fp23, fp0 + fmr fp24, fp0 + fmr fp25, fp0 + fmr fp26, fp0 + fmr fp27, fp0 + fmr fp28, fp0 + fmr fp29, fp0 + fmr fp30, fp0 + fmr fp31, fp0 + + mtfsf 0xFF, fp0 + + blr +#endif // clang-format on +} + +u32 OSGetConsoleType() { + if (BootInfo == NULL || BootInfo->consoleType == 0) { + return OS_CONSOLE_ARTHUR; + } + return BootInfo->consoleType; +} + +void* __OSSavedRegionStart; +void* __OSSavedRegionEnd; + +extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); + +void ClearArena(void) { + if ((u32)(OSGetResetCode()) != 0x80000000) { + __OSSavedRegionStart = 0U; + __OSSavedRegionEnd = 0U; + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + __OSSavedRegionStart = (void*)BOOT_REGION_START; + __OSSavedRegionEnd = (void*)BOOT_REGION_END; + if (BOOT_REGION_START == 0U) { + memset(OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + + if ((u32)OSGetArenaLo() < (u32)__OSSavedRegionStart) { + if ((u32)OSGetArenaHi() <= (u32)__OSSavedRegionStart) { + memset((u32)OSGetArenaLo(), 0U, (u32)OSGetArenaHi() - (u32)OSGetArenaLo()); + return; + } + memset(OSGetArenaLo(), 0U, (u32)__OSSavedRegionStart - (u32)OSGetArenaLo()); + if ((u32)OSGetArenaHi() > (u32)__OSSavedRegionEnd) { + memset((u32)__OSSavedRegionEnd, 0, (u32)OSGetArenaHi() - (u32)__OSSavedRegionEnd); + } + } +} + +static void InquiryCallback(s32 result, DVDCommandBlock* block) { + switch (block->state) { + case 0: + __OSDeviceCode = (u16)(0x8000 | DriveInfo.deviceCode); + break; + default: + __OSDeviceCode = 1; + break; + } +} + +#if DOLPHIN_REV == 2002 +#define HI_MASK 0xFFFF0000 +#define LO_MASK 0x0000FFFF +#else +#define HI_MASK 0xF0000000 +#define LO_MASK 0x0FFFFFFF +#endif + +void OSInit(void) { + /* + Initializes the Dolphin operating system. + - most of the main operations get farmed out to other functions + - loading debug info and setting up heap bounds largely happen here + - a lot of OS reporting also gets controlled here + */ + // pretty sure this is the min(/max) amount of pointers etc for the stack to match + BI2Debug* DebugInfo; + void* debugArenaLo; + u32 inputConsoleType; + u32 tdev; + + // check if we've already done all this or not + if ((BOOL)AreWeInitialized == FALSE) { // fantastic name + AreWeInitialized = TRUE; // flag to make sure we don't have to do this again + + // SYSTEM // + __OSStartTime = __OSGetSystemTime(); + OSDisableInterrupts(); + +// set some PPC things +#if DOLPHIN_REV == 2003 + PPCMtmmcr0(0); + PPCMtmmcr1(0); + PPCMtpmc1(0); + PPCMtpmc2(0); + PPCMtpmc3(0); + PPCMtpmc4(0); +#endif + PPCDisableSpeculation(); + PPCSetFpNonIEEEMode(); + + // DEBUG // + // load some DVD stuff + BI2DebugFlag = 0; // debug flag from the DVD BI2 header + BootInfo = (OSBootInfo*)OS_BASE_CACHED; // set pointer to BootInfo + + __DVDLongFileNameFlag = (u32)0; // flag to tell us whether we make it through the debug loading + + // time to grab a bunch of debug info from the DVD + // the address for where the BI2 debug info is, is stored at OS_BI2_DEBUG_ADDRESS + DebugInfo = (BI2Debug*)*((u32*)OS_BI2_DEBUG_ADDRESS); + + // if the debug info address exists, grab some debug info + if (DebugInfo != NULL) { + BI2DebugFlag = &DebugInfo->debugFlag; // debug flag from DVD BI2 + __PADSpec = (u32)DebugInfo->padSpec; // some other info from DVD BI2 + *((u8*)DEBUGFLAG_ADDR) = (u8)*BI2DebugFlag; // store flag in mem + *((u8*)OS_DEBUG_ADDRESS_2) = (u8)__PADSpec; // store other info in mem + } else if (BootInfo->arenaHi) { // if the top of the heap is already set + BI2DebugFlagHolder = (u32*)*((u8*)DEBUGFLAG_ADDR); // grab whatever's stored at 0x800030E8 + BI2DebugFlag = (u32*)&BI2DebugFlagHolder; // flag is then address of flag holder + __PADSpec = (u32) * ((u8*)OS_DEBUG_ADDRESS_2); // pad spec is whatever's at 0x800030E9 + } + + __DVDLongFileNameFlag = 1; // we made it through debug! + + // HEAP // + // set up bottom of heap (ArenaLo) + // grab address from BootInfo if it exists, otherwise use default __ArenaLo + OSSetArenaLo((BootInfo->arenaLo == NULL) ? __ArenaLo : BootInfo->arenaLo); + + // if the input arenaLo is null, and debug flag location exists (and flag is < 2), + // set arenaLo to just past the end of the db stack + if ((BootInfo->arenaLo == NULL) && (BI2DebugFlag != 0) && (*BI2DebugFlag < 2)) { +#if DOLPHIN_REV == 2002 + debugArenaLo = (char*)(((u32)_db_stack_end + 0x1f) & ~0x1f); +#else + debugArenaLo = (char*)(((u32)_stack_addr + 0x1f) & ~0x1f); +#endif + OSSetArenaLo(debugArenaLo); + } + + // set up top of heap (ArenaHi) + // grab address from BootInfo if it exists, otherwise use default __ArenaHi + OSSetArenaHi((BootInfo->arenaHi == NULL) ? __ArenaHi : BootInfo->arenaHi); + + // OS INIT AND REPORT // + // initialise a whole bunch of OS stuff + OSExceptionInit(); + __OSInitSystemCall(); + OSInitAlarm(); + __OSModuleInit(); + __OSInterruptInit(); + __OSSetInterruptHandler(__OS_INTERRUPT_PI_RSW, (void*)__OSResetSWInterruptHandler); + __OSContextInit(); + __OSCacheInit(); + EXIInit(); + SIInit(); + __OSInitSram(); + __OSThreadInit(); + __OSInitAudioSystem(); + PPCMthid2(PPCMfhid2() & 0xBFFFFFFF); + if ((BOOL)__OSInIPL == FALSE) { + __OSInitMemoryProtection(); + } + +// begin OS reporting +#if DOLPHIN_REV == 2002 + OSReport("\nDolphin OS $Revision: 58 $.\n"); + OSReport("Kernel built : %s %s\n", "Sep 5 2002", "05:32:39"); +#else + OSReport("\nDolphin OS\n"); + OSReport("Kernel built : %s %s\n", "Jul 23 2003", "11:27:16"); +#endif + OSReport("Console Type : "); + + // this is a function in the same file, but it doesn't seem to match + // inputConsoleType = OSGetConsoleType(); + + // inputConsoleType = (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) ? + // 0x10000002 : BootInfo->consoleType; + if (BootInfo == NULL || (inputConsoleType = BootInfo->consoleType) == 0) { + inputConsoleType = OS_CONSOLE_ARTHUR; // default console type + } else { + inputConsoleType = BootInfo->consoleType; + } + + // work out what console type this corresponds to and report it + // consoleTypeSwitchHi = inputConsoleType & 0xF0000000; + switch (inputConsoleType & HI_MASK) { // check "first" byte + case OS_CONSOLE_RETAIL: + OSReport("Retail %d\n", inputConsoleType); + break; +#if DOLPHIN_REV == 2002 + default: +#else + case OS_CONSOLE_DEVELOPMENT: + case OS_CONSOLE_TDEV: +#endif + switch (inputConsoleType & LO_MASK) { // if "first" byte is 2, check "the rest" + case OS_CONSOLE_EMULATOR: + OSReport("Mac Emulator\n"); + break; + case OS_CONSOLE_PC_EMULATOR: + OSReport("PC Emulator\n"); + break; + case OS_CONSOLE_ARTHUR: + OSReport("EPPC Arthur\n"); + break; + case OS_CONSOLE_MINNOW: + OSReport("EPPC Minnow\n"); + break; + default: + tdev = ((u32)inputConsoleType & LO_MASK); + OSReport("Development HW%d (%08x)\n", tdev - 3, inputConsoleType); + break; + } + break; +#if DOLPHIN_REV == 2003 + default: // if none of the above, just report the info we have + OSReport("%08x\n", inputConsoleType); + break; +#endif + } + + // report memory size + OSReport("Memory %d MB\n", (u32)BootInfo->memorySize >> 0x14U); + // report heap bounds + OSReport("Arena : 0x%x - 0x%x\n", OSGetArenaLo(), OSGetArenaHi()); + // report OS version + OSRegisterVersion(__OSVersion); + + // if location of debug flag exists, and flag is >= 2, enable MetroTRKInterrupts + if (BI2DebugFlag && ((*BI2DebugFlag) >= 2)) { + EnableMetroTRKInterrupts(); + } + + // free up memory and re-enable things + ClearArena(); + OSEnableInterrupts(); + + // check if we can load OS from IPL; if not, grab it from DVD (?) + if ((BOOL)__OSInIPL == FALSE) { + DVDInit(); + if ((BOOL)__OSIsGcam) { + __OSDeviceCode = 0x9000; + return; + } + DCInvalidateRange(&DriveInfo, sizeof(DriveInfo)); + DVDInquiryAsync((char*)&DriveBlock, &DriveInfo, InquiryCallback); + } + } +} +static u32 __OSExceptionLocations[] = { + 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700, 0x00000800, + 0x00000900, 0x00000C00, 0x00000D00, 0x00000F00, 0x00001300, 0x00001400, 0x00001700, +}; + +// dummy entry points to the OS Exception vector +void __OSEVStart(void); +void __OSEVEnd(void); +void __OSEVSetNumber(void); +void __OSExceptionVector(void); + +void __DBVECTOR(void); +void __OSDBINTSTART(void); +void __OSDBINTEND(void); +void __OSDBJUMPSTART(void); +void __OSDBJUMPEND(void); + +#define NOP 0x60000000 + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler); + +static void OSExceptionInit(void) { + __OSException exception; + void* destAddr; + + // These two vars help us change the exception number embedded + // in the exception handler code. + u32* opCodeAddr; + u32 oldOpCode; + + // Address range of the actual code to be copied. + u8* handlerStart; + u32 handlerSize; + + // Install the first level exception vector. + opCodeAddr = (u32*)__OSEVSetNumber; + oldOpCode = *opCodeAddr; + handlerStart = (u8*)__OSEVStart; + handlerSize = (u32)((u8*)__OSEVEnd - (u8*)__OSEVStart); + + // Install the DB integrator, only if we are the first OSInit to be run + destAddr = (void*)OSPhysicalToCached(OS_DBJUMPPOINT_ADDR); + if (*(u32*)destAddr == 0) // Lomem should be zero cleared only once by BS2 + { + DBPrintf("Installing OSDBIntegrator\n"); + memcpy(destAddr, (void*)__OSDBINTSTART, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + DCFlushRangeNoSync(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + __sync(); + ICInvalidateRange(destAddr, (u32)__OSDBINTEND - (u32)__OSDBINTSTART); + } + + // Copy the right vector into the table + for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) { + if (BI2DebugFlag && (*BI2DebugFlag >= 2) && __DBIsExceptionMarked(exception)) { + // this DBPrintf is suspicious. + DBPrintf(">>> OSINIT: exception %d commandeered by TRK\n", exception); + continue; + } + + // Modify the copy of code in text before transferring + // to the exception table. + *opCodeAddr = oldOpCode | exception; + + // Modify opcodes at __DBVECTOR if necessary + if (__DBIsExceptionMarked(exception)) { + DBPrintf(">>> OSINIT: exception %d vectored to debugger\n", exception); + memcpy((void*)__DBVECTOR, (void*)__OSDBJUMPSTART, (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART); + } else { + // make sure the opcodes are still nop + u32* ops = (u32*)__DBVECTOR; + int cb; + + for (cb = 0; cb < (u32)__OSDBJUMPEND - (u32)__OSDBJUMPSTART; cb += sizeof(u32)) { + *ops++ = NOP; + } + } + + // Install the modified handler. + destAddr = (void*)OSPhysicalToCached(__OSExceptionLocations[(u32)exception]); + memcpy(destAddr, handlerStart, handlerSize); + DCFlushRangeNoSync(destAddr, handlerSize); + __sync(); + ICInvalidateRange(destAddr, handlerSize); + } + + // initialize pointer to exception table + OSExceptionTable = OSPhysicalToCached(OS_EXCEPTIONTABLE_ADDR); + + // install default exception handlers + for (exception = 0; exception < __OS_EXCEPTION_MAX; exception++) { + __OSSetExceptionHandler(exception, OSDefaultExceptionHandler); + } + + // restore the old opcode, so that we can re-start an application without + // downloading the text segments + *opCodeAddr = oldOpCode; + + DBPrintf("Exceptions initialized...\n"); +} + +static ASM void __OSDBIntegrator(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc +entry __OSDBINTSTART + li r5, OS_DBINTERFACE_ADDR + mflr r3 + stw r3, DB_EXCEPTIONRET_OFFSET(r5) + lwz r3, DB_EXCEPTIONDEST_OFFSET(r5) + oris r3, r3, OS_CACHED_REGION_PREFIX + mtlr r3 + li r3, 0x30 // MSR_IR | MSR_DR // turn on memory addressing + mtmsr r3 + blr +entry __OSDBINTEND +#endif // clang-format on +} + +static ASM void __OSDBJump(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc +entry __OSDBJUMPSTART + bla OS_DBJUMPPOINT_ADDR +entry __OSDBJUMPEND +#endif // clang-format on +} + +__OSExceptionHandler __OSSetExceptionHandler(__OSException exception, __OSExceptionHandler handler) { + __OSExceptionHandler oldHandler; + oldHandler = OSExceptionTable[exception]; + OSExceptionTable[exception] = handler; + return oldHandler; +} + +__OSExceptionHandler __OSGetExceptionHandler(__OSException exception) { return OSExceptionTable[exception]; } + +static ASM void OSExceptionVector(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + +entry __OSEVStart + // Save r4 into SPRG0 + mtsprg 0, r4 + + // Load current context physical address into r4 + lwz r4, OS_CURRENTCONTEXT_PADDR + + // Save r3 - r5 into the current context + stw r3, OS_CONTEXT_R3(r4) + mfsprg r3, 0 + stw r3, OS_CONTEXT_R4(r4) + stw r5, OS_CONTEXT_R5(r4) + + lhz r3, OS_CONTEXT_STATE(r4) + ori r3, r3, OS_CONTEXT_STATE_EXC + sth r3, OS_CONTEXT_STATE(r4) + + // Save misc registers + mfcr r3 + stw r3, OS_CONTEXT_CR(r4) + mflr r3 + stw r3, OS_CONTEXT_LR(r4) + mfctr r3 + stw r3, OS_CONTEXT_CTR(r4) + mfxer r3 + stw r3, OS_CONTEXT_XER(r4) + mfsrr0 r3 + stw r3, OS_CONTEXT_SRR0(r4) + mfsrr1 r3 + stw r3, OS_CONTEXT_SRR1(r4) + mr r5, r3 + +entry __DBVECTOR + nop + + // Set SRR1[IR|DR] to turn on address + // translation at the next RFI + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + // This lets us change the exception number based on the + // exception we're installing. +entry __OSEVSetNumber + addi r3, 0, 0x0000 + + // Load current context virtual address into r4 + lwz r4, 0xD4 + + // Check non-recoverable interrupt + rlwinm. r5, r5, 0, MSR_RI_BIT, MSR_RI_BIT + bne recoverable + addis r5, 0, OSDefaultExceptionHandler@ha + addi r5, r5, OSDefaultExceptionHandler@l + mtsrr0 r5 + rfi + // NOT REACHED HERE + +recoverable: + // Locate exception handler. + rlwinm r5, r3, 2, 22, 29 // r5 contains exception*4 + lwz r5, OS_EXCEPTIONTABLE_ADDR(r5) + mtsrr0 r5 + + // Final state + // r3 - exception number + // r4 - pointer to context + // r5 - garbage + // srr0 - exception handler + // srr1 - address translation enalbed, not yet recoverable + + rfi + // NOT REACHED HERE + // The handler will restore state + +entry __OSEVEnd + nop +#endif // clang-format on +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar); +ASM void OSDefaultExceptionHandler(register __OSException exception, register OSContext* context) { +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + mfdsisr r5 + mfdar r6 + + stwu r1,-8(r1) + b __OSUnhandledException +#endif // clang-foramt on +} + +void __OSPSInit(void) +{ + PPCMthid2(PPCMfhid2() | 0xA0000000); + ICFlashInvalidate(); + __sync(); + + ASM { +#ifdef __MWERKS__ // clang-format off + li r3, 0 + mtspr GQR0, r3 + #if DOLPHIN_REV == 2003 + mtspr GQR1, r3 + mtspr GQR2, r3 + mtspr GQR3, r3 + mtspr GQR4, r3 + mtspr GQR5, r3 + mtspr GQR6, r3 + mtspr GQR7, r3 + #endif +#endif // clang-format on + } +} + +#define DI_CONFIG_IDX 0x9 +#define DI_CONFIG_CONFIG_MASK 0xFF +u32 __OSGetDIConfig(void) { return (__DIRegs[DI_CONFIG_IDX] & DI_CONFIG_CONFIG_MASK); } + +void OSRegisterVersion(const char* id) { OSReport("%s\n", id); } diff --git a/src/dolphin/os/OSAlarm.c b/src/dolphin/os/OSAlarm.c new file mode 100644 index 0000000..12a78e7 --- /dev/null +++ b/src/dolphin/os/OSAlarm.c @@ -0,0 +1,205 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os/OSPriv.h" +#include "dolphin/os/OSReset.h" +#include "macros.h" + +static struct OSAlarmQueue { + OSAlarm* head; + OSAlarm* tail; +} AlarmQueue; + +static void DecrementerExceptionHandler(__OSException exception, OSContext* context); +static BOOL OnReset(BOOL final); + +#if DOLPHIN_REV == 2003 +static OSResetFunctionInfo ResetFunctionInfo = {OnReset, 0xFFFFFFFF}; +#endif + +void OSInitAlarm(void) { + if (__OSGetExceptionHandler(8) != DecrementerExceptionHandler) { + AlarmQueue.head = AlarmQueue.tail = NULL; + __OSSetExceptionHandler(8, DecrementerExceptionHandler); +#if DOLPHIN_REV == 2003 + OSRegisterResetFunction(&ResetFunctionInfo); +#endif + } +} + +void OSCreateAlarm(OSAlarm* alarm) { + alarm->handler = 0; + alarm->tag = 0; +} + +static inline void SetTimer(OSAlarm* alarm) { + OSTime delta; + + delta = alarm->fire - __OSGetSystemTime(); + if (delta < 0) { + PPCMtdec(0); + } else if (delta < 0x80000000) { + PPCMtdec((u32)delta); + } else { + PPCMtdec(0x7fffffff); + } +} + +static void InsertAlarm(OSAlarm* alarm, OSTime fire, OSAlarmHandler handler) { + OSAlarm* next; + OSAlarm* prev; + + if (0 < alarm->period) { + OSTime time = __OSGetSystemTime(); + + fire = alarm->start; + if (alarm->start < time) { + fire += alarm->period * ((time - alarm->start) / alarm->period + 1); + } + } + + alarm->handler = handler; + alarm->fire = fire; + + for (next = AlarmQueue.head; next; next = next->next) { + if (next->fire <= fire) { + continue; + } + + alarm->prev = next->prev; + next->prev = alarm; + alarm->next = next; + prev = alarm->prev; + if (prev) { + prev->next = alarm; + } else { + AlarmQueue.head = alarm; + SetTimer(alarm); + } + return; + } + alarm->next = 0; + prev = AlarmQueue.tail; + AlarmQueue.tail = alarm; + alarm->prev = prev; + if (prev) { + prev->next = alarm; + } else { + AlarmQueue.head = AlarmQueue.tail = alarm; + SetTimer(alarm); + } +} + +void OSSetAlarm(OSAlarm* alarm, OSTime tick, OSAlarmHandler handler) { + BOOL enabled; + enabled = OSDisableInterrupts(); + alarm->period = 0; + InsertAlarm(alarm, __OSGetSystemTime() + tick, handler); + OSRestoreInterrupts(enabled); +} + +void OSCancelAlarm(OSAlarm* alarm) { + OSAlarm* next; + BOOL enabled; + + enabled = OSDisableInterrupts(); + + if (alarm->handler == 0) { + OSRestoreInterrupts(enabled); + return; + } + + next = alarm->next; + if (next == 0) { + AlarmQueue.tail = alarm->prev; + } else { + next->prev = alarm->prev; + } + if (alarm->prev) { + alarm->prev->next = next; + } else { + AlarmQueue.head = next; + if (next) { + SetTimer(next); + } + } + alarm->handler = 0; + + OSRestoreInterrupts(enabled); +} + +static void DecrementerExceptionCallback(register __OSException exception, register OSContext* context) { + OSAlarm* alarm; + OSAlarm* next; + OSAlarmHandler handler; + OSTime time; + OSContext exceptionContext; + time = __OSGetSystemTime(); + alarm = AlarmQueue.head; + if (alarm == 0) { + OSLoadContext(context); + } + + if (time < alarm->fire) { + SetTimer(alarm); + OSLoadContext(context); + } + + next = alarm->next; + AlarmQueue.head = next; + if (next == 0) { + AlarmQueue.tail = 0; + } else { + next->prev = 0; + } + + handler = alarm->handler; + alarm->handler = 0; + if (0 < alarm->period) { + InsertAlarm(alarm, 0, handler); + } + + if (AlarmQueue.head) { + SetTimer(AlarmQueue.head); + } + + OSDisableScheduler(); + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + handler(alarm, context); + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); +} + +static ASM void DecrementerExceptionHandler(register __OSException exception, register OSContext* context) { +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + stwu r1, -8(r1) + b DecrementerExceptionCallback +#endif // clang-format on +} + +#if DOLPHIN_REV == 2003 +static BOOL OnReset(BOOL final) { + OSAlarm* alarm; + OSAlarm* next; + + if (final) { + alarm = AlarmQueue.head; + next = (alarm) ? alarm->next : NULL; + + while (alarm != NULL) { + if (__DVDTestAlarm(alarm) == FALSE) { + OSCancelAlarm(alarm); + } + + alarm = next; + next = (alarm) ? alarm->next : NULL; + } + } + + return TRUE; +} +#endif diff --git a/src/dolphin/os/OSAlloc.c b/src/dolphin/os/OSAlloc.c new file mode 100644 index 0000000..55fadf5 --- /dev/null +++ b/src/dolphin/os/OSAlloc.c @@ -0,0 +1,254 @@ +#include "dolphin/os.h" +#include "dolphin/types.h" + +typedef struct HeapCell { + struct HeapCell* prev; + struct HeapCell* next; + u32 size; +} HeapCell; + +typedef struct Heap { + s32 size; + struct HeapCell* free; // linked list of free cells + struct HeapCell* allocated; // linked list of allocated cells +} Heap; + +void* ArenaEnd; +void* ArenaStart; +int NumHeaps; +struct Heap* HeapArray; +volatile OSHeapHandle __OSCurrHeap = -1; + +#define InRange(addr, start, end) ((u8*)(start) <= (u8*)(addr) && (u8*)(addr) < (u8*)(end)) +#define OFFSET(addr, align) (((u32)(addr) & ((align)-1))) + +#define ALIGNMENT 32 +#define MINOBJSIZE 64 + +static inline void* DLAddFront(struct HeapCell* neighbor, struct HeapCell* cell) { + cell->next = neighbor; + cell->prev = NULL; + if (neighbor != NULL) + neighbor->prev = cell; + return cell; +} + +static inline HeapCell* DLExtract(struct HeapCell* list, struct HeapCell* cell) { + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + return list; +} + +static HeapCell* DLInsert(HeapCell* list, HeapCell* cell, void* unused /* needed to match OSFreeToHeap */) { + HeapCell* before = NULL; + HeapCell* after = list; + + while (after != NULL) { + if (cell <= after) + break; + before = after; + after = after->next; + } + cell->next = after; + cell->prev = before; + if (after != NULL) { + after->prev = cell; + if ((u8*)cell + cell->size == (u8*)after) { + cell->size += after->size; + after = after->next; + cell->next = after; + if (after != NULL) + after->prev = cell; + } + } + if (before != NULL) { + before->next = cell; + if ((u8*)before + before->size == (u8*)cell) { + before->size += cell->size; + before->next = after; + if (after != NULL) + after->prev = before; + } + return list; + } + return cell; +} + +void* OSAllocFromHeap(OSHeapHandle heap, u32 size) { + struct Heap* hd = &HeapArray[heap]; + s32 sizeAligned = OSRoundUp32B(ALIGNMENT + size); + struct HeapCell* cell; + struct HeapCell* oldTail; + u32 leftoverSpace; + + // find first cell with enough capacity + for (cell = hd->free; cell != NULL; cell = cell->next) { + if (sizeAligned <= (s32)cell->size) + break; + } + if (cell == NULL) + return NULL; + + leftoverSpace = cell->size - sizeAligned; + if (leftoverSpace < MINOBJSIZE) { + // remove this cell from the free list + hd->free = DLExtract(hd->free, cell); + } else { + // remove this cell from the free list and make a new cell out of the + // remaining space + struct HeapCell* newcell = (void*)((u8*)cell + sizeAligned); + cell->size = sizeAligned; + newcell->size = leftoverSpace; + newcell->prev = cell->prev; + newcell->next = cell->next; + if (newcell->next != NULL) + newcell->next->prev = newcell; + if (newcell->prev != NULL) + newcell->prev->next = newcell; + else + hd->free = newcell; + } + + // add the cell to the beginning of the allocated list + hd->allocated = DLAddFront(hd->allocated, cell); + + return (u8*)cell + ALIGNMENT; +} + +void OSFreeToHeap(OSHeapHandle heap, void* ptr) { + HeapCell* cell = (void*)((u8*)ptr - ALIGNMENT); + Heap* hd = &HeapArray[heap]; + HeapCell* list = hd->allocated; + + // remove cell from the allocated list + // hd->allocated = DLExtract(hd->allocated, cell); + if (cell->next != NULL) + cell->next->prev = cell->prev; + if (cell->prev == NULL) + list = cell->next; + else + cell->prev->next = cell->next; + hd->allocated = list; + hd->free = DLInsert(hd->free, cell, list); +} + +OSHeapHandle OSSetCurrentHeap(OSHeapHandle heap) { + OSHeapHandle old = __OSCurrHeap; + + __OSCurrHeap = heap; + return old; +} + +void* OSInitAlloc(void* arenaStart, void* arenaEnd, int maxHeaps) { + u32 totalSize = maxHeaps * sizeof(struct Heap); + int i; + + HeapArray = arenaStart; + NumHeaps = maxHeaps; + + for (i = 0; i < NumHeaps; i++) { + Heap* heap = &HeapArray[i]; + + heap->size = -1; + heap->free = heap->allocated = NULL; + } + + __OSCurrHeap = -1; + + arenaStart = (u8*)HeapArray + totalSize; + arenaStart = (void*)OSRoundUp32B(arenaStart); + + ArenaStart = arenaStart; + ArenaEnd = (void*)OSRoundDown32B(arenaEnd); + + return arenaStart; +} + +OSHeapHandle OSCreateHeap(void* start, void* end) { + int i; + HeapCell* cell = (void*)OSRoundUp32B(start); + + end = (void*)OSRoundDown32B(end); + for (i = 0; i < NumHeaps; i++) { + Heap* hd = &HeapArray[i]; + + if (hd->size < 0) { + hd->size = (u8*)end - (u8*)cell; + cell->prev = NULL; + cell->next = NULL; + cell->size = hd->size; + hd->free = cell; + hd->allocated = NULL; + return i; + } + } + return -1; +} + +#define ASSERTREPORT(line, cond) \ + if (!(cond)) { \ + OSReport("OSCheckHeap: Failed " #cond " in %d", line); \ + return -1; \ + } + +s32 OSCheckHeap(int heap) { + struct Heap* hd; + struct HeapCell* cell; + long total = 0; + long free = 0; + + ASSERTREPORT(0x37D, HeapArray); + ASSERTREPORT(0x37E, 0 <= heap && heap < NumHeaps); + hd = &HeapArray[heap]; + ASSERTREPORT(0x381, 0 <= hd->size); + + ASSERTREPORT(0x383, hd->allocated == NULL || hd->allocated->prev == NULL); + + for (cell = hd->allocated; cell; cell = cell->next) { + ASSERTREPORT(0x386, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(0x387, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(0x388, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(0x389, MINOBJSIZE <= cell->size); + ASSERTREPORT(0x38A, OFFSET(cell->size, ALIGNMENT) == 0); + total += cell->size; + ASSERTREPORT(0x38D, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(0x390, cell->hd == hd); + ASSERTREPORT(0x391, ALIGNMENT + cell->requested <= cell->size); +#endif + } + + ASSERTREPORT(0x395, hd->free == NULL || hd->free->prev == NULL); + + for (cell = hd->free; cell; cell = cell->next) { + ASSERTREPORT(0x398, InRange(cell, ArenaStart, ArenaEnd)); + ASSERTREPORT(0x399, OFFSET(cell, ALIGNMENT) == 0); + ASSERTREPORT(0x39A, cell->next == NULL || cell->next->prev == cell); + ASSERTREPORT(0x39B, MINOBJSIZE <= cell->size); + ASSERTREPORT(0x39C, OFFSET(cell->size, ALIGNMENT) == 0); + // clang-format off + ASSERTREPORT(0x39D, cell->next == NULL || (char*) cell + cell->size < (char*) cell->next); + // clang-format on + total += cell->size; + free = (cell->size + free); + free -= ALIGNMENT; + ASSERTREPORT(0x3A1, 0 < total && total <= hd->size); +#ifdef ENABLE_HEAPDESC + ASSERTREPORT(0x3A4, cell->hd == NULL); +#endif + } + ASSERTREPORT(0x3A8, total == hd->size); + return free; +} + +// OSDumpHeap is unused but the strings from that function are present +char D_800F0B4C[] = "\nOSDumpHeap(%d):\n"; +char D_800F0B60[] = "--------Inactive\n"; +char D_800F0B74[] = "addr\tsize\t\tend\tprev\tnext\n"; +char D_800F0B90[] = "--------Allocated\n"; +char D_800F0BA4[] = "%x\t%d\t%x\t%x\t%x\n"; +char D_800F0BB4[] = "--------Free\n"; diff --git a/src/dolphin/os/OSArena.c b/src/dolphin/os/OSArena.c new file mode 100644 index 0000000..eb6fb7d --- /dev/null +++ b/src/dolphin/os/OSArena.c @@ -0,0 +1,15 @@ +#include "dolphin/os/OSArena.h" + +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) + +void* __OSArenaHi; +void* __OSArenaLo = (void*)-1; + +void* OSGetArenaHi(void) { return __OSArenaHi; } + +void* OSGetArenaLo(void) { return __OSArenaLo; } + +void OSSetArenaHi(void* addr) { __OSArenaHi = addr; } + +void OSSetArenaLo(void* addr) { __OSArenaLo = addr; } diff --git a/src/dolphin/os/OSAudioSystem.c b/src/dolphin/os/OSAudioSystem.c new file mode 100644 index 0000000..ee0124d --- /dev/null +++ b/src/dolphin/os/OSAudioSystem.c @@ -0,0 +1,115 @@ +#include "dolphin/hw_regs.h" +#include "dolphin/types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// clang-format off +static u8 DSPInitCode[128] = { + 0x02, 0x9F, 0x00, 0x10, 0x02, 0x9F, 0x00, 0x33, 0x02, 0x9F, 0x00, 0x34, 0x02, 0x9F, 0x00, 0x35, + 0x02, 0x9F, 0x00, 0x36, 0x02, 0x9F, 0x00, 0x37, 0x02, 0x9F, 0x00, 0x38, 0x02, 0x9F, 0x00, 0x39, + 0x12, 0x06, 0x12, 0x03, 0x12, 0x04, 0x12, 0x05, 0x00, 0x80, 0x80, 0x00, 0x00, 0x88, 0xFF, 0xFF, + 0x00, 0x84, 0x10, 0x00, 0x00, 0x64, 0x00, 0x1D, 0x02, 0x18, 0x00, 0x00, 0x81, 0x00, 0x1C, 0x1E, + 0x00, 0x44, 0x1B, 0x1E, 0x00, 0x84, 0x08, 0x00, 0x00, 0x64, 0x00, 0x27, 0x19, 0x1E, 0x00, 0x00, + 0x00, 0xDE, 0xFF, 0xFC, 0x02, 0xA0, 0x80, 0x00, 0x02, 0x9C, 0x00, 0x28, 0x16, 0xFC, 0x00, 0x54, + 0x16, 0xFD, 0x43, 0x48, 0x00, 0x21, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, 0x02, 0xFF, + 0x02, 0xFF, 0x02, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +// clang-format on + +#define __DSPWorkBuffer (void*)0x81000000 + +void __OSInitAudioSystem(void) { + u32 r28; + u16 r3; + + u32 padding; + + memcpy((void*)((u8*)OSGetArenaHi() - 128), __DSPWorkBuffer, 128); + memcpy(__DSPWorkBuffer, (void*)DSPInitCode, 128); + + DCFlushRange(__DSPWorkBuffer, 128); + + __DSPRegs[9] = 0x43; + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + while (__DSPRegs[5] & 1) + ; + __DSPRegs[0] = 0; + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000) + ; + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + r3 = __DSPRegs[5]; + while (!(r3 & 0x20)) + r3 = __DSPRegs[5]; + __DSPRegs[5] = r3; + + r28 = OSGetTick(); + while ((s32)(OSGetTick() - r28) < 0x892) + ; + + *(u32*)&__DSPRegs[16] = 0x1000000; + *(u32*)&__DSPRegs[18] = 0; + *(u32*)&__DSPRegs[20] = 0x20; + + r3 = __DSPRegs[5]; + while (!(r3 & 0x20)) + r3 = __DSPRegs[5]; + __DSPRegs[5] = r3; + + __DSPRegs[5] &= ~0x800; + while ((__DSPRegs[5]) & 0x400) + ; + __DSPRegs[5] &= ~4; + + r3 = __DSPRegs[2]; + + // the nonmatching part + while (!(r3 & 0x8000)) + r3 = __DSPRegs[2]; + + (void)__DSPRegs[3]; + r3 != 42069; + __DSPRegs[5] |= 4; + __DSPRegs[5] = 0x8AC; + __DSPRegs[5] |= 1; + while (__DSPRegs[5] & 1) + ; + memcpy(__DSPWorkBuffer, (void*)((u8*)OSGetArenaHi() - 128), 128); +} + +void __OSStopAudioSystem(void) { + u32 r28; + +#define waitUntil(load, mask) \ + r28 = (load); \ + while (r28 & (mask)) { \ + r28 = (load); \ + } + + __DSPRegs[5] = 0x804; + r28 = __DSPRegs[27]; + __DSPRegs[27] = r28 & ~0x8000; + waitUntil(__DSPRegs[5], 0x400); + waitUntil(__DSPRegs[5], 0x200); + __DSPRegs[5] = 0x8ac; + __DSPRegs[0] = 0; + + while (((__DSPRegs[2] << 16) | __DSPRegs[3]) & 0x80000000) + ; + r28 = OSGetTick(); + while ((s32)(OSGetTick() - r28) < 0x2c) + ; + __DSPRegs[5] |= 1; + waitUntil(__DSPRegs[5], 0x001); + +#undef waitUntil +} + +#ifdef __cplusplus +} +#endif diff --git a/src/dolphin/os/OSCache.c b/src/dolphin/os/OSCache.c new file mode 100644 index 0000000..d0405c9 --- /dev/null +++ b/src/dolphin/os/OSCache.c @@ -0,0 +1,387 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/db.h" +#include "dolphin/os.h" +#include "macros.h" + +ASM void DCEnable(){ +#ifdef __MWERKS__ // clang-format off + nofralloc + sync + mfspr r3, HID0 + ori r3, r3, 0x4000 + mtspr HID0, r3 + blr +#endif // clang-format on +} + +ASM void DCInvalidateRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbi r0, addr + addi addr, addr, 32 + bdnz @1 + blr +#endif // clang-format on +} + +ASM void DCFlushRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + sc + blr +#endif // clang-format on +} + +ASM void DCStoreRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbst r0, addr + addi addr, addr, 32 + bdnz @1 + sc + + blr +#endif // clang-format on +} + +ASM void DCFlushRangeNoSync(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbf r0, addr + addi addr, addr, 32 + bdnz @1 + blr +#endif // clang-format on +} + +ASM void DCZeroRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + dcbz r0, addr + addi addr, addr, 32 + bdnz @1 + + blr +#endif // clang-format on +} + +ASM void ICInvalidateRange(register void* addr, register u32 nBytes) { +#ifdef __MWERKS__ // clang-format off + nofralloc + cmplwi nBytes, 0 + blelr + clrlwi r5, addr, 27 + add nBytes, nBytes, r5 + addi nBytes, nBytes, 31 + srwi nBytes, nBytes, 5 + mtctr nBytes + +@1 + icbi r0, addr + addi addr, addr, 32 + bdnz @1 + sync + isync + + blr +#endif // clang-format on +} + +ASM void ICFlashInvalidate(){ +#ifdef __MWERKS__ // clang-format off + nofralloc + mfspr r3, HID0 + ori r3, r3, 0x800 + mtspr HID0, r3 + blr +#endif // clang-format on +} + +ASM void ICEnable(){ +#ifdef __MWERKS__ // clang-format off + nofralloc + isync + mfspr r3, HID0 + ori r3, r3, 0x8000 + mtspr HID0, r3 + blr +#endif // clang-format on +} + +#define LC_LINES 512 +#define CACHE_LINES 1024 + +ASM void __LCEnable() { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x1000 + mtmsr r5 + + lis r3, OS_CACHED_REGION_PREFIX + li r4, CACHE_LINES + mtctr r4 + _touchloop: + dcbt 0,r3 + dcbst 0,r3 + addi r3,r3,32 + bdnz _touchloop + mfspr r4, HID2 + oris r4, r4, 0x100F + mtspr HID2, r4 + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + lis r3, LC_BASE_PREFIX + ori r3, r3, 0x0002 + mtspr DBAT3L, r3 + ori r3, r3, 0x01fe + mtspr DBAT3U, r3 + isync + lis r3, LC_BASE_PREFIX + li r6, LC_LINES + mtctr r6 + li r6, 0 + +_lockloop: + dcbz_l r6, r3 + addi r3, r3, 32 + bdnz+ _lockloop + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + blr +#endif // clang-format on +} + +void LCEnable() { + BOOL enabled; + + enabled = OSDisableInterrupts(); + __LCEnable(); + OSRestoreInterrupts(enabled); +} + +ASM void LCDisable() { +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r3, LC_BASE_PREFIX + li r4, LC_LINES + mtctr r4 +@1 + dcbi r0, r3 + addi r3, r3, 32 + bdnz @1 + mfspr r4, HID2 + rlwinm r4, r4, 0, 4, 2 + mtspr HID2, r4 + blr +#endif // clang-format on +} + +ASM void LCStoreBlocks(register void* destAddr, register void* srcTag, register u32 numBlocks){ +#ifdef __MWERKS__ // clang-format off + nofralloc + rlwinm r6, numBlocks, 30, 27, 31 + rlwinm destAddr, destAddr, 0, 4, 31 + or r6, r6, destAddr + mtspr DMA_U, r6 + rlwinm r6, numBlocks, 2, 28, 29 + or r6, r6, srcTag + ori r6, r6, 0x2 + mtspr DMA_L, r6 + blr +#endif // clang-format on +} + +u32 LCStoreData(void* destAddr, void* srcAddr, u32 nBytes) { + u32 numBlocks = (nBytes + 31) / 32; + u32 numTransactions = (numBlocks + 128 - 1) / 128; + + while (numBlocks > 0) { + if (numBlocks < 128) { + LCStoreBlocks(destAddr, srcAddr, numBlocks); + numBlocks = 0; + } else { + LCStoreBlocks(destAddr, srcAddr, 0); + numBlocks -= 128; + destAddr = (void*)((u32)destAddr + 4096); + srcAddr = (void*)((u32)srcAddr + 4096); + } + } + + return numTransactions; +} + +ASM void LCQueueWait(register u32 len) { +#ifdef __MWERKS__ // clang-format off + nofralloc +#if DOLPHIN_REV == 2002 + addi len, len, 1 +#endif +@1 + mfspr r4, HID2 + rlwinm r4, r4, 8, 28, 31 +#if DOLPHIN_REV == 2002 + cmpw cr2, r4, r3 + bge cr2, @1 +#else + cmpw r4, r3 + bgt @1 +#endif + blr +#endif // clang-format on +} + +static inline void L2Disable(void) { + __sync(); + PPCMtl2cr(PPCMfl2cr() & ~0x80000000); + __sync(); +} + +void L2GlobalInvalidate(void) { + L2Disable(); + PPCMtl2cr(PPCMfl2cr() | 0x00200000); + while (PPCMfl2cr() & 0x00000001u) + ; + PPCMtl2cr(PPCMfl2cr() & ~0x00200000); + while (PPCMfl2cr() & 0x00000001u) { + DBPrintf(">>> L2 INVALIDATE : SHOULD NEVER HAPPEN\n"); + } +} + +static inline void L2Init(void) { + u32 oldMSR; + oldMSR = PPCMfmsr(); + __sync(); + PPCMtmsr(MSR_IR | MSR_DR); + __sync(); + L2Disable(); + L2GlobalInvalidate(); + PPCMtmsr(oldMSR); +} + +inline void L2Enable(void) { PPCMtl2cr((PPCMfl2cr() | L2CR_L2E) & ~L2CR_L2I); } + +void DMAErrorHandler(OSError error, OSContext* context, ...) { + u32 hid2 = PPCMfhid2(); + + OSReport("Machine check received\n"); + OSReport("HID2 = 0x%x SRR1 = 0x%x\n", hid2, context->srr1); + if (!(hid2 & (HID2_DCHERR | HID2_DNCERR | HID2_DCMERR | HID2_DQOERR)) || !(context->srr1 & SRR1_DMA_BIT)) { + OSReport("Machine check was not DMA/locked cache related\n"); + OSDumpContext(context); + PPCHalt(); + } + + OSReport("DMAErrorHandler(): An error occurred while processing DMA.\n"); + OSReport("The following errors have been detected and cleared :\n"); + + if (hid2 & HID2_DCHERR) { + OSReport("\t- Requested a locked cache tag that was already in the cache\n"); + } + + if (hid2 & HID2_DNCERR) { + OSReport("\t- DMA attempted to access normal cache\n"); + } + + if (hid2 & HID2_DCMERR) { + OSReport("\t- DMA missed in data cache\n"); + } + + if (hid2 & HID2_DQOERR) { + OSReport("\t- DMA queue overflowed\n"); + } + + // write hid2 back to clear the error bits + PPCMthid2(hid2); +} + +void __OSCacheInit() { + if (!(PPCMfhid0() & HID0_ICE)) { + ICEnable(); + DBPrintf("L1 i-caches initialized\n"); + } + if (!(PPCMfhid0() & HID0_DCE)) { + DCEnable(); + DBPrintf("L1 d-caches initialized\n"); + } + + if (!(PPCMfl2cr() & L2CR_L2E)) { + L2Init(); + L2Enable(); + DBPrintf("L2 cache initialized\n"); + } + + OSSetErrorHandler(OS_ERROR_MACHINE_CHECK, DMAErrorHandler); + DBPrintf("Locked cache machine check handler installed\n"); +} diff --git a/src/dolphin/os/OSContext.c b/src/dolphin/os/OSContext.c new file mode 100644 index 0000000..d785c9a --- /dev/null +++ b/src/dolphin/os/OSContext.c @@ -0,0 +1,512 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/db.h" +#include "dolphin/os.h" +#include "macros.h" + +volatile OSContext* __OSCurrentContext AT_ADDRESS(OS_BASE_CACHED | 0x00D4); +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED | 0x00D8); + +static ASM void __OSLoadFPUContext(register u32, register OSContext* fpuContext) { +#ifdef __MWERKS__ // clang-format off + nofralloc + lhz r5, fpuContext->state; + clrlwi. r5, r5, 31 + beq _return + + lfd fp0, OS_CONTEXT_FPSCR(fpuContext) + mtfsf 0xFF, fp0 + mfspr r5, HID2 + rlwinm. r5, r5, 3, 31, 31 + beq _regular_FPRs + + psq_l fp0, OS_CONTEXT_PSF0(fpuContext), 0, 0 + psq_l fp1, OS_CONTEXT_PSF1(fpuContext), 0, 0 + psq_l fp2, OS_CONTEXT_PSF2(fpuContext), 0, 0 + psq_l fp3, OS_CONTEXT_PSF3(fpuContext), 0, 0 + psq_l fp4, OS_CONTEXT_PSF4(fpuContext), 0, 0 + psq_l fp5, OS_CONTEXT_PSF5(fpuContext), 0, 0 + psq_l fp6, OS_CONTEXT_PSF6(fpuContext), 0, 0 + psq_l fp7, OS_CONTEXT_PSF7(fpuContext), 0, 0 + psq_l fp8, OS_CONTEXT_PSF8(fpuContext), 0, 0 + psq_l fp9, OS_CONTEXT_PSF9(fpuContext), 0, 0 + psq_l fp10, OS_CONTEXT_PSF10(fpuContext), 0, 0 + psq_l fp11, OS_CONTEXT_PSF11(fpuContext), 0, 0 + psq_l fp12, OS_CONTEXT_PSF12(fpuContext), 0, 0 + psq_l fp13, OS_CONTEXT_PSF13(fpuContext), 0, 0 + psq_l fp14, OS_CONTEXT_PSF14(fpuContext), 0, 0 + psq_l fp15, OS_CONTEXT_PSF15(fpuContext), 0, 0 + psq_l fp16, OS_CONTEXT_PSF16(fpuContext), 0, 0 + psq_l fp17, OS_CONTEXT_PSF17(fpuContext), 0, 0 + psq_l fp18, OS_CONTEXT_PSF18(fpuContext), 0, 0 + psq_l fp19, OS_CONTEXT_PSF19(fpuContext), 0, 0 + psq_l fp20, OS_CONTEXT_PSF20(fpuContext), 0, 0 + psq_l fp21, OS_CONTEXT_PSF21(fpuContext), 0, 0 + psq_l fp22, OS_CONTEXT_PSF22(fpuContext), 0, 0 + psq_l fp23, OS_CONTEXT_PSF23(fpuContext), 0, 0 + psq_l fp24, OS_CONTEXT_PSF24(fpuContext), 0, 0 + psq_l fp25, OS_CONTEXT_PSF25(fpuContext), 0, 0 + psq_l fp26, OS_CONTEXT_PSF26(fpuContext), 0, 0 + psq_l fp27, OS_CONTEXT_PSF27(fpuContext), 0, 0 + psq_l fp28, OS_CONTEXT_PSF28(fpuContext), 0, 0 + psq_l fp29, OS_CONTEXT_PSF29(fpuContext), 0, 0 + psq_l fp30, OS_CONTEXT_PSF30(fpuContext), 0, 0 + psq_l fp31, OS_CONTEXT_PSF31(fpuContext), 0, 0 + +_regular_FPRs: + lfd fp0, fpuContext->fpr[0] + lfd fp1, fpuContext->fpr[1] + lfd fp2, fpuContext->fpr[2] + lfd fp3, fpuContext->fpr[3] + lfd fp4, fpuContext->fpr[4] + lfd fp5, fpuContext->fpr[5] + lfd fp6, fpuContext->fpr[6] + lfd fp7, fpuContext->fpr[7] + lfd fp8, fpuContext->fpr[8] + lfd fp9, fpuContext->fpr[9] + lfd fp10, fpuContext->fpr[10] + lfd fp11, fpuContext->fpr[11] + lfd fp12, fpuContext->fpr[12] + lfd fp13, fpuContext->fpr[13] + lfd fp14, fpuContext->fpr[14] + lfd fp15, fpuContext->fpr[15] + lfd fp16, fpuContext->fpr[16] + lfd fp17, fpuContext->fpr[17] + lfd fp18, fpuContext->fpr[18] + lfd fp19, fpuContext->fpr[19] + lfd fp20, fpuContext->fpr[20] + lfd fp21, fpuContext->fpr[21] + lfd fp22, fpuContext->fpr[22] + lfd fp23, fpuContext->fpr[23] + lfd fp24, fpuContext->fpr[24] + lfd fp25, fpuContext->fpr[25] + lfd fp26, fpuContext->fpr[26] + lfd fp27, fpuContext->fpr[27] + lfd fp28, fpuContext->fpr[28] + lfd fp29, fpuContext->fpr[29] + lfd fp30, fpuContext->fpr[30] + lfd fp31, fpuContext->fpr[31] +_return: + blr +#endif // clang-format on +} + +static ASM void __OSSaveFPUContext(register u32, register u32, register OSContext* fpuContext){ +#ifdef __MWERKS__ // clang-format off + nofralloc + + lhz r3, fpuContext->state + ori r3, r3, 1 + sth r3, fpuContext->state + + stfd fp0, fpuContext->fpr[0] + stfd fp1, fpuContext->fpr[1] + stfd fp2, fpuContext->fpr[2] + stfd fp3, fpuContext->fpr[3] + stfd fp4, fpuContext->fpr[4] + stfd fp5, fpuContext->fpr[5] + stfd fp6, fpuContext->fpr[6] + stfd fp7, fpuContext->fpr[7] + stfd fp8, fpuContext->fpr[8] + stfd fp9, fpuContext->fpr[9] + stfd fp10, fpuContext->fpr[10] + stfd fp11, fpuContext->fpr[11] + stfd fp12, fpuContext->fpr[12] + stfd fp13, fpuContext->fpr[13] + stfd fp14, fpuContext->fpr[14] + stfd fp15, fpuContext->fpr[15] + stfd fp16, fpuContext->fpr[16] + stfd fp17, fpuContext->fpr[17] + stfd fp18, fpuContext->fpr[18] + stfd fp19, fpuContext->fpr[19] + stfd fp20, fpuContext->fpr[20] + stfd fp21, fpuContext->fpr[21] + stfd fp22, fpuContext->fpr[22] + stfd fp23, fpuContext->fpr[23] + stfd fp24, fpuContext->fpr[24] + stfd fp25, fpuContext->fpr[25] + stfd fp26, fpuContext->fpr[26] + stfd fp27, fpuContext->fpr[27] + stfd fp28, fpuContext->fpr[28] + stfd fp29, fpuContext->fpr[29] + stfd fp30, fpuContext->fpr[30] + stfd fp31, fpuContext->fpr[31] + + mffs fp0 + stfd fp0, OS_CONTEXT_FPSCR(fpuContext) + + lfd fp0, fpuContext->fpr[0] + + mfspr r3, HID2 + rlwinm. r3, r3, 3, 31, 31 + bc 12, 2, _return + + psq_st fp0, OS_CONTEXT_PSF0(fpuContext), 0, 0 + psq_st fp1, OS_CONTEXT_PSF1(fpuContext), 0, 0 + psq_st fp2, OS_CONTEXT_PSF2(fpuContext), 0, 0 + psq_st fp3, OS_CONTEXT_PSF3(fpuContext), 0, 0 + psq_st fp4, OS_CONTEXT_PSF4(fpuContext), 0, 0 + psq_st fp5, OS_CONTEXT_PSF5(fpuContext), 0, 0 + psq_st fp6, OS_CONTEXT_PSF6(fpuContext), 0, 0 + psq_st fp7, OS_CONTEXT_PSF7(fpuContext), 0, 0 + psq_st fp8, OS_CONTEXT_PSF8(fpuContext), 0, 0 + psq_st fp9, OS_CONTEXT_PSF9(fpuContext), 0, 0 + psq_st fp10, OS_CONTEXT_PSF10(fpuContext), 0, 0 + psq_st fp11, OS_CONTEXT_PSF11(fpuContext), 0, 0 + psq_st fp12, OS_CONTEXT_PSF12(fpuContext), 0, 0 + psq_st fp13, OS_CONTEXT_PSF13(fpuContext), 0, 0 + psq_st fp14, OS_CONTEXT_PSF14(fpuContext), 0, 0 + psq_st fp15, OS_CONTEXT_PSF15(fpuContext), 0, 0 + psq_st fp16, OS_CONTEXT_PSF16(fpuContext), 0, 0 + psq_st fp17, OS_CONTEXT_PSF17(fpuContext), 0, 0 + psq_st fp18, OS_CONTEXT_PSF18(fpuContext), 0, 0 + psq_st fp19, OS_CONTEXT_PSF19(fpuContext), 0, 0 + psq_st fp20, OS_CONTEXT_PSF20(fpuContext), 0, 0 + psq_st fp21, OS_CONTEXT_PSF21(fpuContext), 0, 0 + psq_st fp22, OS_CONTEXT_PSF22(fpuContext), 0, 0 + psq_st fp23, OS_CONTEXT_PSF23(fpuContext), 0, 0 + psq_st fp24, OS_CONTEXT_PSF24(fpuContext), 0, 0 + psq_st fp25, OS_CONTEXT_PSF25(fpuContext), 0, 0 + psq_st fp26, OS_CONTEXT_PSF26(fpuContext), 0, 0 + psq_st fp27, OS_CONTEXT_PSF27(fpuContext), 0, 0 + psq_st fp28, OS_CONTEXT_PSF28(fpuContext), 0, 0 + psq_st fp29, OS_CONTEXT_PSF29(fpuContext), 0, 0 + psq_st fp30, OS_CONTEXT_PSF30(fpuContext), 0, 0 + psq_st fp31, OS_CONTEXT_PSF31(fpuContext), 0, 0 + +_return: + blr +#endif // clang-format on +} + +ASM void OSSaveFPUContext(register OSContext* fpuContext){ +#ifdef __MWERKS__ // clang-format off + nofralloc + addi r5, fpuContext, 0 + b __OSSaveFPUContext +#endif // clang-format on +} + +ASM void OSSetCurrentContext(register OSContext* context){ +#ifdef __MWERKS__ // clang-format off + nofralloc + + addis r4, r0, OS_CACHED_REGION_PREFIX + + stw context, 0x00D4(r4) + + clrlwi r5, context, 2 + stw r5, 0x00C0(r4) + + lwz r5, 0x00D8(r4) + cmpw r5, context + bne _disableFPU + + lwz r6, context->srr1 + ori r6, r6, 0x2000 + stw r6, context->srr1 + mfmsr r6 + ori r6, r6, 2 + mtmsr r6 + blr + +_disableFPU: + lwz r6, context->srr1 + rlwinm r6, r6, 0, 19, 17 + stw r6, context->srr1 + mfmsr r6 + rlwinm r6, r6, 0, 19, 17 + ori r6, r6, 2 + mtmsr r6 + isync + blr +#endif // clang-format on +} + +OSContext* OSGetCurrentContext(void) { + return (OSContext*)__OSCurrentContext; +} + +ASM u32 OSSaveContext(register OSContext* context) { +#ifdef __MWERKS__ // clang-format off + nofralloc + stmw r13, context->gpr[13] + mfspr r0, GQR1 + stw r0, context->gqr[1] + mfspr r0, GQR2 + stw r0, context->gqr[2] + mfspr r0, GQR3 + stw r0, context->gqr[3] + mfspr r0, GQR4 + stw r0, context->gqr[4] + mfspr r0, GQR5 + stw r0, context->gqr[5] + mfspr r0, GQR6 + stw r0, context->gqr[6] + mfspr r0, GQR7 + stw r0, context->gqr[7] + mfcr r0 + stw r0, context->cr + mflr r0 + stw r0, context->lr + stw r0, context->srr0 + mfmsr r0 + stw r0, context->srr1 + mfctr r0 + stw r0, context->ctr + mfxer r0 + stw r0, context->xer + stw r1, context->gpr[1] + stw r2, context->gpr[2] + li r0, 0x1 + stw r0, context->gpr[3] + li r3, 0 + blr +#endif // clang-format on +} + +extern void __RAS_OSDisableInterrupts_begin(); +extern void __RAS_OSDisableInterrupts_end(); + +ASM void OSLoadContext(register OSContext* context) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + lis r4,__RAS_OSDisableInterrupts_begin@ha + lwz r6,context->srr0 + addi r5,r4,__RAS_OSDisableInterrupts_begin@l + cmplw r6,r5 + ble _notInRAS + lis r4,__RAS_OSDisableInterrupts_end@ha + addi r0,r4,__RAS_OSDisableInterrupts_end@l + cmplw r6,r0 + bge _notInRAS + stw r5,context->srr0 + +_notInRAS: + + lwz r0, context->gpr[0] + lwz r1, context->gpr[1] + lwz r2, context->gpr[2] + + lhz r4, context->state + rlwinm. r5, r4, 0, 30, 30 + beq notexc + rlwinm r4, r4, 0, 31, 29 + sth r4, context->state + lmw r5, context->gpr[5] + b misc +notexc: + lmw r13, context->gpr[13] +misc: + + lwz r4, context->gqr[1] + mtspr GQR1, r4 + lwz r4, context->gqr[2] + mtspr GQR2, r4 + lwz r4, context->gqr[3] + mtspr GQR3, r4 + lwz r4, context->gqr[4] + mtspr GQR4, r4 + lwz r4, context->gqr[5] + mtspr GQR5, r4 + lwz r4, context->gqr[6] + mtspr GQR6, r4 + lwz r4, context->gqr[7] + mtspr GQR7, r4 + + lwz r4, context->cr + mtcr r4 + lwz r4, context->lr + mtlr r4 + lwz r4, context->ctr + mtctr r4 + lwz r4, context->xer + mtxer r4 + + mfmsr r4 + rlwinm r4, r4, 0, 17, 15 + rlwinm r4, r4, 0, 31, 29 + mtmsr r4 + + lwz r4, context->srr0 + mtsrr0 r4 + lwz r4, context->srr1 + mtsrr1 r4 + + lwz r4, context->gpr[4] + lwz r3, context->gpr[3] + + rfi +#endif // clang-format on +} + +ASM u32 OSGetStackPointer() { +#ifdef __MWERKS__ // clang-format off + nofralloc + mr r3, r1 + blr +#endif // clang-format on +} + +void OSClearContext(register OSContext* context) { + context->mode = 0; + context->state = 0; + if (context == __OSFPUContext) + __OSFPUContext = NULL; +} + +ASM void OSInitContext(register OSContext* context, register u32 pc, register u32 newsp) { +#ifdef __MWERKS__ // clang-format off + nofralloc + + stw pc, OS_CONTEXT_SRR0(context) + stw newsp, OS_CONTEXT_R1(context) + li r11, 0 + ori r11, r11, 0x00008000 | 0x00000020 | 0x00000010 | 0x00000002 | 0x00001000 + stw r11, OS_CONTEXT_SRR1(context) + li r0, 0x0 + stw r0, OS_CONTEXT_CR(context) + stw r0, OS_CONTEXT_XER(context) + + + stw r2, OS_CONTEXT_R2(context) + stw r13, OS_CONTEXT_R13(context) + + stw r0, OS_CONTEXT_R3(context) + stw r0, OS_CONTEXT_R4(context) + stw r0, OS_CONTEXT_R5(context) + stw r0, OS_CONTEXT_R6(context) + stw r0, OS_CONTEXT_R7(context) + stw r0, OS_CONTEXT_R8(context) + stw r0, OS_CONTEXT_R9(context) + stw r0, OS_CONTEXT_R10(context) + stw r0, OS_CONTEXT_R11(context) + stw r0, OS_CONTEXT_R12(context) + + stw r0, OS_CONTEXT_R14(context) + stw r0, OS_CONTEXT_R15(context) + stw r0, OS_CONTEXT_R16(context) + stw r0, OS_CONTEXT_R17(context) + stw r0, OS_CONTEXT_R18(context) + stw r0, OS_CONTEXT_R19(context) + stw r0, OS_CONTEXT_R20(context) + stw r0, OS_CONTEXT_R21(context) + stw r0, OS_CONTEXT_R22(context) + stw r0, OS_CONTEXT_R23(context) + stw r0, OS_CONTEXT_R24(context) + stw r0, OS_CONTEXT_R25(context) + stw r0, OS_CONTEXT_R26(context) + stw r0, OS_CONTEXT_R27(context) + stw r0, OS_CONTEXT_R28(context) + stw r0, OS_CONTEXT_R29(context) + stw r0, OS_CONTEXT_R30(context) + stw r0, OS_CONTEXT_R31(context) + + stw r0, OS_CONTEXT_GQR0(context) + stw r0, OS_CONTEXT_GQR1(context) + stw r0, OS_CONTEXT_GQR2(context) + stw r0, OS_CONTEXT_GQR3(context) + stw r0, OS_CONTEXT_GQR4(context) + stw r0, OS_CONTEXT_GQR5(context) + stw r0, OS_CONTEXT_GQR6(context) + stw r0, OS_CONTEXT_GQR7(context) + + b OSClearContext +#endif // clang-format on +} + +void OSDumpContext(OSContext* context) { + u32 i; + u32* p; + + OSReport("------------------------- Context 0x%08x -------------------------\n", context); + + for (i = 0; i < 16; ++i) { + OSReport("r%-2d = 0x%08x (%14d) r%-2d = 0x%08x (%14d)\n", i, context->gpr[i], context->gpr[i], i + 16, + context->gpr[i + 16], context->gpr[i + 16]); + } + + OSReport("LR = 0x%08x CR = 0x%08x\n", context->lr, context->cr); + OSReport("SRR0 = 0x%08x SRR1 = 0x%08x\n", context->srr0, context->srr1); + + OSReport("\nGQRs----------\n"); + for (i = 0; i < 4; ++i) { + OSReport("gqr%d = 0x%08x \t gqr%d = 0x%08x\n", i, context->gqr[i], i + 4, context->gqr[i + 4]); + } + + if (context->state & OS_CONTEXT_STATE_FPSAVED) { + OSContext* currentContext; + OSContext fpuContext; + BOOL enabled; + + enabled = OSDisableInterrupts(); + currentContext = OSGetCurrentContext(); + OSClearContext(&fpuContext); + OSSetCurrentContext(&fpuContext); + + OSReport("\n\nFPRs----------\n"); + for (i = 0; i < 32; i += 2) { + OSReport("fr%d \t= %d \t fr%d \t= %d\n", i, (u32)context->fpr[i], i + 1, (u32)context->fpr[i + 1]); + } + OSReport("\n\nPSFs----------\n"); + for (i = 0; i < 32; i += 2) { + OSReport("ps%d \t= 0x%x \t ps%d \t= 0x%x\n", i, (u32)context->psf[i], i + 1, (u32)context->psf[i + 1]); + } + + OSClearContext(&fpuContext); + OSSetCurrentContext(currentContext); + OSRestoreInterrupts(enabled); + } + + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)context->gpr[1]; p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } +} + +static ASM void OSSwitchFPUContext(register __OSException exception, register OSContext* context) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r5 + ori r5, r5, 0x2000 + mtmsr r5 + isync + lwz r5, OS_CONTEXT_SRR1(context) + ori r5, r5, 0x2000 + mtsrr1 r5 + addis r3, r0, OS_CACHED_REGION_PREFIX + lwz r5, 0x00D8(r3) + stw context, 0x00D8(r3) + cmpw r5, r4 + beq _restoreAndExit + cmpwi r5, 0x0 + beq _loadNewFPUContext + bl __OSSaveFPUContext +_loadNewFPUContext: + bl __OSLoadFPUContext +_restoreAndExit: + lwz r3, OS_CONTEXT_CR(context) + mtcr r3 + lwz r3, OS_CONTEXT_LR(context) + mtlr r3 + lwz r3, OS_CONTEXT_SRR0(context) + mtsrr0 r3 + lwz r3, OS_CONTEXT_CTR(context) + mtctr r3 + lwz r3, OS_CONTEXT_XER(context) + mtxer r3 + lhz r3, context->state + rlwinm r3, r3, 0, 31, 29 + sth r3, context->state + lwz r5, OS_CONTEXT_R5(context) + lwz r3, OS_CONTEXT_R3(context) + lwz r4, OS_CONTEXT_R4(context) + rfi +#endif // clang-format on +} + +void __OSContextInit(void) { + __OSSetExceptionHandler(__OS_EXCEPTION_FLOATING_POINT, OSSwitchFPUContext); + __OSFPUContext = NULL; + DBPrintf("FPU-unavailable handler installed\n"); +} diff --git a/src/dolphin/os/OSError.c b/src/dolphin/os/OSError.c new file mode 100644 index 0000000..d6a6b7b --- /dev/null +++ b/src/dolphin/os/OSError.c @@ -0,0 +1,198 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" +#include "macros.h" +#include "stdio.h" + +OSErrorHandler __OSErrorTable[OS_ERROR_MAX]; + +#define FPSCR_ENABLE (FPSCR_VE | FPSCR_OE | FPSCR_UE | FPSCR_ZE | FPSCR_XE) +u32 __OSFpscrEnableBits = FPSCR_ENABLE; + +WEAK void OSReport(const char* msg, ...) { + va_list args; + va_start(args, msg); + vprintf(msg, args); + va_end(args); +} + +WEAK void OSPanic(const char* file, int line, const char* msg, ...) { + va_list marker; + u32 i; + u32* p; + + OSDisableInterrupts(); + va_start(marker, msg); + vprintf(msg, marker); + va_end(marker); + OSReport(" in \"%s\" on line %d.\n", file, line); + + OSReport("\nAddress: Back Chain LR Save\n"); + for (i = 0, p = (u32*)OSGetStackPointer(); p && (u32)p != 0xffffffff && i++ < 16; p = (u32*)*p) { + OSReport("0x%08x: 0x%08x 0x%08x\n", p, p[0], p[1]); + } + + PPCHalt(); +} + +OSErrorHandler OSSetErrorHandler(OSError error, OSErrorHandler handler) { + OSErrorHandler oldHandler; + BOOL enabled; + + enabled = OSDisableInterrupts(); + oldHandler = __OSErrorTable[error]; + __OSErrorTable[error] = handler; + + if (error == OS_ERROR_FPE) { + u32 msr; + u32 fpscr; + OSThread* thread; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + fpscr = PPCMffpscr(); + if (handler) { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 |= MSR_FE0 | MSR_FE1; + if ((thread->context.state & OS_CONTEXT_STATE_FPSAVED) == 0) { + int i; + thread->context.state |= OS_CONTEXT_STATE_FPSAVED; + for (i = 0; i < 32; ++i) { + *(u64*)&thread->context.fpr[i] = (u64)0xffffffffffffffffLL; + *(u64*)&thread->context.psf[i] = (u64)0xffffffffffffffffLL; + } + thread->context.fpscr = FPSCR_NI; + } + thread->context.fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | FPSCR_VXSOFT | + FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr |= __OSFpscrEnableBits & FPSCR_ENABLE; + msr |= MSR_FE0 | MSR_FE1; + } else { + for (thread = __OSActiveThreadQueue.head; thread; thread = thread->linkActive.next) { + thread->context.srr1 &= ~(MSR_FE0 | MSR_FE1); + thread->context.fpscr &= ~FPSCR_ENABLE; + thread->context.fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | FPSCR_VXSOFT | + FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + } + fpscr &= ~FPSCR_ENABLE; + msr &= ~(MSR_FE0 | MSR_FE1); + } + + fpscr &= ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | FPSCR_VXSOFT | + FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + + PPCMtfpscr(fpscr); + PPCMtmsr(msr); + } + + OSRestoreInterrupts(enabled); + return oldHandler; +} + +void __OSUnhandledException(__OSException exception, OSContext* context, u32 dsisr, u32 dar) { + OSTime now; + + now = OSGetTime(); + + if (!(context->srr1 & MSR_RI)) { + OSReport("Non-recoverable Exception %d", exception); + } else { + if (exception == __OS_EXCEPTION_PROGRAM && (context->srr1 & (0x80000000 >> 11)) && + __OSErrorTable[OS_ERROR_FPE] != 0) { + u32 fpscr; + u32 msr; + + exception = OS_ERROR_FPE; + + msr = PPCMfmsr(); + PPCMtmsr(msr | MSR_FP); + + if (__OSFPUContext) { + OSSaveFPUContext((OSContext*)__OSFPUContext); + } + + fpscr = PPCMffpscr(); + fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | FPSCR_VXSOFT | + FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + PPCMtfpscr(fpscr); + + PPCMtmsr(msr); + + if (__OSFPUContext == context) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + + context->fpscr &= + ~(FPSCR_VXVC | FPSCR_VXIMZ | FPSCR_VXZDZ | FPSCR_VXIDI | FPSCR_VXISI | FPSCR_VXSNAN | FPSCR_VXSOFT | + FPSCR_VXSQRT | FPSCR_VXCVI | FPSCR_XX | FPSCR_ZX | FPSCR_UX | FPSCR_OX | FPSCR_FX | FPSCR_FI); + OSEnableScheduler(); + __OSReschedule(); + } else { + context->srr1 &= ~MSR_FP; + __OSFPUContext = NULL; + } + + OSLoadContext(context); + } + + if (__OSErrorTable[exception]) { + OSDisableScheduler(); + __OSErrorTable[exception](exception, context, dsisr, dar); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + + if (exception == OS_ERROR_DECREMENTER) { + OSLoadContext(context); + } + + OSReport("Unhandled Exception %d", exception); + } + + OSReport("\n"); + OSDumpContext(context); + OSReport("\nDSISR = 0x%08x DAR = 0x%08x\n", dsisr, dar); + OSReport("TB = 0x%016llx\n", now); + + switch (exception) { + case __OS_EXCEPTION_DSI: + OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access " + "invalid address 0x%x (read from DAR)\n", + context->srr0, dar); + break; + case __OS_EXCEPTION_ISI: + OSReport("\nAttempted to fetch instruction from invalid address 0x%x " + "(read from SRR0)\n", + context->srr0); + break; + case __OS_EXCEPTION_ALIGNMENT: + OSReport("\nInstruction at 0x%x (read from SRR0) attempted to access " + "unaligned address 0x%x (read from DAR)\n", + context->srr0, dar); + break; + case __OS_EXCEPTION_PROGRAM: + OSReport("\nProgram exception : Possible illegal instruction/operation " + "at or around 0x%x (read from SRR0)\n", + context->srr0, dar); + break; + case OS_ERROR_PROTECTION: + OSReport("\n"); + OSReport("AI DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000018], __DSPRegs[0x00000018 + 1]); + OSReport("ARAM DMA Address = 0x%04x%04x\n", __DSPRegs[0x00000010], __DSPRegs[0x00000010 + 1]); + OSReport("DI DMA Address = 0x%08x\n", __DIRegs[0x00000005]); + break; + } + + OSReport("\nLast interrupt (%d): SRR0 = 0x%08x TB = 0x%016llx\n", __OSLastInterrupt, __OSLastInterruptSrr0, + __OSLastInterruptTime); + + PPCHalt(); +} diff --git a/src/dolphin/os/OSFont.c b/src/dolphin/os/OSFont.c new file mode 100644 index 0000000..51f0dc5 --- /dev/null +++ b/src/dolphin/os/OSFont.c @@ -0,0 +1,26 @@ +#include "dolphin/gx.h" +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" + +u16 OSGetFontEncode(void) { + static u16 fontEncode = 0xFFFF; + if (fontEncode <= 1) { + return fontEncode; + } + switch (__OSTVMode) { + case VI_NTSC: + fontEncode = (__VIRegs[VI_DTV_STAT] & 2) ? OS_FONT_ENCODE_SJIS : OS_FONT_ENCODE_ANSI; + break; + + case VI_PAL: + case VI_MPAL: + case VI_DEBUG: + case VI_DEBUG_PAL: + case VI_EURGB60: + default: + fontEncode = OS_FONT_ENCODE_ANSI; + } + + return fontEncode; +} diff --git a/src/dolphin/os/OSInterrupt.c b/src/dolphin/os/OSInterrupt.c new file mode 100644 index 0000000..f8412b2 --- /dev/null +++ b/src/dolphin/os/OSInterrupt.c @@ -0,0 +1,403 @@ +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" +#include "macros.h" + +static ASM void ExternalInterruptHandler(register __OSException exception, register OSContext* context); + +extern void __RAS_OSDisableInterrupts_begin(void); +extern void __RAS_OSDisableInterrupts_end(void); + +static __OSInterruptHandler* InterruptHandlerTable; + +static OSInterruptMask InterruptPrioTable[] = { + OS_INTERRUPTMASK_PI_ERROR, + OS_INTERRUPTMASK_PI_DEBUG, + OS_INTERRUPTMASK_MEM, + OS_INTERRUPTMASK_PI_RSW, + OS_INTERRUPTMASK_PI_VI, + OS_INTERRUPTMASK_PI_PE, + OS_INTERRUPTMASK_PI_HSP, + OS_INTERRUPTMASK_DSP_ARAM | OS_INTERRUPTMASK_DSP_DSP | OS_INTERRUPTMASK_AI | OS_INTERRUPTMASK_EXI | + OS_INTERRUPTMASK_PI_SI | OS_INTERRUPTMASK_PI_DI, + OS_INTERRUPTMASK_DSP_AI, + OS_INTERRUPTMASK_PI_CP, + 0xFFFFFFFF, +}; + +ASM BOOL OSDisableInterrupts(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc +entry __RAS_OSDisableInterrupts_begin + mfmsr r3 + rlwinm r4, r3, 0, 17, 15 + mtmsr r4 +entry __RAS_OSDisableInterrupts_end + rlwinm r3, r3, 17, 31, 31 + blr +#endif // clang-format on +} + +ASM BOOL OSEnableInterrupts(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + + mfmsr r3 + ori r4, r3, 0x8000 + mtmsr r4 + rlwinm r3, r3, 17, 31, 31 + blr +#endif // clang-format on +} + +ASM BOOL OSRestoreInterrupts(register BOOL level){ +#ifdef __MWERKS__ // clang-format off + + nofralloc + + cmpwi level, 0 + mfmsr r4 + beq _disable + ori r5, r4, 0x8000 + b _restore +_disable: + rlwinm r5, r4, 0, 17, 15 +_restore: + mtmsr r5 + rlwinm r3, r4, 17, 31, 31 + blr +#endif // clang-format on +} + +__OSInterruptHandler __OSSetInterruptHandler(__OSInterrupt interrupt, __OSInterruptHandler handler) { + __OSInterruptHandler oldHandler; + + oldHandler = InterruptHandlerTable[interrupt]; + InterruptHandlerTable[interrupt] = handler; + return oldHandler; +} + +__OSInterruptHandler __OSGetInterruptHandler(__OSInterrupt interrupt) { return InterruptHandlerTable[interrupt]; } + +void __OSInterruptInit(void) { + InterruptHandlerTable = OSPhysicalToCached(0x3040); + memset(InterruptHandlerTable, 0, __OS_INTERRUPT_MAX * sizeof(__OSInterruptHandler)); + + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = 0; + + *(OSInterruptMask*)OSPhysicalToCached(0x00C8) = 0; + + __PIRegs[1] = 0xf0; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM | OS_INTERRUPTMASK_DSP | OS_INTERRUPTMASK_AI | OS_INTERRUPTMASK_EXI | + OS_INTERRUPTMASK_PI); + + __OSSetExceptionHandler(4, ExternalInterruptHandler); +} + +u32 SetInterruptMask(OSInterruptMask mask, OSInterruptMask current) { + u32 reg; + + switch (__cntlzw(mask)) { + case __OS_INTERRUPT_MEM_0: + case __OS_INTERRUPT_MEM_1: + case __OS_INTERRUPT_MEM_2: + case __OS_INTERRUPT_MEM_3: + case __OS_INTERRUPT_MEM_ADDRESS: + reg = 0; + if (!(current & OS_INTERRUPTMASK_MEM_0)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_MEM_1)) + reg |= 0x2; + if (!(current & OS_INTERRUPTMASK_MEM_2)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_MEM_3)) + reg |= 0x8; + if (!(current & OS_INTERRUPTMASK_MEM_ADDRESS)) + reg |= 0x10; + __MEMRegs[0x0000000e] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_MEM; + break; + case __OS_INTERRUPT_DSP_AI: + case __OS_INTERRUPT_DSP_ARAM: + case __OS_INTERRUPT_DSP_DSP: + reg = __DSPRegs[0x00000005]; + reg &= ~0x1F8; + if (!(current & OS_INTERRUPTMASK_DSP_AI)) + reg |= 0x10; + if (!(current & OS_INTERRUPTMASK_DSP_ARAM)) + reg |= 0x40; + if (!(current & OS_INTERRUPTMASK_DSP_DSP)) + reg |= 0x100; + __DSPRegs[0x00000005] = (u16)reg; + mask &= ~OS_INTERRUPTMASK_DSP; + break; + case __OS_INTERRUPT_AI_AI: + reg = __AIRegs[0]; + reg &= ~0x2C; + if (!(current & OS_INTERRUPTMASK_AI_AI)) + reg |= 0x4; + __AIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_AI; + break; + case __OS_INTERRUPT_EXI_0_EXI: + case __OS_INTERRUPT_EXI_0_TC: + case __OS_INTERRUPT_EXI_0_EXT: + reg = __EXIRegs[0]; + reg &= ~0x2C0F; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_0_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_0_EXT)) + reg |= 0x400; + __EXIRegs[0] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_0; + break; + case __OS_INTERRUPT_EXI_1_EXI: + case __OS_INTERRUPT_EXI_1_TC: + case __OS_INTERRUPT_EXI_1_EXT: + reg = __EXIRegs[5]; + reg &= ~0xC0F; + + if (!(current & OS_INTERRUPTMASK_EXI_1_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_1_TC)) + reg |= 0x4; + if (!(current & OS_INTERRUPTMASK_EXI_1_EXT)) + reg |= 0x400; + __EXIRegs[5] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_1; + break; + case __OS_INTERRUPT_EXI_2_EXI: + case __OS_INTERRUPT_EXI_2_TC: + reg = __EXIRegs[10]; + reg &= ~0xF; + if (!(current & OS_INTERRUPTMASK_EXI_2_EXI)) + reg |= 0x1; + if (!(current & OS_INTERRUPTMASK_EXI_2_TC)) + reg |= 0x4; + + __EXIRegs[10] = reg; + mask &= ~OS_INTERRUPTMASK_EXI_2; + break; + case __OS_INTERRUPT_PI_CP: + case __OS_INTERRUPT_PI_SI: + case __OS_INTERRUPT_PI_DI: + case __OS_INTERRUPT_PI_RSW: + case __OS_INTERRUPT_PI_ERROR: + case __OS_INTERRUPT_PI_VI: + case __OS_INTERRUPT_PI_DEBUG: + case __OS_INTERRUPT_PI_PE_TOKEN: + case __OS_INTERRUPT_PI_PE_FINISH: + case __OS_INTERRUPT_PI_HSP: + reg = 0xF0; + + if (!(current & OS_INTERRUPTMASK_PI_CP)) { + reg |= 0x800; + } + if (!(current & OS_INTERRUPTMASK_PI_SI)) { + reg |= 0x8; + } + if (!(current & OS_INTERRUPTMASK_PI_DI)) { + reg |= 0x4; + } + if (!(current & OS_INTERRUPTMASK_PI_RSW)) { + reg |= 0x2; + } + if (!(current & OS_INTERRUPTMASK_PI_ERROR)) { + reg |= 0x1; + } + if (!(current & OS_INTERRUPTMASK_PI_VI)) { + reg |= 0x100; + } + if (!(current & OS_INTERRUPTMASK_PI_DEBUG)) { + reg |= 0x1000; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_TOKEN)) { + reg |= 0x200; + } + if (!(current & OS_INTERRUPTMASK_PI_PE_FINISH)) { + reg |= 0x400; + } + if (!(current & OS_INTERRUPTMASK_PI_HSP)) { + reg |= 0x2000; + } + __PIRegs[1] = reg; + mask &= ~OS_INTERRUPTMASK_PI; + break; + default: + break; + } + return mask; +} + +OSInterruptMask __OSMaskInterrupts(OSInterruptMask global) { + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = ~(prev | local) & global; + global |= prev; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +OSInterruptMask __OSUnmaskInterrupts(OSInterruptMask global) { + BOOL enabled; + OSInterruptMask prev; + OSInterruptMask local; + OSInterruptMask mask; + + enabled = OSDisableInterrupts(); + prev = *(OSInterruptMask*)OSPhysicalToCached(0x00C4); + local = *(OSInterruptMask*)OSPhysicalToCached(0x00C8); + mask = (prev | local) & global; + global = prev & ~global; + *(OSInterruptMask*)OSPhysicalToCached(0x00C4) = global; + while (mask) { + mask = SetInterruptMask(mask, global | local); + } + OSRestoreInterrupts(enabled); + return prev; +} + +volatile OSTime __OSLastInterruptTime; +volatile __OSInterrupt __OSLastInterrupt; +volatile u32 __OSLastInterruptSrr0; + +void __OSDispatchInterrupt(__OSException exception, OSContext* context) { + u32 intsr; + u32 reg; + OSInterruptMask cause; + OSInterruptMask unmasked; + OSInterruptMask* prio; + __OSInterrupt interrupt; + __OSInterruptHandler handler; + intsr = __PIRegs[0]; + intsr &= ~0x00010000; + + if (intsr == 0 || (intsr & __PIRegs[1]) == 0) { + OSLoadContext(context); + } + + cause = 0; + + if (intsr & 0x00000080) { + reg = __MEMRegs[15]; + if (reg & 0x1) + cause |= OS_INTERRUPTMASK_MEM_0; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_MEM_1; + if (reg & 0x4) + cause |= OS_INTERRUPTMASK_MEM_2; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_MEM_3; + if (reg & 0x10) + cause |= OS_INTERRUPTMASK_MEM_ADDRESS; + } + + if (intsr & 0x00000040) { + reg = __DSPRegs[5]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_DSP_AI; + if (reg & 0x20) + cause |= OS_INTERRUPTMASK_DSP_ARAM; + if (reg & 0x80) + cause |= OS_INTERRUPTMASK_DSP_DSP; + } + + if (intsr & 0x00000020) { + reg = __AIRegs[0]; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_AI_AI; + } + + if (intsr & 0x00000010) { + reg = __EXIRegs[0]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_0_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_0_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_0_EXT; + reg = __EXIRegs[5]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_1_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_1_TC; + if (reg & 0x800) + cause |= OS_INTERRUPTMASK_EXI_1_EXT; + reg = __EXIRegs[10]; + if (reg & 0x2) + cause |= OS_INTERRUPTMASK_EXI_2_EXI; + if (reg & 0x8) + cause |= OS_INTERRUPTMASK_EXI_2_TC; + } + + if (intsr & 0x00002000) + cause |= OS_INTERRUPTMASK_PI_HSP; + if (intsr & 0x00001000) + cause |= OS_INTERRUPTMASK_PI_DEBUG; + if (intsr & 0x00000400) + cause |= OS_INTERRUPTMASK_PI_PE_FINISH; + if (intsr & 0x00000200) + cause |= OS_INTERRUPTMASK_PI_PE_TOKEN; + if (intsr & 0x00000100) + cause |= OS_INTERRUPTMASK_PI_VI; + if (intsr & 0x00000008) + cause |= OS_INTERRUPTMASK_PI_SI; + if (intsr & 0x00000004) + cause |= OS_INTERRUPTMASK_PI_DI; + if (intsr & 0x00000002) + cause |= OS_INTERRUPTMASK_PI_RSW; + if (intsr & 0x00000800) + cause |= OS_INTERRUPTMASK_PI_CP; + if (intsr & 0x00000001) + cause |= OS_INTERRUPTMASK_PI_ERROR; + + unmasked = cause & ~(*(OSInterruptMask*)OSPhysicalToCached(0x00C4) | *(OSInterruptMask*)OSPhysicalToCached(0x00C8)); + if (unmasked) { + for (prio = InterruptPrioTable;; ++prio) { + if (unmasked & *prio) { + interrupt = (__OSInterrupt)__cntlzw(unmasked & *prio); + break; + } + } + + handler = __OSGetInterruptHandler(interrupt); + if (handler) { + if (__OS_INTERRUPT_MEM_ADDRESS < interrupt) { + __OSLastInterrupt = interrupt; + __OSLastInterruptTime = OSGetTime(); + __OSLastInterruptSrr0 = context->srr0; + } + + OSDisableScheduler(); + handler(interrupt, context); + OSEnableScheduler(); + __OSReschedule(); + OSLoadContext(context); + } + } + + OSLoadContext(context); +} + +static ASM void ExternalInterruptHandler(register __OSException exception, register OSContext* context) { +#pragma unused(exception) +#ifdef __MWERKS__ // clang-format off + nofralloc + OS_EXCEPTION_SAVE_GPRS(context) + + stwu r1, -8(r1) + b __OSDispatchInterrupt +#endif // clang-format on +} diff --git a/src/dolphin/os/OSLink.c b/src/dolphin/os/OSLink.c new file mode 100644 index 0000000..b55dec9 --- /dev/null +++ b/src/dolphin/os/OSLink.c @@ -0,0 +1,9 @@ +#include "dolphin/os.h" + +OSModuleQueue __OSModuleInfoList AT_ADDRESS(OS_BASE_CACHED | 0x30C8); +const void* __OSStringTable AT_ADDRESS(OS_BASE_CACHED | 0x30D0); + +void __OSModuleInit(void) { + __OSModuleInfoList.head = __OSModuleInfoList.tail = 0; + __OSStringTable = 0; +} diff --git a/src/dolphin/os/OSMemory.c b/src/dolphin/os/OSMemory.c new file mode 100644 index 0000000..24cca7d --- /dev/null +++ b/src/dolphin/os/OSMemory.c @@ -0,0 +1,197 @@ +#include "dolphin/os.h" +#include "macros.h" + +#define TRUNC(n, a) (((u32)(n)) & ~((a)-1)) +#define ROUND(n, a) (((u32)(n) + (a)-1) & ~((a)-1)) + +vu16 __MEMRegs[64] AT_ADDRESS(0xCC004000); +extern OSErrorHandler __OSErrorTable[16]; + +static BOOL OnReset(BOOL final); + +static OSResetFunctionInfo ResetFunctionInfo = { + OnReset, + 127, +}; + +static BOOL OnReset(BOOL final) { + if (final != FALSE) { + __MEMRegs[8] = 0xFF; + __OSMaskInterrupts(0xf0000000); + } + return TRUE; +} + +inline u32 OSGetPhysicalMemSize() { return *(u32*)(OSPhysicalToCached(0x0028)); } + +inline u32 OSGetConsoleSimulatedMemSize() { return *(u32*)(OSPhysicalToCached(0x00F0)); } + +static void MEMIntrruptHandler(__OSInterrupt interrupt, OSContext* context) { + u32 addr; + u32 cause; + + cause = __MEMRegs[0xf]; + addr = (((u32)__MEMRegs[0x12] & 0x3ff) << 16) | __MEMRegs[0x11]; + __MEMRegs[0x10] = 0; + + if (__OSErrorTable[OS_ERROR_PROTECTION]) { + __OSErrorTable[OS_ERROR_PROTECTION](OS_ERROR_PROTECTION, context, cause, addr); + return; + } + + __OSUnhandledException(OS_ERROR_PROTECTION, context, cause, addr); +} + +ASM void Config24MB() { +#ifdef __MWERKS__ // clang-format off + nofralloc + + addi r7,r0,0 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800001ff@ha + addi r3,r3,0x800001ff@l + + addis r6,r0,0x01000002@ha + addi r6,r6,0x01000002@l + addis r5,r0,0x810000ff@ha + addi r5,r5,0x810000ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi +#endif // clang-format on +} + +ASM void Config48MB() { +#ifdef __MWERKS__ // clang-format off + nofralloc + + addi r7,r0,0x0000 + + addis r4,r0,0x00000002@ha + addi r4,r4,0x00000002@l + addis r3,r0,0x800003ff@ha + addi r3,r3,0x800003ff@l + + addis r6,r0,0x02000002@ha + addi r6,r6,0x02000002@l + addis r5,r0,0x820001ff@ha + addi r5,r5,0x820001ff@l + + isync + + mtspr dbat0u,r7 + mtspr dbat0l,r4 + mtspr dbat0u,r3 + isync + + mtspr ibat0u,r7 + mtspr ibat0l,r4 + mtspr ibat0u,r3 + isync + + mtspr dbat2u,r7 + mtspr dbat2l,r6 + mtspr dbat2u,r5 + isync + + mtspr ibat2u,r7 + mtspr ibat2l,r6 + mtspr ibat2u,r5 + isync + + mfmsr r3 + ori r3, r3, 0x30 + mtsrr1 r3 + + mflr r3 + mtsrr0 r3 + rfi +#endif // clang-format on +} + +ASM void RealMode(register u32 addr) { +#ifdef __MWERKS__ // clang-format off + nofralloc + clrlwi r3, r3, 2 + mtsrr0 r3 + mfmsr r3 + rlwinm r3, r3, 0, 28, 25 + mtsrr1 r3 + rfi +#endif // clang-format on +} + +void __OSInitMemoryProtection() { + u32 padding[8]; + u32 simulatedSize; + BOOL enabled; + simulatedSize = OSGetConsoleSimulatedMemSize(); + enabled = OSDisableInterrupts(); + +#if DOLPHIN_REV == 2002 + if (simulatedSize <= 0x1800000) { + RealMode((u32)&Config24MB); + } else if (simulatedSize <= 0x3000000) { + RealMode((u32)&Config48MB); + } +#endif + + __MEMRegs[16] = 0; + __MEMRegs[8] = 0xFF; + + __OSMaskInterrupts(OS_INTERRUPTMASK_MEM_0 | OS_INTERRUPTMASK_MEM_1 | OS_INTERRUPTMASK_MEM_2 | + OS_INTERRUPTMASK_MEM_3); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_0, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_1, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_2, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_3, MEMIntrruptHandler); + __OSSetInterruptHandler(__OS_INTERRUPT_MEM_ADDRESS, MEMIntrruptHandler); + OSRegisterResetFunction(&ResetFunctionInfo); + + if (OSGetConsoleSimulatedMemSize() < OSGetPhysicalMemSize() && OSGetConsoleSimulatedMemSize() == 0x1800000) { +#if DOLPHIN_REV == 2003 + DCInvalidateRange((void*)0x81800000, 0x1800000); +#endif + __MEMRegs[20] = 2; + } + +#if DOLPHIN_REV == 2003 + if (simulatedSize <= 0x1800000) { + RealMode((u32)&Config24MB); + } else if (simulatedSize <= 0x3000000) { + RealMode((u32)&Config48MB); + } +#endif + + __OSUnmaskInterrupts(OS_INTERRUPTMASK_MEM_ADDRESS); + OSRestoreInterrupts(enabled); +} diff --git a/src/dolphin/os/OSMessage.c b/src/dolphin/os/OSMessage.c new file mode 100644 index 0000000..d0b473a --- /dev/null +++ b/src/dolphin/os/OSMessage.c @@ -0,0 +1,61 @@ +#include "dolphin/os.h" + +void OSInitMessageQueue(OSMessageQueue* mq, OSMessage* msgArray, s32 msgCount) { + OSInitThreadQueue(&mq->queueSend); + OSInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +BOOL OSSendMessage(OSMessageQueue* mq, OSMessage msg, s32 flags) { + BOOL enabled; + s32 lastIndex; + + enabled = OSDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueSend); + } + } + + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + OSWakeupThread(&mq->queueReceive); + + OSRestoreInterrupts(enabled); + return TRUE; +} + +BOOL OSReceiveMessage(OSMessageQueue* mq, OSMessage* msg, s32 flags) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + OSRestoreInterrupts(enabled); + return FALSE; + } else { + OSSleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + OSWakeupThread(&mq->queueSend); + + OSRestoreInterrupts(enabled); + return TRUE; +} diff --git a/src/dolphin/os/OSMutex.c b/src/dolphin/os/OSMutex.c new file mode 100644 index 0000000..4cee52b --- /dev/null +++ b/src/dolphin/os/OSMutex.c @@ -0,0 +1,25 @@ +#include "dolphin/os.h" + +#define PopHead(queue, mutex, link) \ + do { \ + OSMutex* __next; \ + \ + (mutex) = (queue)->head; \ + __next = (mutex)->link.next; \ + if (__next == NULL) \ + (queue)->tail = NULL; \ + else \ + __next->link.prev = NULL; \ + (queue)->head = __next; \ + } while (0) + +void __OSUnlockAllMutex(OSThread* thread) { + OSMutex* mutex; + + while (thread->queueMutex.head) { + PopHead(&thread->queueMutex, mutex, link); + mutex->count = 0; + mutex->thread = NULL; + OSWakeupThread(&mutex->queue); + } +} diff --git a/src/dolphin/os/OSReboot.c b/src/dolphin/os/OSReboot.c new file mode 100644 index 0000000..f247155 --- /dev/null +++ b/src/dolphin/os/OSReboot.c @@ -0,0 +1,126 @@ +#include "dolphin/dvd.h" +#include "dolphin/os.h" +#include "dolphin/os/OSBootInfo.h" +#include "macros.h" + +typedef struct ApploaderHeader { + // total size: 0x20 + char date[16]; // offset 0x0, size 0x10 + u32 entry; // offset 0x10, size 0x4 + u32 size; // offset 0x14, size 0x4 + u32 rebootSize; // offset 0x18, size 0x4 + u32 reserved2; // offset 0x1C, size 0x4 +} ApploaderHeader; + +static ApploaderHeader Header ALIGNAS(32); + +extern void* __OSSavedRegionStart; +extern void* __OSSavedRegionEnd; + +static void* SaveStart = NULL; +static void* SaveEnd = NULL; + +extern u32 UNK_817FFFF8 AT_ADDRESS(0x817FFFF8); +extern u32 UNK_817FFFFC AT_ADDRESS(0x817FFFFC); +extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0); +extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC); +extern u32 OS_RESET_CODE AT_ADDRESS(0x800030F0); +extern u8 OS_REBOOT_BOOL AT_ADDRESS(0x800030E2); // unknown function, set to true by __OSReboot +extern s32 __OSIsGcam; + +static BOOL Prepared = FALSE; + +void __OSDoHotReset(int); + +inline void ReadApploader(OSTime time1) { + if (DVDCheckDisk() == DVD_RESULT_GOOD || OSGetTime() - time1 > OS_TIMER_CLOCK) { + __OSDoHotReset(UNK_817FFFFC); + } +} + +#pragma dont_inline on + +ASM void Run() { +#ifdef __MWERKS__ // clang-format off + nofralloc + sync + isync + mtlr r3 + blr +#endif // clang-format on +} + +#pragma dont_inline reset + +static void Callback() { Prepared = TRUE; } + +#pragma peephole off + +inline BOOL IsStreamEnabled(void) { + if (DVDGetCurrentDiskID()->streaming) { + return TRUE; + } + return FALSE; +} + +void __OSReboot(u32 resetCode, u32 bootDol) { + OSContext exceptionContext; + OSTime time; + DVDCommandBlock dvdCmd; + DVDCommandBlock dvdCmd2; + DVDCommandBlock dvdCmd3; + u32 numBytes; + u32 offset; + + OSDisableInterrupts(); + UNK_817FFFFC = 0; + UNK_817FFFF8 = 0; + OS_REBOOT_BOOL = TRUE; + BOOT_REGION_START = (u32)SaveStart; + BOOT_REGION_END = (u32)SaveEnd; + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + DVDInit(); + DVDSetAutoInvalidation(TRUE); + DVDResume(); + Prepared = FALSE; + __DVDPrepareResetAsync(Callback); + __OSMaskInterrupts(~0x1F); + __OSUnmaskInterrupts(0x400); + OSEnableInterrupts(); + + time = OSGetTime(); + while (Prepared != TRUE) { + ReadApploader(time); + } + + if (!__OSIsGcam && IsStreamEnabled()) { + AISetStreamVolLeft(0); + AISetStreamVolRight(0); + DVDCancelStreamAsync(&dvdCmd, NULL); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd)) { + ReadApploader(time); + } + AISetStreamPlayState(0); + } + + DVDReadAbsAsyncPrio(&dvdCmd2, &Header, 32, 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd2)) { + ReadApploader(time); + } + + offset = Header.size + 0x20; + numBytes = OSRoundUp32B(Header.rebootSize); + DVDReadAbsAsyncPrio(&dvdCmd3, (void*)(OS_BOOTROM_ADDR), numBytes, offset + 0x2440, NULL, 0); + time = OSGetTime(); + while (DVDGetCommandBlockStatus(&dvdCmd3)) { + ReadApploader(time); + } + + ICInvalidateRange((void*)(OS_BOOTROM_ADDR), numBytes); + OSDisableInterrupts(); + ICFlashInvalidate(); + Run((void*)OS_BOOTROM_ADDR); +} diff --git a/src/dolphin/os/OSReset.c b/src/dolphin/os/OSReset.c new file mode 100644 index 0000000..e92b9f3 --- /dev/null +++ b/src/dolphin/os/OSReset.c @@ -0,0 +1,200 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/hw_regs.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" +#include "macros.h" + +typedef struct OSResetQueue { + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; +} OSResetQueue; + +static OSResetQueue ResetFunctionQueue; + +#if DOLPHIN_REV == 2003 +static u32 bootThisDol; +#endif + +void OSRegisterResetFunction(OSResetFunctionInfo* func) { + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; + + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) + ; + + if (iter == NULL) { + tmp = ResetFunctionQueue.last; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + } else { + tmp->next = func; + } + func->prev = tmp; + func->next = NULL; + ResetFunctionQueue.last = func; + return; + } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; + func->prev = tmp; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; +} + +inline BOOL __OSCallResetFunctions(u32 arg0) { + OSResetFunctionInfo* iter; + s32 retCode = 0; + +#if DOLPHIN_REV == 2002 + for (iter = ResetFunctionQueue.first; iter != NULL; iter = iter->next) +#else + for (iter = ResetFunctionQueue.first; iter != NULL && retCode == FALSE; iter = iter->next) +#endif + { + retCode |= !iter->func(arg0); + } + retCode |= !__OSSyncSram(); + if (retCode) { + return 0; + } + return 1; +} + +ASM void Reset(register s32 resetCode) { +#ifdef __MWERKS__ // clang-format off + nofralloc + b lbl_8038315C +lbl_80383140: + mfspr r8, HID0 + ori r8, r8, 8 + mtspr HID0, r8 + isync + sync + nop + b lbl_80383160 +lbl_8038315C: + b lbl_8038317C +lbl_80383160: + mftb r5, 268 +lbl_80383164: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt lbl_80383164 + nop + b lbl_80383180 +lbl_8038317C: + b lbl_8038319C +lbl_80383180: + lis r8, 0xCC003000@h + ori r8, r8, 0xCC003000@l + li r4, 3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b lbl_803831A0 +lbl_8038319C: + b lbl_803831A8 +lbl_803831A0: + nop + b lbl_803831A0 +lbl_803831A8: + b lbl_80383140 +#endif // clang-format on +} + +OSThreadQueue __OSActiveThreadQueue AT_ADDRESS(OS_BASE_CACHED | 0x00DC); + +inline void KillThreads(void) { + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) { + next = thread->linkActive.next; + switch (thread->state) { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } + } +} + +void __OSDoHotReset(s32 arg0) { + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); +} + +void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; + OSDisableScheduler(); + __OSStopAudioSystem(); + +#if DOLPHIN_REV == 2002 + if (reset == OS_RESET_SHUTDOWN) +#else + if (reset == OS_RESET_SHUTDOWN || (reset == OS_RESET_RESTART && bootThisDol != 0)) +#endif + { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + while (!__OSCallResetFunctions(FALSE)) + ; + + if (reset == OS_RESET_HOTRESET && forceMenu) { + OSSram* sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); + + while (!__OSSyncSram()) + ; + } + + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + + if (reset == OS_RESET_HOTRESET) { + __OSDoHotReset(resetCode); + } else if (reset == OS_RESET_RESTART) { +#if DOLPHIN_REV == 2003 + if ((*(u32*)OSPhysicalToCached(0x30EC) = bootThisDol) != 0) { + __PADDisableRecalibration(disableRecalibration); + } +#endif + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); + } + KillThreads(); + memset(OSPhysicalToCached(0x40), 0, 0xcc - 0x40); + memset(OSPhysicalToCached(0xd4), 0, 0xe8 - 0xd4); + memset(OSPhysicalToCached(0xf4), 0, 0xf8 - 0xf4); + memset(OSPhysicalToCached(0x3000), 0, 0xc0); + memset(OSPhysicalToCached(0x30c8), 0, 0xd4 - 0xc8); + memset(OSPhysicalToCached(0x30e2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); +} + +u32 OSGetResetCode(void) { + if (*(u8*)OSPhysicalToCached(0x30E2) != 0) { + return 0x80000000; + } + + return ((__PIRegs[PI_RESETCODE] & ~7) >> 3); +} diff --git a/src/dolphin/os/OSResetSW.c b/src/dolphin/os/OSResetSW.c new file mode 100644 index 0000000..7abd3fe --- /dev/null +++ b/src/dolphin/os/OSResetSW.c @@ -0,0 +1,99 @@ +#include "dolphin/os.h" + +extern OSTime __OSGetSystemTime(); + +u8 GameChoice AT_ADDRESS(OS_BASE_CACHED | 0x30E3); + +vu32 __PIRegs[12] AT_ADDRESS(0xCC003000); + +extern OSTime __OSStartTime; + +#if DOLPHIN_REV == 2002 +//! TODO: find what's wrong with sbss on mq +static BOOL bootThisDol; +#endif + +static OSResetCallback ResetCallback; +static BOOL Down; +static BOOL LastState; +static OSTime HoldUp; +static OSTime HoldDown; + +void __OSResetSWInterruptHandler(__OSInterrupt interrupt, OSContext* context) { + OSResetCallback callback; + + HoldDown = __OSGetSystemTime(); + while (__OSGetSystemTime() - HoldDown < OSMicrosecondsToTicks(100) && !(__PIRegs[0] & 0x00010000)) { + ; + } + if (!(__PIRegs[0] & 0x00010000)) { + LastState = Down = TRUE; + __OSMaskInterrupts(OS_INTERRUPTMASK_PI_RSW); + if (ResetCallback) { + callback = ResetCallback; + ResetCallback = NULL; + callback(); + } + } + __PIRegs[0] = 2; +} + +#if DOLPHIN_REV == 2002 +#define GAME_CHOICE_MASK 0x3F +#else +#define GAME_CHOICE_MASK 0x1F +#endif + +BOOL OSGetResetButtonState(void) { + BOOL enabled; + BOOL state; + u32 reg; + OSTime now; + + enabled = OSDisableInterrupts(); + + now = __OSGetSystemTime(); + + reg = __PIRegs[0]; + if (!(reg & 0x00010000)) { + if (!Down) { + Down = TRUE; + state = HoldUp ? TRUE : FALSE; + HoldDown = now; + } else { + state = (HoldUp || (OSMicrosecondsToTicks(100) < now - HoldDown)) ? TRUE : FALSE; + } + } else if (Down) { + Down = FALSE; + state = LastState; + if (state) { + HoldUp = now; + } else { + HoldUp = 0; + } + } else if (HoldUp && (now - HoldUp < OSMillisecondsToTicks(40))) { + state = TRUE; + } else { + state = FALSE; + HoldUp = 0; + } + + LastState = state; + + if (GameChoice & GAME_CHOICE_MASK) { + OSTime fire = (GameChoice & GAME_CHOICE_MASK) * 60; + fire = __OSStartTime + OSSecondsToTicks(fire); + if (fire < now) { + now -= fire; + now = OSTicksToSeconds(now) / 2; + if ((now & 1) == 0) { + state = TRUE; + } else { + state = FALSE; + } + } + } + + OSRestoreInterrupts(enabled); + return state; +} diff --git a/src/dolphin/os/OSRtc.c b/src/dolphin/os/OSRtc.c new file mode 100644 index 0000000..a923f77 --- /dev/null +++ b/src/dolphin/os/OSRtc.c @@ -0,0 +1,243 @@ +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" + +#define RTC_CMD_READ 0x20000000 +#define RTC_CMD_WRITE 0xa0000000 + +#define RTC_SRAM_ADDR 0x00000100 +#define RTC_SRAM_SIZE 64 + +#define RTC_CHAN 0 +#define RTC_DEV 1 +#define RTC_FREQ 3 // EXI_FREQ_8M + +typedef struct SramControlBlock { + u8 sram[RTC_SRAM_SIZE]; + u32 offset; + BOOL enabled; + BOOL locked; + BOOL sync; + void (*callback)(void); +} SramControlBlock; + +static SramControlBlock Scb ATTRIBUTE_ALIGN(32); + +#if DOLPHIN_REV == 2003 +u16 OSGetGbsMode(); +void OSSetGbsMode(u16 mode); +#endif + +static inline BOOL ReadSram(void* buffer) { + BOOL err; + u32 cmd; + + DCInvalidateRange(buffer, RTC_SRAM_SIZE); + + if (!EXILock(RTC_CHAN, RTC_DEV, 0)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + cmd = RTC_CMD_READ | RTC_SRAM_ADDR; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDma(RTC_CHAN, buffer, RTC_SRAM_SIZE, 0, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size); +static void WriteSramCallback(s32 chan, OSContext* context) { + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) { + Scb.offset = RTC_SRAM_SIZE; + } +} + +BOOL WriteSram(void* buffer, u32 offset, u32 size) { + BOOL err; + u32 cmd; + + if (!EXILock(RTC_CHAN, RTC_DEV, WriteSramCallback)) { + return FALSE; + } + if (!EXISelect(RTC_CHAN, RTC_DEV, RTC_FREQ)) { + EXIUnlock(RTC_CHAN); + return FALSE; + } + + offset <<= 6; + cmd = RTC_CMD_WRITE | RTC_SRAM_ADDR + offset; + err = FALSE; + err |= !EXIImm(RTC_CHAN, &cmd, 4, 1, NULL); + err |= !EXISync(RTC_CHAN); + err |= !EXIImmEx(RTC_CHAN, buffer, (s32)size, 1); + err |= !EXIDeselect(RTC_CHAN); + EXIUnlock(RTC_CHAN); + + return !err; +} + +void __OSInitSram() { + Scb.locked = Scb.enabled = FALSE; + Scb.sync = ReadSram(Scb.sram); + Scb.offset = RTC_SRAM_SIZE; +#if DOLPHIN_REV == 2003 + OSSetGbsMode(OSGetGbsMode()); +#endif +} + +static inline void* LockSram(u32 offset) { + BOOL enabled; + enabled = OSDisableInterrupts(); + + if (Scb.locked != FALSE) { + OSRestoreInterrupts(enabled); + return NULL; + } + + Scb.enabled = enabled; + Scb.locked = TRUE; + + return Scb.sram + offset; +} + +OSSram* __OSLockSram() { return LockSram(0); } + +OSSramEx* __OSLockSramEx() { return LockSram(sizeof(OSSram)); } + +static BOOL UnlockSram(BOOL commit, u32 offset) { + u16* p; + + if (commit) { + if (offset == 0) { + OSSram* sram = (OSSram*)Scb.sram; + + if (2u < (sram->flags & 3)) { + sram->flags &= ~3; + } + + sram->checkSum = sram->checkSumInv = 0; + for (p = (u16*)&sram->counterBias; p < (u16*)(Scb.sram + sizeof(OSSram)); p++) { + sram->checkSum += *p; + sram->checkSumInv += ~*p; + } + } + + if (offset < Scb.offset) { + Scb.offset = offset; + } + +#if DOLPHIN_REV == 2003 + if (Scb.offset <= 20) { + // this seems to work? esp. since we have GbsMode functions when prime doesn't + // wacky tho + OSSramEx* sramEx = (OSSramEx*)(&Scb.sram[20]); + if ((u32)(sramEx->gbs & 0x7C00) == 0x5000 || (u32)(sramEx->gbs & 0xC0) == 0xC0) { + sramEx->gbs = 0; + } + } +#endif + + Scb.sync = WriteSram(Scb.sram + Scb.offset, Scb.offset, RTC_SRAM_SIZE - Scb.offset); + if (Scb.sync) { + Scb.offset = RTC_SRAM_SIZE; + } + } + Scb.locked = FALSE; + OSRestoreInterrupts(Scb.enabled); + return Scb.sync; +} + +BOOL __OSUnlockSram(BOOL commit) { return UnlockSram(commit, 0); } + +BOOL __OSUnlockSramEx(BOOL commit) { return UnlockSram(commit, sizeof(OSSram)); } + +BOOL __OSSyncSram() { return Scb.sync; } + +inline OSSram* __OSLockSramHACK() { return LockSram(0); } +u32 OSGetSoundMode() { + OSSram* sram; + u32 mode; + + sram = __OSLockSramHACK(); + mode = (sram->flags & 0x4) ? OS_SOUND_MODE_STEREO : OS_SOUND_MODE_MONO; + __OSUnlockSram(FALSE); + return mode; +} + +void OSSetSoundMode(u32 mode) { + OSSram* sram; + mode <<= 2; + mode &= 4; + + sram = __OSLockSramHACK(); + if (mode == (sram->flags & 4)) { + __OSUnlockSram(FALSE); + return; + } + + sram->flags &= ~4; + sram->flags |= mode; + __OSUnlockSram(TRUE); +} + +u16 OSGetWirelessID(s32 channel) { + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->wirelessPadID[channel]; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetWirelessID(s32 channel, u16 id) { + OSSramEx* sram; + + sram = __OSLockSramEx(); + if (sram->wirelessPadID[channel] != id) { + sram->wirelessPadID[channel] = id; + __OSUnlockSramEx(TRUE); + return; + } + + __OSUnlockSramEx(FALSE); +} + +#if DOLPHIN_REV == 2003 +u16 OSGetGbsMode() { + OSSramEx* sram; + u16 id; + + sram = __OSLockSramEx(); + id = sram->gbs; + __OSUnlockSramEx(FALSE); + return id; +} + +void OSSetGbsMode(u16 mode) { + OSSramEx* sram; + + // same odd code as in UnlockSram? + if ((u32)(mode & 0x7C00) == 0x5000 || (u32)(mode & 0xC0) == 0xC0) { + mode = 0; + } + + sram = __OSLockSramEx(); + if (mode == sram->gbs) { + __OSUnlockSramEx(FALSE); + return; + } + + sram->gbs = mode; + __OSUnlockSramEx(TRUE); +} +#endif diff --git a/src/dolphin/os/OSSync.c b/src/dolphin/os/OSSync.c new file mode 100644 index 0000000..09c99ff --- /dev/null +++ b/src/dolphin/os/OSSync.c @@ -0,0 +1,33 @@ +#include "dolphin/base/PPCArch.h" +#include "dolphin/os.h" +#include "macros.h" +#include "string.h" + +void __OSSystemCallVectorStart(); +void __OSSystemCallVectorEnd(); + +static ASM void SystemCallVector() { +#ifdef __MWERKS__ // clang-format off + nofralloc +entry __OSSystemCallVectorStart + mfspr r9, HID0 + ori r10, r9, 8 + mtspr HID0, r10 + isync + sync + mtspr HID0, r9 + + rfi + +entry __OSSystemCallVectorEnd + nop +#endif // clang-format on +} + +void __OSInitSystemCall() { + void* addr = OSPhysicalToCached(0x00C00); + memcpy(addr, __OSSystemCallVectorStart, (size_t)__OSSystemCallVectorEnd - (size_t)__OSSystemCallVectorStart); + DCFlushRangeNoSync(addr, 0x100); + __sync(); + ICInvalidateRange(addr, 0x100); +} diff --git a/src/dolphin/os/OSThread.c b/src/dolphin/os/OSThread.c new file mode 100644 index 0000000..a37136a --- /dev/null +++ b/src/dolphin/os/OSThread.c @@ -0,0 +1,532 @@ +#include "dolphin/os/OSPriv.h" + +static vu32 RunQueueBits; +static volatile BOOL RunQueueHint; +static vs32 Reschedule; + +static OSThreadQueue RunQueue[32]; +static OSThread IdleThread; +static OSThread DefaultThread; +static OSContext IdleContext; +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to); +static OSSwitchThreadCallback SwitchThreadCallback = DefaultSwitchThreadCallback; + +OSThread* __OSCurrentThread AT_ADDRESS(OS_BASE_CACHED + 0x00E4); +OSThreadQueue __OSActiveThreadQueue AT_ADDRESS(OS_BASE_CACHED + 0x00DC); +volatile OSContext __OSCurrentContext AT_ADDRESS(OS_BASE_CACHED + 0x00D4); +volatile OSContext* __OSFPUContext AT_ADDRESS(OS_BASE_CACHED + 0x00D8); + +static void DefaultSwitchThreadCallback(OSThread* from, OSThread* to) {} + +extern u8 _stack_addr[]; +extern u8 _stack_end[]; +extern u32 __OSFpscrEnableBits; +extern OSErrorHandler __OSErrorTable[OS_ERROR_MAX + 2]; // fake? + +#define AddTail(queue, thread, link) \ + do { \ + OSThread* prev; \ + \ + prev = (queue)->tail; \ + if (prev == NULL) \ + (queue)->head = (thread); \ + else \ + prev->link.next = (thread); \ + (thread)->link.prev = prev; \ + (thread)->link.next = NULL; \ + (queue)->tail = (thread); \ + } while (0) + +#define AddPrio(queue, thread, link) \ + do { \ + OSThread *prev, *next; \ + \ + for (next = (queue)->head; next && next->priority <= thread->priority; next = next->link.next) \ + ; \ + if (next == NULL) \ + AddTail(queue, thread, link); \ + else { \ + (thread)->link.next = next; \ + prev = next->link.prev; \ + next->link.prev = (thread); \ + (thread)->link.prev = prev; \ + if (prev == NULL) \ + (queue)->head = (thread); \ + else \ + prev->link.next = (thread); \ + } \ + } while (0) + +#define RemoveItem(queue, thread, link) \ + do { \ + OSThread *next, *prev; \ + next = (thread)->link.next; \ + prev = (thread)->link.prev; \ + if (next == NULL) \ + (queue)->tail = prev; \ + else \ + next->link.prev = prev; \ + if (prev == NULL) \ + (queue)->head = next; \ + else \ + prev->link.next = next; \ + } while (0) + +#define RemoveHead(queue, thread, link) \ + do { \ + OSThread* __next; \ + (thread) = (queue)->head; \ + __next = (thread)->link.next; \ + if (__next == NULL) \ + (queue)->tail = NULL; \ + else \ + __next->link.prev = NULL; \ + (queue)->head = __next; \ + } while (0) + +static inline void OSInitMutexQueue(OSMutexQueue* queue) { queue->head = queue->tail = NULL; } + +static inline void OSSetCurrentThread(OSThread* thread) { + SwitchThreadCallback(__OSCurrentThread, thread); + __OSCurrentThread = thread; +} + +void __OSThreadInit() { + OSThread* thread = &DefaultThread; + int prio; + + thread->state = OS_THREAD_STATE_RUNNING; + thread->attr = OS_THREAD_ATTR_DETACH; + thread->priority = thread->base = 16; + thread->suspend = 0; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + + __OSFPUContext = &thread->context; + + OSClearContext(&thread->context); + OSSetCurrentContext(&thread->context); + thread->stackBase = (void*)_stack_addr; + thread->stackEnd = (void*)_stack_end; + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + + OSSetCurrentThread(thread); + OSClearStack(0); + + RunQueueBits = 0; + RunQueueHint = FALSE; + for (prio = OS_PRIORITY_MIN; prio <= OS_PRIORITY_MAX; ++prio) { + OSInitThreadQueue(&RunQueue[prio]); + } + + OSInitThreadQueue(&__OSActiveThreadQueue); + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSClearContext(&IdleContext); + Reschedule = 0; +} + +void OSInitThreadQueue(OSThreadQueue* queue) { queue->head = queue->tail = NULL; } + +OSThread* OSGetCurrentThread() { return __OSCurrentThread; } + +s32 OSDisableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule++; + OSRestoreInterrupts(enabled); + return count; +} + +s32 OSEnableScheduler() { + BOOL enabled; + s32 count; + + enabled = OSDisableInterrupts(); + count = Reschedule--; + OSRestoreInterrupts(enabled); + return count; +} + +static inline void SetRun(OSThread* thread) { + thread->queue = &RunQueue[thread->priority]; + AddTail(thread->queue, thread, link); + RunQueueBits |= 1u << (OS_PRIORITY_MAX - thread->priority); + RunQueueHint = TRUE; +} + +#pragma dont_inline on +static void UnsetRun(OSThread* thread) { + OSThreadQueue* queue; + queue = thread->queue; + RemoveItem(queue, thread, link); + if (queue->head == 0) + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - thread->priority)); + thread->queue = NULL; +} +#pragma dont_inline reset + +OSPriority __OSGetEffectivePriority(OSThread* thread) { + OSPriority priority; + OSMutex* mutex; + OSThread* blocked; + + priority = thread->base; + for (mutex = thread->queueMutex.head; mutex; mutex = mutex->link.next) { + blocked = mutex->queue.head; + if (blocked && blocked->priority < priority) { + priority = blocked->priority; + } + } + return priority; +} + +static OSThread* SetEffectivePriority(OSThread* thread, OSPriority priority) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + UnsetRun(thread); + thread->priority = priority; + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = priority; + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + return thread->mutex->thread; + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->priority = priority; + break; + } + return NULL; +} + +static inline void UpdatePriority(OSThread* thread) { + OSPriority priority; + + do { + if (0 < thread->suspend) { + break; + } + priority = __OSGetEffectivePriority(thread); + if (thread->priority == priority) { + break; + } + thread = SetEffectivePriority(thread, priority); + } while (thread); +} + +static inline void __OSSwitchThread(OSThread* nextThread) { + OSSetCurrentThread(nextThread); + OSSetCurrentContext(&nextThread->context); + OSLoadContext(&nextThread->context); +} + +static OSThread* SelectThread(BOOL yield) { + OSContext* currentContext; + OSThread* currentThread; + OSThread* nextThread; + OSPriority priority; + OSThreadQueue* queue; + + if (0 < Reschedule) { + return 0; + } + + currentContext = OSGetCurrentContext(); + currentThread = OSGetCurrentThread(); + if (currentContext != ¤tThread->context) { + return 0; + } + + if (currentThread) { + if (currentThread->state == OS_THREAD_STATE_RUNNING) { + if (!yield) { + priority = __cntlzw(RunQueueBits); + if (currentThread->priority <= priority) { + return 0; + } + } + currentThread->state = OS_THREAD_STATE_READY; + SetRun(currentThread); + } + + if (!(currentThread->context.state & OS_CONTEXT_STATE_EXC) && OSSaveContext(¤tThread->context)) { + return 0; + } + } + +#if DOLPHIN_REV == 2002 + OSSetCurrentThread(NULL); +#endif + + if (RunQueueBits == 0) { +#if DOLPHIN_REV == 2003 + OSSetCurrentThread(NULL); +#endif + + OSSetCurrentContext(&IdleContext); + do { + OSEnableInterrupts(); + while (RunQueueBits == 0) + ; + OSDisableInterrupts(); + } while (RunQueueBits == 0); + + OSClearContext(&IdleContext); + } + + RunQueueHint = FALSE; + + priority = __cntlzw(RunQueueBits); + queue = &RunQueue[priority]; + RemoveHead(queue, nextThread, link); + if (queue->head == 0) { + RunQueueBits &= ~(1u << (OS_PRIORITY_MAX - priority)); + } + nextThread->queue = NULL; + nextThread->state = OS_THREAD_STATE_RUNNING; + __OSSwitchThread(nextThread); + return nextThread; +} + +void __OSReschedule() { + if (!RunQueueHint) { + return; + } + + SelectThread(FALSE); +} + +BOOL OSCreateThread(OSThread* thread, void* (*func)(void*), void* param, void* stack, u32 stackSize, + OSPriority priority, u16 attr) { + BOOL enable; + u32 stackThing; + int i; + u32 tmp[2]; // DUMB compiler smfh. + + if (priority < OS_PRIORITY_MIN || priority > OS_PRIORITY_MAX) { + return FALSE; + } + + stackThing = ((u32)stack & 0xFFFFFFF8); // ?? + thread->state = OS_THREAD_STATE_READY; + thread->attr = attr & OS_THREAD_ATTR_DETACH; + thread->base = priority; + thread->priority = priority; + thread->suspend = 1; + thread->val = (void*)-1; + thread->mutex = NULL; + OSInitThreadQueue(&thread->queueJoin); + OSInitMutexQueue(&thread->queueMutex); + *(u32*)(stackThing - 8) = 0; + *(u32*)(stackThing - 4) = 0; + + OSInitContext(&thread->context, (u32)func, (u32)(stackThing - 8)); + + thread->context.lr = (u32)&OSExitThread; + thread->context.gpr[3] = (u32)param; + thread->stackBase = stack; + thread->stackEnd = (u32*)((u32)stack - stackSize); + *(thread->stackEnd) = OS_THREAD_STACK_MAGIC; + thread->error = 0; + thread->specific[0] = NULL; + thread->specific[1] = NULL; + + enable = OSDisableInterrupts(); + + if (__OSErrorTable[16] != NULL) { + thread->context.srr1 |= 0x900; // ?? + thread->context.state |= OS_CONTEXT_STATE_FPSAVED; + thread->context.fpscr = (__OSFpscrEnableBits & 0xF8) | 0x4; // ?? + + for (i = 0; i < 32; i++) { + *(u64*)&thread->context.fpr[i] = -1; // ??????? + *(u64*)&thread->context.psf[i] = -1; // ??????? + } + } + + AddTail(&__OSActiveThreadQueue, thread, linkActive); + OSRestoreInterrupts(enable); + return TRUE; +} + +void OSExitThread(void* val) { + OSThread* thread; + BOOL enable; + + enable = OSDisableInterrupts(); + thread = __OSCurrentThread; + OSClearContext(&thread->context); + + if (thread->attr & OS_THREAD_ATTR_DETACH) { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + + } else { + thread->state = OS_THREAD_STATE_MORIBUND; + thread->val = val; + } + + __OSUnlockAllMutex(thread); + OSWakeupThread(&thread->queueJoin); + RunQueueHint = TRUE; + if (RunQueueHint != FALSE) { + SelectThread(FALSE); + } + + OSRestoreInterrupts(enable); +} + +void OSCancelThread(OSThread* thread) { + BOOL enabled; + + enabled = OSDisableInterrupts(); + + switch (thread->state) { + case OS_THREAD_STATE_READY: + if (!(0 < thread->suspend)) { + UnsetRun(thread); + } + break; + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->queue = NULL; + if (!(0 < thread->suspend) && thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + default: + OSRestoreInterrupts(enabled); + return; + } + + OSClearContext(&thread->context); + if (thread->attr & OS_THREAD_ATTR_DETACH) { + RemoveItem(&__OSActiveThreadQueue, thread, linkActive); + thread->state = 0; + } else { + thread->state = OS_THREAD_STATE_MORIBUND; + } + + __OSUnlockAllMutex(thread); + + OSWakeupThread(&thread->queueJoin); + + __OSReschedule(); + OSRestoreInterrupts(enabled); + + return; +} + +s32 OSResumeThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend--; + if (thread->suspend < 0) { + thread->suspend = 0; + } else if (thread->suspend == 0) { + switch (thread->state) { + case OS_THREAD_STATE_READY: + thread->priority = __OSGetEffectivePriority(thread); + SetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = __OSGetEffectivePriority(thread); + AddPrio(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +s32 OSSuspendThread(OSThread* thread) { + BOOL enabled; + s32 suspendCount; + + enabled = OSDisableInterrupts(); + suspendCount = thread->suspend++; + if (suspendCount == 0) { + switch (thread->state) { + case OS_THREAD_STATE_RUNNING: + RunQueueHint = TRUE; + thread->state = OS_THREAD_STATE_READY; + break; + case OS_THREAD_STATE_READY: + UnsetRun(thread); + break; + case OS_THREAD_STATE_WAITING: + RemoveItem(thread->queue, thread, link); + thread->priority = 32; + AddTail(thread->queue, thread, link); + if (thread->mutex) { + UpdatePriority(thread->mutex->thread); + } + break; + } + + __OSReschedule(); + } + OSRestoreInterrupts(enabled); + return suspendCount; +} + +void OSSleepThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* currentThread; + + enabled = OSDisableInterrupts(); + currentThread = OSGetCurrentThread(); + + currentThread->state = OS_THREAD_STATE_WAITING; + currentThread->queue = queue; + AddPrio(queue, currentThread, link); + RunQueueHint = TRUE; + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +void OSWakeupThread(OSThreadQueue* queue) { + BOOL enabled; + OSThread* thread; + + enabled = OSDisableInterrupts(); + while (queue->head) { + RemoveHead(queue, thread, link); + thread->state = OS_THREAD_STATE_READY; + if (!(0 < thread->suspend)) { + SetRun(thread); + } + } + __OSReschedule(); + OSRestoreInterrupts(enabled); +} + +void OSClearStack(u8 val) { + register u32 sp; + register u32* p; + register u32 pattern; + + pattern = ((u32)val << 24) | ((u32)val << 16) | ((u32)val << 8) | (u32)val; + sp = OSGetStackPointer(); + for (p = __OSCurrentThread->stackEnd + 1; p < (u32*)sp; ++p) { + *p = pattern; + } +} diff --git a/src/dolphin/os/OSTime.c b/src/dolphin/os/OSTime.c new file mode 100644 index 0000000..cc00e19 --- /dev/null +++ b/src/dolphin/os/OSTime.c @@ -0,0 +1,129 @@ +#include "dolphin/os.h" +#include "macros.h" + +#define OS_TIME_MONTH_MAX 12 +#define OS_TIME_WEEK_DAY_MAX 7 +#define OS_TIME_YEAR_DAY_MAX 365 + +// End of each month in standard year +static s32 YearDays[OS_TIME_MONTH_MAX] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; +// End of each month in leap year +static s32 LeapYearDays[OS_TIME_MONTH_MAX] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}; + +ASM OSTime OSGetTime(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc +@0 + mftbu r3 + mftb r4 + + // Check for possible carry from TBL to TBU + mftbu r5 + cmpw r3, r5 + bne @0 + + blr +#endif // clang-format on +} + +ASM OSTick OSGetTick(void){ +#ifdef __MWERKS__ // clang-format off + nofralloc + + mftb r3 + blr +#endif // clang-format on +} + +#define OS_SYSTEMTIME_BASE 0x30D8 + +OSTime __OSGetSystemTime(void) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + OSGetTime(); + OSRestoreInterrupts(enabled); + + return result; +} + +inline OSTime __OSTimeToSystemTime(OSTime time) { + BOOL enabled; + OSTime* timeAdjustAddr = (OSTime*)(OS_BASE_CACHED + OS_SYSTEMTIME_BASE); + OSTime result; + + enabled = OSDisableInterrupts(); + result = *timeAdjustAddr + time; + OSRestoreInterrupts(enabled); + + return result; +} + +inline static BOOL IsLeapYear(s32 year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } + +inline static s32 GetYearDays(s32 year, s32 mon) { return (IsLeapYear(year) ? LeapYearDays : YearDays)[mon]; } + +inline static s32 GetLeapDays(s32 year) { + if (year < 1) { + return 0; + } + return (year + 3) / 4 - (year - 1) / 100 + (year - 1) / 400; +} + +static void GetDates(s32 days, OSCalendarTime* cal) { + s32 year; + s32 totalDays; + s32* p_days; + s32 month; + cal->wday = (days + 6) % OS_TIME_WEEK_DAY_MAX; + + for (year = days / OS_TIME_YEAR_DAY_MAX; days < (totalDays = year * OS_TIME_YEAR_DAY_MAX + GetLeapDays(year));) { + year--; + } + + days -= totalDays; + cal->year = year; + cal->yday = days; + + p_days = IsLeapYear(year) ? LeapYearDays : YearDays; + month = OS_TIME_MONTH_MAX; + while (days < p_days[--month]) { + ; + } + cal->mon = month; + cal->mday = days - p_days[month] + 1; +} + +#define BIAS (2000 * 365 + (2000 + 3) / 4 - (2000 - 1) / 100 + (2000 - 1) / 400) + +#pragma push +#pragma dont_inline on +void OSTicksToCalendarTime(OSTime ticks, OSCalendarTime* td) { + int days; + int secs; + OSTime d; + + d = ticks % OSSecondsToTicks(1); + if (d < 0) { + d += OSSecondsToTicks(1); + } + td->usec = (int)(OSTicksToMicroseconds(d) % 1000); + td->msec = (int)(OSTicksToMilliseconds(d) % 1000); + + ticks -= d; + days = (int)(OSTicksToSeconds(ticks) / 86400 + BIAS); + secs = (int)(OSTicksToSeconds(ticks) % 86400); + if (secs < 0) { + days -= 1; + secs += 24 * 60 * 60; + } + + GetDates(days, td); + + td->hour = secs / 60 / 60; + td->min = (secs / 60) % 60; + td->sec = secs % 60; +} +#pragma dont_inline reset diff --git a/src/dolphin/os/__ppc_eabi_init.c b/src/dolphin/os/__ppc_eabi_init.c new file mode 100644 index 0000000..1e307d6 --- /dev/null +++ b/src/dolphin/os/__ppc_eabi_init.c @@ -0,0 +1,74 @@ +#include "dolphin/__ppc_eabi_init.h" +#include "dolphin/base/PPCArch.h" +#include "macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void __OSPSInit(); +void __OSCacheInit(); + +ASM void __init_hardware(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r0 + ori r0, r0, 0x2000 + mtmsr r0 + + mflr r31 + bl __OSPSInit + #if DOLPHIN_REV == 2003 + bl __OSFPRInit + #endif + bl __OSCacheInit + mtlr r31 + blr +#endif // clang-format on +} + +ASM void __flush_cache(register void* address, register unsigned int size) { +#ifdef __MWERKS__ // clang-format off + nofralloc + lis r5, ~0 + ori r5, r5, ~14 + and r5, r5, r3 + subf r3, r5, r3 + add r4, r4, r3 + +loop: + dcbst r0, r5 + sync + icbi r0, r5 + addic r5, r5, 8 + subic. r4, r4, 8 + bge loop + isync + blr +#endif // clang-format on +} + +void InitMetroTRK_BBA() { return; } + +void __init_user() { __init_cpp(); } + +typedef void (*voidfunctionptr)(void); // pointer to function returning void +INIT extern voidfunctionptr _ctors[]; +INIT extern voidfunctionptr _dtors[]; + +void __init_cpp(void) { + voidfunctionptr* constructor; + + /* + * call static initializers + */ + for (constructor = _ctors; *constructor; constructor++) { + (*constructor)(); + } +} + +void _ExitProcess(void) { PPCHalt(); } + +#ifdef __cplusplus +} +#endif diff --git a/src/dolphin/os/__start.c b/src/dolphin/os/__start.c new file mode 100644 index 0000000..dcf7493 --- /dev/null +++ b/src/dolphin/os/__start.c @@ -0,0 +1,227 @@ +#include "dolphin/__start.h" +#include "__ppc_eabi_linker.h" +#include "dolphin/__ppc_eabi_init.h" +#include "macros.h" + +static void __init_registers(void); + +void __check_pad3(void) { + if ((Pad3Button & 0x0eef) == 0x0eef) { + OSResetSystem(OS_RESET_RESTART, 0, FALSE); + } + return; +} + +#if DOLPHIN_REV == 2003 +INIT static void __set_debug_bba(void) { Debug_BBA = 1; } +INIT static u8 __get_debug_bba(void) { return Debug_BBA; } +#endif + +WEAK ASM void __start(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + bl __init_registers + bl __init_hardware + li r0, -1 + stwu r1, -8(r1) + stw r0, 4(r1) + stw r0, 0(r1) + bl __init_data + li r0, 0 + lis r6, EXCEPTIONMASK_ADDR@ha + addi r6, r6, EXCEPTIONMASK_ADDR@l + stw r0, 0(r6) + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r6, 0(r6) + +_check_TRK: + cmplwi r6, 0 + beq _load_lomem_debug_flag + lwz r7, OS_BI2_DEBUGFLAG_OFFSET(r6) + b _check_debug_flag + +_load_lomem_debug_flag: + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + lwz r5, 0(r5) + cmplwi r5, 0 + beq _goto_main + lis r7, DEBUGFLAG_ADDR@ha + addi r7, r7, DEBUGFLAG_ADDR@l + lwz r7, 0(r7) + +#if DOLPHIN_REV == 2002 +_check_debug_flag: + li r5, 0 + cmplwi r7, 2 + beq _goto_inittrk + cmplwi r7, 3 + bne _goto_main + li r5, 1 +#else +_check_debug_flag: + li r5, 0 + cmplwi r7, 2 + beq _goto_inittrk + cmplwi r7, 3 + li r5, 1 + beq _goto_inittrk + cmplwi r7, 4 + bne _goto_main + li r5, 2 + bl __set_debug_bba + b _goto_main +#endif + +_goto_inittrk: + lis r6, InitMetroTRK@ha + addi r6, r6, InitMetroTRK@l + mtlr r6 + blrl + +_goto_main: + lis r6, BOOTINFO2_ADDR@ha + addi r6, r6, BOOTINFO2_ADDR@l + lwz r5, 0(r6) + cmplwi r5, 0 + beq+ _no_args + lwz r6, 8(r5) + cmplwi r6, 0 + beq+ _no_args + add r6, r5, r6 + lwz r14, 0(r6) + cmplwi r14, 0 + beq _no_args + addi r15, r6, 4 + mtctr r14 + +_loop: + addi r6, r6, 4 + lwz r7, 0(r6) + add r7, r7, r5 + stw r7, 0(r6) + bdnz _loop + lis r5, ARENAHI_ADDR@ha + addi r5, r5, ARENAHI_ADDR@l + rlwinm r7, r15, 0, 0, 0x1a + stw r7, 0(r5) + b _end_of_parseargs + +_no_args: + li r14, 0 + li r15, 0 + +_end_of_parseargs: + bl DBInit + bl OSInit + lis r4, DVD_DEVICECODE_ADDR@ha + addi r4, r4, DVD_DEVICECODE_ADDR@l + lhz r3, 0(r4) + andi. r5, r3, 0x8000 + beq _check_pad3 + andi. r3, r3, 0x7fff + cmplwi r3, 1 +#if DOLPHIN_REV == 2002 + bne _goto_skip_init_bba +#else + bne _skip_crc +#endif + +_check_pad3: + bl __check_pad3 + +#if DOLPHIN_REV == 2003 +_skip_crc: + bl __get_debug_bba + cmplwi r3, 1 + bne _goto_skip_init_bba + bl InitMetroTRK_BBA +#endif + +_goto_skip_init_bba: + bl __init_user + mr r3, r14 + mr r4, r15 + bl main + b exit +#endif // clang-format on +} + +ASM static void __init_registers(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + #if DOLPHIN_REV == 2003 + li r0, 0 + li r3, 0 + li r4, 0 + li r5, 0 + li r6, 0 + li r7, 0 + li r8, 0 + li r9, 0 + li r10, 0 + li r11, 0 + li r12, 0 + li r14, 0 + li r15, 0 + li r16, 0 + li r17, 0 + li r18, 0 + li r19, 0 + li r20, 0 + li r21, 0 + li r22, 0 + li r23, 0 + li r24, 0 + li r25, 0 + li r26, 0 + li r27, 0 + li r28, 0 + li r29, 0 + li r30, 0 + li r31, 0 + #endif + lis r1, _stack_addr@h + ori r1, r1, _stack_addr@l + lis r2, _SDA2_BASE_@h + ori r2, r2, _SDA2_BASE_@l + lis r13, _SDA_BASE_@h + ori r13, r13, _SDA_BASE_@l + blr +#endif // clang-format on +} + +inline static void __copy_rom_section(void* dst, const void* src, unsigned long size) { + if (size && (dst != src)) { + memcpy(dst, src, size); + __flush_cache(dst, size); + } +} + +inline static void __init_bss_section(void* dst, unsigned long size) { + if (size) { + memset(dst, 0, size); + } +} + +void __init_data(void) { + __rom_copy_info* dci; + __bss_init_info* bii; + + dci = _rom_copy_info; + while (TRUE) { + if (dci->size == 0) + break; + __copy_rom_section(dci->addr, dci->rom, dci->size); + dci++; + } + + bii = _bss_init_info; + while (TRUE) { + if (bii->size == 0) + break; + __init_bss_section(bii->addr, bii->size); + bii++; + } +} diff --git a/src/THPAudioDecode.c b/src/emulator/THPAudioDecode.c similarity index 100% rename from src/THPAudioDecode.c rename to src/emulator/THPAudioDecode.c diff --git a/src/THPDraw.c b/src/emulator/THPDraw.c similarity index 100% rename from src/THPDraw.c rename to src/emulator/THPDraw.c diff --git a/src/THPPlayer.c b/src/emulator/THPPlayer.c similarity index 99% rename from src/THPPlayer.c rename to src/emulator/THPPlayer.c index 5db9934..0377656 100644 --- a/src/THPPlayer.c +++ b/src/emulator/THPPlayer.c @@ -1,4 +1,4 @@ -#include "THPPlayer.h" +#include "emulator/THPPlayer.h" #include "macros.h" u16 VolumeTable[128] = { diff --git a/src/THPRead.c b/src/emulator/THPRead.c similarity index 97% rename from src/THPRead.c rename to src/emulator/THPRead.c index 21fd95b..f94808a 100644 --- a/src/THPRead.c +++ b/src/emulator/THPRead.c @@ -1,5 +1,5 @@ -#include "THPRead.h" -#include "THPRead_jumptables.h" +#include "emulator/THPRead.h" +#include "emulator/THPRead_jumptables.h" #include "macros.h" const f32 D_800D3130[12] = {1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, -1.0}; diff --git a/src/THPVideoDecode.c b/src/emulator/THPVideoDecode.c similarity index 100% rename from src/THPVideoDecode.c rename to src/emulator/THPVideoDecode.c diff --git a/src/_buildtev.c b/src/emulator/_buildtev.c similarity index 98% rename from src/_buildtev.c rename to src/emulator/_buildtev.c index bd7e9fb..a8dba51 100644 --- a/src/_buildtev.c +++ b/src/emulator/_buildtev.c @@ -1,4 +1,4 @@ -#include "_buildtev.h" +#include "emulator/_buildtev.h" GXTevColorArg gColorArgs[16] = { GX_CC_CPREV, GX_CC_TEXC, GX_CC_TEXC, GX_CC_C1, GX_CC_RASC, GX_CC_C2, GX_CC_ONE, GX_CC_APREV, diff --git a/src/_frameGCNcc.c b/src/emulator/_frameGCNcc.c similarity index 98% rename from src/_frameGCNcc.c rename to src/emulator/_frameGCNcc.c index 6d7d40a..f5d5f69 100644 --- a/src/_frameGCNcc.c +++ b/src/emulator/_frameGCNcc.c @@ -1,5 +1,5 @@ -#include "_buildtev.h" #include "dolphin.h" +#include "emulator/_buildtev.h" GXTevColorArg gCombinedColor[] = { 0x00000000, 0x00000008, 0x00000008, 0x00000006, 0x0000000A, 0x0000000E, 0x0000000C, 0x00000001, diff --git a/src/audio.c b/src/emulator/audio.c similarity index 95% rename from src/audio.c rename to src/emulator/audio.c index a2d941f..73d167d 100644 --- a/src/audio.c +++ b/src/emulator/audio.c @@ -1,10 +1,10 @@ -#include "audio.h" +#include "emulator/audio.h" #include "dolphin.h" -#include "ram.h" -#include "rsp.h" -#include "soundGCN.h" -#include "system.h" -#include "xlPostGCN.h" +#include "emulator/ram.h" +#include "emulator/rsp.h" +#include "emulator/soundGCN.h" +#include "emulator/system.h" +#include "emulator/xlPostGCN.h" _XL_OBJECTTYPE gClassAudio = { "AUDIO", diff --git a/src/codeGCN.c b/src/emulator/codeGCN.c similarity index 94% rename from src/codeGCN.c rename to src/emulator/codeGCN.c index 77ffed5..f7b94e3 100644 --- a/src/codeGCN.c +++ b/src/emulator/codeGCN.c @@ -1,4 +1,4 @@ -#include "codeGCN.h" +#include "emulator/codeGCN.h" _XL_OBJECTTYPE gClassCode = { "Code", diff --git a/src/cpu.c b/src/emulator/cpu.c similarity index 99% rename from src/cpu.c rename to src/emulator/cpu.c index e31c290..6b6ea77 100644 --- a/src/cpu.c +++ b/src/emulator/cpu.c @@ -1,18 +1,18 @@ -#include "cpu.h" -#include "cpu_jumptable.h" +#include "emulator/cpu.h" #include "dolphin.h" -#include "frame.h" -#include "library.h" +#include "emulator/cpu_jumptable.h" +#include "emulator/frame.h" +#include "emulator/library.h" +#include "emulator/ram.h" +#include "emulator/rom.h" +#include "emulator/rsp.h" +#include "emulator/simGCN.h" +#include "emulator/system.h" +#include "emulator/video.h" +#include "emulator/xlHeap.h" +#include "emulator/xlObject.h" +#include "libc/math.h" #include "macros.h" -#include "math.h" -#include "ram.h" -#include "rom.h" -#include "rsp.h" -#include "simGCN.h" -#include "system.h" -#include "video.h" -#include "xlHeap.h" -#include "xlObject.h" static s32 cpuSetTLB(Cpu* pCPU, s32 iEntry); s32 cpuSetRegisterCP0(Cpu* pCPU, s32 iRegister, s64 nData); diff --git a/src/disk.c b/src/emulator/disk.c similarity index 97% rename from src/disk.c rename to src/emulator/disk.c index 6b9eb81..68f1f36 100644 --- a/src/disk.c +++ b/src/emulator/disk.c @@ -1,6 +1,6 @@ -#include "disk.h" -#include "cpu.h" -#include "system.h" +#include "emulator/disk.h" +#include "emulator/cpu.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassDisk = { "DISK", diff --git a/src/flash.c b/src/emulator/flash.c similarity index 97% rename from src/flash.c rename to src/emulator/flash.c index dee02fc..740287b 100644 --- a/src/flash.c +++ b/src/emulator/flash.c @@ -1,9 +1,9 @@ -#include "flash.h" +#include "emulator/flash.h" +#include "emulator/ram.h" +#include "emulator/simGCN.h" +#include "emulator/system.h" +#include "emulator/xlHeap.h" #include "macros.h" -#include "ram.h" -#include "simGCN.h" -#include "system.h" -#include "xlHeap.h" _XL_OBJECTTYPE gClassFlash = { "FLASH", diff --git a/src/library.c b/src/emulator/library.c similarity index 99% rename from src/library.c rename to src/emulator/library.c index 3c6bb67..9d2e535 100644 --- a/src/library.c +++ b/src/emulator/library.c @@ -1,11 +1,11 @@ -#include "library.h" -#include "frame.h" -#include "library_jumptables.h" +#include "emulator/library.h" +#include "emulator/frame.h" +#include "emulator/library_jumptables.h" +#include "emulator/ram.h" +#include "emulator/system.h" +#include "emulator/xlPostGCN.h" +#include "libc/math.h" #include "macros.h" -#include "math.h" -#include "ram.h" -#include "system.h" -#include "xlPostGCN.h" char D_800EEB00[] = "OS-LIBRARY"; diff --git a/src/mcardGCN.c b/src/emulator/mcardGCN.c similarity index 98% rename from src/mcardGCN.c rename to src/emulator/mcardGCN.c index a072ddc..f6d4b6b 100644 --- a/src/mcardGCN.c +++ b/src/emulator/mcardGCN.c @@ -1,5 +1,5 @@ -#include "mcardGCN.h" -#include "mcardGCN_jumptables.h" +#include "emulator/mcardGCN.h" +#include "emulator/mcardGCN_jumptables.h" // ゼルダの伝説:時のオカリナ char D_800EA548[] = diff --git a/src/mips.c b/src/emulator/mips.c similarity index 99% rename from src/mips.c rename to src/emulator/mips.c index 1c26d73..d705247 100644 --- a/src/mips.c +++ b/src/emulator/mips.c @@ -1,5 +1,5 @@ -#include "mips.h" -#include "system.h" +#include "emulator/mips.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassMips = { "MIPS", diff --git a/src/movie.c b/src/emulator/movie.c similarity index 86% rename from src/movie.c rename to src/emulator/movie.c index 05840ce..e2471be 100644 --- a/src/movie.c +++ b/src/emulator/movie.c @@ -1,7 +1,7 @@ #include "dolphin.h" -#include "simGCN.h" -#include "system.h" -#include "xlCoreGCN.h" +#include "emulator/simGCN.h" +#include "emulator/system.h" +#include "emulator/xlCoreGCN.h" void* gBufferP; diff --git a/src/peripheral.c b/src/emulator/peripheral.c similarity index 97% rename from src/peripheral.c rename to src/emulator/peripheral.c index 21f62e8..007aab5 100644 --- a/src/peripheral.c +++ b/src/emulator/peripheral.c @@ -1,9 +1,9 @@ -#include "peripheral.h" -#include "cpu.h" -#include "flash.h" -#include "simGCN.h" -#include "sram.h" -#include "system.h" +#include "emulator/peripheral.h" +#include "emulator/cpu.h" +#include "emulator/flash.h" +#include "emulator/simGCN.h" +#include "emulator/sram.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassPeripheral = { "PERIPHERAL", diff --git a/src/pif.c b/src/emulator/pif.c similarity index 98% rename from src/pif.c rename to src/emulator/pif.c index 51f193e..cac695e 100644 --- a/src/pif.c +++ b/src/emulator/pif.c @@ -1,4 +1,4 @@ -#include "pif.h" +#include "emulator/pif.h" _XL_OBJECTTYPE gClassPIF = { "PIF", diff --git a/src/ram.c b/src/emulator/ram.c similarity index 98% rename from src/ram.c rename to src/emulator/ram.c index de9a505..bc7b880 100644 --- a/src/ram.c +++ b/src/emulator/ram.c @@ -1,6 +1,6 @@ -#include "ram.h" -#include "cpu.h" -#include "system.h" +#include "emulator/ram.h" +#include "emulator/cpu.h" +#include "emulator/system.h" s32 ramEvent(Ram* pRAM, s32 nEvent, void* pArgument); diff --git a/src/rdb.c b/src/emulator/rdb.c similarity index 99% rename from src/rdb.c rename to src/emulator/rdb.c index d781ff7..a80993a 100644 --- a/src/rdb.c +++ b/src/emulator/rdb.c @@ -1,5 +1,5 @@ -#include "rdb.h" -#include "system.h" +#include "emulator/rdb.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassRdb = { "RDB", diff --git a/src/rdp.c b/src/emulator/rdp.c similarity index 98% rename from src/rdp.c rename to src/emulator/rdp.c index 7462d9a..8fa08f7 100644 --- a/src/rdp.c +++ b/src/emulator/rdp.c @@ -1,5 +1,5 @@ -#include "rdp.h" -#include "rdp_jumptables.h" +#include "emulator/rdp.h" +#include "emulator/rdp_jumptables.h" _XL_OBJECTTYPE gClassRDP = { "RDP", diff --git a/src/rom.c b/src/emulator/rom.c similarity index 99% rename from src/rom.c rename to src/emulator/rom.c index 6ab89dd..09d519e 100644 --- a/src/rom.c +++ b/src/emulator/rom.c @@ -1,12 +1,12 @@ -#include "rom.h" -#include "cpu.h" +#include "emulator/rom.h" #include "dolphin.h" -#include "frame.h" +#include "emulator/cpu.h" +#include "emulator/frame.h" +#include "emulator/ram.h" +#include "emulator/simGCN.h" +#include "emulator/system.h" +#include "emulator/xlCoreGCN.h" #include "macros.h" -#include "ram.h" -#include "simGCN.h" -#include "system.h" -#include "xlCoreGCN.h" static s32 romMakeFreeCache(Rom* pROM, s32* piCache, RomCacheType eType); static s32 romSetBlockCache(Rom* pROM, s32 iBlock, RomCacheType eType); diff --git a/src/rsp.c b/src/emulator/rsp.c similarity index 99% rename from src/rsp.c rename to src/emulator/rsp.c index aec0047..ebd5e4a 100644 --- a/src/rsp.c +++ b/src/emulator/rsp.c @@ -1,5 +1,5 @@ -#include "rsp.h" -#include "rsp_jumptables.h" +#include "emulator/rsp.h" +#include "emulator/rsp_jumptables.h" _XL_OBJECTTYPE gClassRSP = { "RSP", diff --git a/src/serial.c b/src/emulator/serial.c similarity index 95% rename from src/serial.c rename to src/emulator/serial.c index b1c7310..585b3f2 100644 --- a/src/serial.c +++ b/src/emulator/serial.c @@ -1,8 +1,8 @@ -#include "serial.h" -#include "cpu.h" -#include "pif.h" -#include "ram.h" -#include "system.h" +#include "emulator/serial.h" +#include "emulator/cpu.h" +#include "emulator/pif.h" +#include "emulator/ram.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassSerial = { "SERIAL", diff --git a/src/simGCN.c b/src/emulator/simGCN.c similarity index 98% rename from src/simGCN.c rename to src/emulator/simGCN.c index b12c7d2..8b5025d 100644 --- a/src/simGCN.c +++ b/src/emulator/simGCN.c @@ -1,18 +1,18 @@ -#include "simGCN.h" -#include "THPPlayer.h" -#include "THPRead.h" -#include "codeGCN.h" +#include "emulator/simGCN.h" #include "dolphin.h" -#include "frame.h" +#include "emulator/THPPlayer.h" +#include "emulator/THPRead.h" +#include "emulator/codeGCN.h" +#include "emulator/frame.h" +#include "emulator/mcardGCN.h" +#include "emulator/movie.h" +#include "emulator/pif.h" +#include "emulator/rom.h" +#include "emulator/soundGCN.h" +#include "emulator/system.h" +#include "emulator/xlCoreGCN.h" +#include "emulator/xlPostGCN.h" #include "macros.h" -#include "mcardGCN.h" -#include "movie.h" -#include "pif.h" -#include "rom.h" -#include "soundGCN.h" -#include "system.h" -#include "xlCoreGCN.h" -#include "xlPostGCN.h" const f32 D_800D2FE0[3][4] = { {1.0, 0.0, 0.0, 0.0}, diff --git a/src/soundGCN.c b/src/emulator/soundGCN.c similarity index 97% rename from src/soundGCN.c rename to src/emulator/soundGCN.c index cf0905d..871a8ea 100644 --- a/src/soundGCN.c +++ b/src/emulator/soundGCN.c @@ -1,4 +1,4 @@ -#include "soundGCN.h" +#include "emulator/soundGCN.h" #include "macros.h" _XL_OBJECTTYPE gClassSound = { diff --git a/src/sram.c b/src/emulator/sram.c similarity index 95% rename from src/sram.c rename to src/emulator/sram.c index 74b126e..8066bad 100644 --- a/src/sram.c +++ b/src/emulator/sram.c @@ -1,8 +1,8 @@ -#include "sram.h" -#include "cpu.h" -#include "ram.h" -#include "simGCN.h" -#include "system.h" +#include "emulator/sram.h" +#include "emulator/cpu.h" +#include "emulator/ram.h" +#include "emulator/simGCN.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassSram = { "SRAM", diff --git a/src/system.c b/src/emulator/system.c similarity index 99% rename from src/system.c rename to src/emulator/system.c index a5acadc..470d182 100644 --- a/src/system.c +++ b/src/emulator/system.c @@ -1,29 +1,27 @@ -#include "system.h" -#include "audio.h" -#include "cpu.h" -#include "disk.h" +#include "emulator/system.h" #include "dolphin.h" -#include "flash.h" -#include "frame.h" -#include "library.h" +#include "emulator/audio.h" +#include "emulator/cpu.h" +#include "emulator/disk.h" +#include "emulator/flash.h" +#include "emulator/frame.h" +#include "emulator/library.h" +#include "emulator/mcardGCN.h" +#include "emulator/mips.h" +#include "emulator/peripheral.h" +#include "emulator/pif.h" +#include "emulator/ram.h" +#include "emulator/rdb.h" +#include "emulator/rdp.h" +#include "emulator/rom.h" +#include "emulator/rsp.h" +#include "emulator/serial.h" +#include "emulator/simGCN.h" +#include "emulator/soundGCN.h" +#include "emulator/sram.h" +#include "emulator/video.h" +#include "libc/stdlib.h" #include "macros.h" -#include "mcardGCN.h" -#include "mips.h" -#include "peripheral.h" -#include "pif.h" -#include "ram.h" -#include "rdb.h" -#include "rdp.h" -#include "rom.h" -#include "rsp.h" -#include "serial.h" -#include "simGCN.h" -#include "soundGCN.h" -#include "sram.h" -#include "video.h" - -//! TODO: import MSL headers -extern int atoi(const char* str); _XL_OBJECTTYPE gClassSystem = { "SYSTEM (N64)", diff --git a/src/video.c b/src/emulator/video.c similarity index 98% rename from src/video.c rename to src/emulator/video.c index 151db4e..67035e0 100644 --- a/src/video.c +++ b/src/emulator/video.c @@ -1,7 +1,7 @@ -#include "video.h" -#include "frame.h" -#include "ram.h" -#include "system.h" +#include "emulator/video.h" +#include "emulator/frame.h" +#include "emulator/ram.h" +#include "emulator/system.h" _XL_OBJECTTYPE gClassVideo = { "VIDEO", diff --git a/src/xlCoreGCN.c b/src/emulator/xlCoreGCN.c similarity index 99% rename from src/xlCoreGCN.c rename to src/emulator/xlCoreGCN.c index fa55c05..28b6322 100644 --- a/src/xlCoreGCN.c +++ b/src/emulator/xlCoreGCN.c @@ -1,6 +1,6 @@ -#include "xlCoreGCN.h" +#include "emulator/xlCoreGCN.h" +#include "emulator/simGCN.h" #include "macros.h" -#include "simGCN.h" u8 gTgPcTPL[32897] = { #pragma INCBIN("SIM_original.elf", 0x000D07A0, 0x00008081) diff --git a/src/xlFileGCN.c b/src/emulator/xlFileGCN.c similarity index 97% rename from src/xlFileGCN.c rename to src/emulator/xlFileGCN.c index e07e6ef..2fdd6d0 100644 --- a/src/xlFileGCN.c +++ b/src/emulator/xlFileGCN.c @@ -1,7 +1,7 @@ -#include "xlFileGCN.h" +#include "emulator/xlFileGCN.h" #include "dolphin.h" -#include "xlHeap.h" -#include "xlObject.h" +#include "emulator/xlHeap.h" +#include "emulator/xlObject.h" _XL_OBJECTTYPE gTypeFile = { "FILE", diff --git a/src/xlHeap.c b/src/emulator/xlHeap.c similarity index 99% rename from src/xlHeap.c rename to src/emulator/xlHeap.c index fef7df4..c4b1104 100644 --- a/src/xlHeap.c +++ b/src/emulator/xlHeap.c @@ -1,4 +1,4 @@ -#include "xlHeap.h" +#include "emulator/xlHeap.h" static u32* gpHeap; static u32* gpHeapBlockFirst; diff --git a/src/xlList.c b/src/emulator/xlList.c similarity index 98% rename from src/xlList.c rename to src/emulator/xlList.c index ac527dc..ba5255f 100644 --- a/src/xlList.c +++ b/src/emulator/xlList.c @@ -1,7 +1,7 @@ -#include "xlList.h" +#include "emulator/xlList.h" #include "dolphin.h" +#include "emulator/xlHeap.h" #include "macros.h" -#include "xlHeap.h" static tXL_LIST gListList; diff --git a/src/xlObject.c b/src/emulator/xlObject.c similarity index 98% rename from src/xlObject.c rename to src/emulator/xlObject.c index 4d88bbd..073330d 100644 --- a/src/xlObject.c +++ b/src/emulator/xlObject.c @@ -1,5 +1,5 @@ -#include "xlObject.h" -#include "xlList.h" +#include "emulator/xlObject.h" +#include "emulator/xlList.h" static tXL_LIST* gpListData; diff --git a/src/xlPostGCN.c b/src/emulator/xlPostGCN.c similarity index 82% rename from src/xlPostGCN.c rename to src/emulator/xlPostGCN.c index 8ee4ebb..079a9dd 100644 --- a/src/xlPostGCN.c +++ b/src/emulator/xlPostGCN.c @@ -1,4 +1,4 @@ -#include "xlPostGCN.h" +#include "emulator/xlPostGCN.h" s32 xlPostText(const char* fmt, const char* file, s32 line, ...) { return 1; }