diff --git a/.gitignore b/.gitignore index 948f52e5..258e02d5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ *.a *.o *.ii -*.s *.xa \ No newline at end of file diff --git a/include/PSX/System/syscalls.h b/include/PSX/System/syscalls.h new file mode 100644 index 00000000..9487627a --- /dev/null +++ b/include/PSX/System/syscalls.h @@ -0,0 +1,128 @@ +#ifndef __JABYENGINE_SYSCALLS__H +#define __JABYENGINE_SYSCALLS__H +#include "../jabyengine_defines.h" + +/* +R0 zr Constant Zero +R1 at Reserved for the assembler +R2-R3 v0-v1 Values for results and expression evaluation +R4-R7 a0-a3 Arguments +R8-R15 t0-t7 Temporaries (not preserved across call) +R16-R23 s0-s7 Saved (preserved across call) +R24-R25 t8-t9 More temporaries (not preserved across call) +R26-R27 k0-k1 Reserved for OS Kernel +R28 gp Global Pointer +R29 sp Stack Pointer +R30 fp Frame Pointer +R31 ra Return address (set by function call) +*/ + +static __constexpr const uint32_t __syscall_Table_A = 0xA0; +static __constexpr const uint32_t __syscall_Table_B = 0xB0; +static __constexpr const uint32_t __syscall_Table_C = 0xC0; + +enum __syscall_PriorityChain { + CdromDmaIrq = 0, + CdromIoIrq = 0, + SyscallException = 0, + + CardSpecificIrq = 1, + VblankIrq = 1, + Timer2Irq = 1, + Timer1Irq = 1, + Timer0Irq = 1, + + PadCardIrq = 2, + + DefInt = 3 +}; + +static __constexpr const uint32_t SkipHandler = 0; +static __constexpr const uint32_t ExecuteHandler = 1; + +struct __no_align __syscall_InterruptElement { + struct __syscall_InterruptElement *next; + void (*handler)(uint32_t); + uint32_t (*verifier)(); + uint32_t notUsed; +}; + +#ifdef __cplusplus + reinterpret_cast<__VA_ARGS__>(table) +#else + #define __syscall_function_cast(table, ...) ((__VA_ARGS__)(void*)table) +#endif + +static __always_inline void* __syscall_memcpy(void *dst, const void *src, size_t len) { + register uint32_t FuncID asm("t1") = 0x2A; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(__syscall_Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); +} + +static __always_inline void __syscall_InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) { + register uint32_t FuncID asm("t1") = 0x12; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(__syscall_Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize); +} + +static __always_inline void __syscall_StartPad() { + register uint32_t FuncID asm("t1") = 0x13; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(__syscall_Table_B, void(*)())(); +} + +static __always_inline void __syscall_StopPad() { + register uint32_t FuncID asm("t1") = 0x14; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(__syscall_Table_B, void(*)())(); +} + +static __always_inline void __syscall_ChangeClearPad(int32_t _reserved) { + register uint32_t FuncID asm("t1") = 0x5B; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(__syscall_Table_B, void(*)(int32_t))(_reserved); +} + +static __always_inline void __syscall_ReturnFromException() { + register uint32_t FuncID asm("t1") = 0x17; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(__syscall_Table_B, void(*)())(); +} + +static __always_inline int __syscall_SysEnqIntRP(enum __syscall_PriorityChain prio, struct __syscall_InterruptElement* interElm) { + register uint32_t FuncID asm("t1") = 0x02; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(__syscall_Table_C, int(*)(enum __syscall_PriorityChain prio, struct __syscall_InterruptElement *interElm))(prio, interElm); +} + +static __always_inline int __syscall_SysDeqIntRP(enum __syscall_PriorityChain prio, struct __syscall_InterruptElement *interElm) { + register uint32_t FuncID asm("t1") = 0x03; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(__syscall_Table_C, int(*)(enum __syscall_PriorityChain prio, struct __syscall_InterruptElement *interElm))(prio, interElm); +} + +static __always_inline uint32_t __syscall_EnterCriticalSection() { + register uint32_t FuncID asm("a0") = 0x01; + register uint32_t returnValue asm("v0"); + + __asm__ volatile("syscall" : "=r"(FuncID), "=r"(returnValue) : "r"(FuncID) : "at", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); + return returnValue; +} + +static __always_inline void __syscall_ExitCriticalSection() { + register uint32_t FuncID asm("a0") = 0x2; + + __asm__ volatile("syscall" : "=r"(FuncID) : "r"(FuncID) : "at", "v0", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); +} + +int __syscall_printf(const char* txt, ...); + +#endif //!__JABYENGINE_SYSCALLS__H \ No newline at end of file diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h new file mode 100644 index 00000000..b6a866dc --- /dev/null +++ b/include/PSX/jabyengine_defines.h @@ -0,0 +1,17 @@ +#ifndef __JABYENGINE_DEFINES__H +#define __JABYENGINE_DEFINES__H +#include "../stddef.h" + +#define __keep __attribute__((used)) +#define __no_align __attribute__((packed)) +#define __no_inline __attribute__((noinline)) +#define __always_inline __attribute__((always_inline)) +#define __section(name) __attribute__((section(name))) + +#ifdef __cplusplus + #define __constexpr constexpr +#else + #define __constexpr +#endif + +#endif //!__JABYENGINE_DEFINES__H \ No newline at end of file diff --git a/include/stddef.h b/include/stddef.h new file mode 100644 index 00000000..ffb37baf --- /dev/null +++ b/include/stddef.h @@ -0,0 +1,7 @@ +#ifndef __STDDEF__H +#define __STDDEF__H +#include "stdint.h" + +typedef uintmax_t size_t; + +#endif //!__STDDEF__H \ No newline at end of file diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 00000000..f27f36cc --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,37 @@ +#ifndef __STDINT__H +#define __STDINT__H + +typedef signed char int8_t; +typedef unsigned char uint8_t; + +typedef short int16_t; +typedef unsigned short uint16_t; + +typedef int int32_t; +typedef unsigned int uint32_t; + +typedef signed char int_least8_t; +typedef unsigned char uint_least8_t; + +typedef short int_least16_t; +typedef unsigned short uint_least16_t; + +typedef int int_least32_t; +typedef unsigned int uint_least32_t; + +typedef signed char int_fast8_t; +typedef unsigned char uint_fast8_t; + +typedef int int_fast16_t; +typedef unsigned int uint_fast16_t; + +typedef int int_fast32_t; +typedef unsigned int uint_fast32_t; + +typedef signed int intmax_t; +typedef unsigned int uintmax_t; + +typedef signed long intptr_t; +typedef unsigned long uintptr_t; + +#endif //!__STDINT__H \ No newline at end of file diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 00000000..cb03ac80 --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,7 @@ +#ifndef __STDIO__H +#define __STDIO__H +#include "PSX/System/syscalls.h" + +#define printf __syscall_printf + +#endif //!__STDIO__H \ No newline at end of file diff --git a/lib/Makefile b/lib/Makefile index f9ffeb47..9109ac3b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -43,13 +43,13 @@ CXXFLAGS += -fno-exceptions -fno-rtti USE_FUNCTION_SECTIONS ?= true ifeq ($(USE_FUNCTION_SECTIONS),true) -CCFLAGS_all += -ffunction-sections +CCFLAGS += -ffunction-sections endif -CCFLAGS_all += -mno-gpopt -fomit-frame-pointer -CCFLAGS_all += -fno-builtin -fno-strict-aliasing -Wno-attributes -CCFLAGS_all += $(ARCHFLAGS) +CCFLAGS += -mno-gpopt -fomit-frame-pointer +CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes +CCFLAGS += $(ARCHFLAGS) -CCFLAGS_all += $(CCFLAGS_$(BUILD_PROFILE)) +CCFLAGS += $(CCFLAGS_$(BUILD_PROFILE)) #Linker flags LDFLAGS_release += -Os @@ -66,13 +66,17 @@ DEPS = -Wp,-MMD,$(@:%.o=%.d),-MT,$@ OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(subst ..,!super,$(basename $(SRCS))))) #Compiling rule +$(OUTPUT_DIR)/%.o: %.s + @mkdir -p $(dir $@) + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< + $(OUTPUT_DIR)/%.o: %.c @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS_all) $(CCFLAGS) $< + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< $(OUTPUT_DIR)/%.o: %.cpp @mkdir -p $(dir $@) - $(CXX) -c $(DEPS) -o $@ $(CCFLAGS_all) $(CXXFLAGS) $< + $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< .SECONDEXPANSION: $(OUTPUT_DIR)/%.o: $$(subst !super,..,%.s) diff --git a/lib/PSEXETarget.mk b/lib/PSEXETarget.mk index bd5fbf66..97b49e8e 100644 --- a/lib/PSEXETarget.mk +++ b/lib/PSEXETarget.mk @@ -1,6 +1,6 @@ #Linking rule $(TARGET).elf: $(OBJS) - $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) $(LIBS_all) $(LIBS) + $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) $(LIBS) #Strips the psexe $(TARGET).psexe: $(TARGET).elf diff --git a/src/Library/Library.code-workspace b/src/Library/Library.code-workspace index 13919258..44697c10 100644 --- a/src/Library/Library.code-workspace +++ b/src/Library/Library.code-workspace @@ -55,12 +55,12 @@ }, "settings": { "C_Cpp.default.includePath": [ - "./" + "../../include" ], "C_Cpp.default.compilerPath": "", "C_Cpp.default.cStandard": "c17", "C_Cpp.default.cppStandard": "c++20", - "C_Cpp.default.intelliSenseMode": "", + "C_Cpp.default.intelliSenseMode": "linux-gcc-x86", "C_Cpp.default.compilerArgs": [ ], "C_Cpp.default.defines": [ @@ -69,6 +69,9 @@ "files.exclude": { "**/*.o": true, "**/*.dep": true + }, + "files.associations": { + "stdio.h": "c" } } } \ No newline at end of file diff --git a/src/Library/Makefile b/src/Library/Makefile index 2ca1b9dd..1cc481c8 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -1,8 +1,11 @@ ARTIFACT = libJabyEngine BUILD_DIR = bin +CCFLAGS += -I../../include + include ../../lib/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) +SRCS += src/syscall_printf.asm include ../../lib/Makefile LIB_DIR = ../../lib/$(CONFIG_NAME) diff --git a/src/Library/src/BootLoader/start.c b/src/Library/src/BootLoader/start.c new file mode 100644 index 00000000..30b03799 --- /dev/null +++ b/src/Library/src/BootLoader/start.c @@ -0,0 +1,6 @@ +#include + +void _start() { + //call main here + printf("Hello Planschbecken c:\n"); +} \ No newline at end of file diff --git a/src/Library/src/start.c b/src/Library/src/start.c deleted file mode 100644 index 54cb85ac..00000000 --- a/src/Library/src/start.c +++ /dev/null @@ -1,5 +0,0 @@ - - -void _start() { - //call main here -} \ No newline at end of file diff --git a/src/Library/src/syscall_printf.s b/src/Library/src/syscall_printf.s new file mode 100644 index 00000000..08d7c540 --- /dev/null +++ b/src/Library/src/syscall_printf.s @@ -0,0 +1,12 @@ + .set push + .set noreorder +#.section .ramtext, "ax", @progbits + .align 2 + .global __syscall_printf + .type __syscall_printf, @function + +__syscall_printf: + li $t2, 0xa0 + jr $t2 + li $t1, 0x3f + \ No newline at end of file