diff --git a/.gitignore b/.gitignore index d4db486a..6df861f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,14 @@ -# For now we ignore what is in root -**/build -**/bin -**/gcm.cache -**/iso/Info -/iso - -.lfsconfig - -*.d -*.a -*.o -*.ii +# For now we ignore what is in root +**/build +**/bin +**/gcm.cache +**/iso/Info +/iso + +.lfsconfig + +*.d +*.a +*.o +*.ii *.xa \ No newline at end of file diff --git a/examples/PoolBox/Makefile b/examples/PoolBox/Makefile index 8a43de83..73f122ce 100644 --- a/examples/PoolBox/Makefile +++ b/examples/PoolBox/Makefile @@ -1,20 +1,20 @@ -ARTIFACT = PoolBox -make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets -make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application -make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C iso - -all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS) - -all_%: always - $(call make_assets,$*) - $(call make_application,$*) - $(call make_cd,$*) - -assets_%: always - $(call make_assets,$*) -application_%: always - $(call make_application,$*) -cd_%: always - $(call make_cd,$*) - +ARTIFACT = PoolBox +make_assets = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C assets +make_application = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C application +make_cd = $(MAKE) $(1) ARTIFACT=$(ARTIFACT) -C iso + +all clean rebuild: |assets_$(MAKECMDGOALS) application_$(MAKECMDGOALS) cd_$(MAKECMDGOALS) + +all_%: always + $(call make_assets,$*) + $(call make_application,$*) + $(call make_cd,$*) + +assets_%: always + $(call make_assets,$*) +application_%: always + $(call make_application,$*) +cd_%: always + $(call make_cd,$*) + always: ; \ No newline at end of file diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index d0ac4ef3..77365839 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -1,12 +1,12 @@ -BUILD_DIR = bin - -OVERLAY_CONFIG = Overlays.json - -include $(JABY_ENGINE_DIR)/mkfile/Wildcard.mk -SRCS = $(call rwildcard, src, c cpp) - -INCLUDES += -I$(JABY_ENGINE_DIR)/include -CCFLAGS += -save-temps=obj - -include $(JABY_ENGINE_DIR)/mkfile/Makefile +BUILD_DIR = bin + +OVERLAY_CONFIG = Overlays.json + +include $(JABY_ENGINE_DIR)/mkfile/Wildcard.mk +SRCS = $(call rwildcard, src, c cpp) + +INCLUDES += -I$(JABY_ENGINE_DIR)/include +CCFLAGS += -save-temps=obj + +include $(JABY_ENGINE_DIR)/mkfile/Makefile include $(JABY_ENGINE_DIR)/mkfile/PSEXETarget.mk \ No newline at end of file diff --git a/examples/PoolBox/assets/Makefile b/examples/PoolBox/assets/Makefile index 17b04c4a..25601b8c 100644 --- a/examples/PoolBox/assets/Makefile +++ b/examples/PoolBox/assets/Makefile @@ -1,24 +1,24 @@ -include $(JABY_ENGINE_DIR)/mkfile/ExportPath.mk -include $(JABY_ENGINE_DIR)/mkfile/RebuildTarget.mk - -OUTPUT_DIR = bin -INPUT = $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin $(OUTPUT_DIR)/YoshiFont.bin $(OUTPUT_DIR)/Paco.bin - -$(OUTPUT_DIR)/TexturePage.bin: TexturePage.png - @mkdir -p $(OUTPUT_DIR) - jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 - -$(OUTPUT_DIR)/IconTexture.bin: IconTexture.png - @mkdir -p $(OUTPUT_DIR) - jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --semi-trans --color-trans - -$(OUTPUT_DIR)/YoshiFont.bin: YoshiFont.png - jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans - -$(OUTPUT_DIR)/Paco.bin: Paco.png - jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans - -all: $(INPUT) - -clean: +include $(JABY_ENGINE_DIR)/mkfile/ExportPath.mk +include $(JABY_ENGINE_DIR)/mkfile/RebuildTarget.mk + +OUTPUT_DIR = bin +INPUT = $(OUTPUT_DIR)/TexturePage.bin $(OUTPUT_DIR)/IconTexture.bin $(OUTPUT_DIR)/YoshiFont.bin $(OUTPUT_DIR)/Paco.bin + +$(OUTPUT_DIR)/TexturePage.bin: TexturePage.png + @mkdir -p $(OUTPUT_DIR) + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 + +$(OUTPUT_DIR)/IconTexture.bin: IconTexture.png + @mkdir -p $(OUTPUT_DIR) + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --semi-trans --color-trans + +$(OUTPUT_DIR)/YoshiFont.bin: YoshiFont.png + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans + +$(OUTPUT_DIR)/Paco.bin: Paco.png + jaby_engine_fconv --lz4 $< -o $@ simple-tim clut4 --color-trans + +all: $(INPUT) + +clean: rm -fr $(OUTPUT_DIR) \ No newline at end of file diff --git a/examples/PoolBox/iso/Makefile b/examples/PoolBox/iso/Makefile index e5dcf2c8..6887609e 100644 --- a/examples/PoolBox/iso/Makefile +++ b/examples/PoolBox/iso/Makefile @@ -1,2 +1,2 @@ -include $(JABY_ENGINE_DIR)/mkfile/ISOMakefile.mk +include $(JABY_ENGINE_DIR)/mkfile/ISOMakefile.mk include $(JABY_ENGINE_DIR)/mkfile/RebuildTarget.mk \ No newline at end of file diff --git a/include/PSX/File/Processor/file_processor.hpp b/include/PSX/File/Processor/file_processor.hpp index a0110f60..5cf1091f 100644 --- a/include/PSX/File/Processor/file_processor.hpp +++ b/include/PSX/File/Processor/file_processor.hpp @@ -1,57 +1,57 @@ -#pragma once -#include "../../Auxiliary/types.hpp" -#include "../file_types.hpp" - -namespace JabyEngine { - namespace FileProcessor { - class State { - __friends: - struct Reserved { - uint32_t reserved[4]; - }; - - struct Configuration; - - template - using GenericProcessRoutine = Progress (*)(Configuration&, T&); - - typedef GenericProcessRoutine ProcessRoutine; - - struct Configuration { - ProcessRoutine process_routine = nullptr; - const uint8_t* data_adr = nullptr; - size_t data_bytes = 0ull; - - template - static __always_inline Configuration from(GenericProcessRoutine process_routine, const uint8_t* data_adr) { - return {reinterpret_cast(process_routine), data_adr}; - } - - constexpr void processed(size_t bytes) { - this->data_adr += bytes; - this->data_bytes -= bytes; - } - }; - - __friends: - Configuration config; - Reserved reserved; - - template - static __always_inline State from(const T& reserved, const uint8_t* data_adr, GenericProcessRoutine process_routine) { - return {Configuration::from(process_routine, data_adr), *reinterpret_cast(&reserved)}; - static_assert(sizeof(T) <= sizeof(Reserved)); - } - - public: - Progress process(size_t bytes_ready) { - this->config.data_bytes += bytes_ready; - return (*this->config.process_routine)(this->config, this->reserved); - } - }; - - // The nothing state - State create(const uint32_t* data_adr, const Nothing& nothing); - State create(const uint32_t* data_adr, const SimpleTIM& file); - } +#pragma once +#include "../../Auxiliary/types.hpp" +#include "../file_types.hpp" + +namespace JabyEngine { + namespace FileProcessor { + class State { + __friends: + struct Reserved { + uint32_t reserved[4]; + }; + + struct Configuration; + + template + using GenericProcessRoutine = Progress (*)(Configuration&, T&); + + typedef GenericProcessRoutine ProcessRoutine; + + struct Configuration { + ProcessRoutine process_routine = nullptr; + const uint8_t* data_adr = nullptr; + size_t data_bytes = 0ull; + + template + static __always_inline Configuration from(GenericProcessRoutine process_routine, const uint8_t* data_adr) { + return {reinterpret_cast(process_routine), data_adr}; + } + + constexpr void processed(size_t bytes) { + this->data_adr += bytes; + this->data_bytes -= bytes; + } + }; + + __friends: + Configuration config; + Reserved reserved; + + template + static __always_inline State from(const T& reserved, const uint8_t* data_adr, GenericProcessRoutine process_routine) { + return {Configuration::from(process_routine, data_adr), *reinterpret_cast(&reserved)}; + static_assert(sizeof(T) <= sizeof(Reserved)); + } + + public: + Progress process(size_t bytes_ready) { + this->config.data_bytes += bytes_ready; + return (*this->config.process_routine)(this->config, this->reserved); + } + }; + + // The nothing state + State create(const uint32_t* data_adr, const Nothing& nothing); + State create(const uint32_t* data_adr, const SimpleTIM& file); + } } \ No newline at end of file diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index d42cf6af..f3b76916 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -1,167 +1,167 @@ -#pragma once -#include "../jabyengine_defines.h" - -/* -R0 zr Constant Zero -R1 at Reserved for the assembler -R2-R3 v0-v1 Values for results and expression evaluation -R4-R7 a0-a3 Arguments -R8-R15 t0-t7 Temporaries (not preserved across call) -R16-R23 s0-s7 Saved (preserved across call) -R24-R25 t8-t9 More temporaries (not preserved across call) -R26-R27 k0-k1 Reserved for OS Kernel -R28 gp Global Pointer -R29 sp Stack Pointer -R30 fp Frame Pointer -R31 ra Return address (set by function call) -*/ - -namespace JabyEngine { - namespace SysCall { - static constexpr const uint32_t Table_A = 0xA0; - static constexpr const uint32_t Table_B = 0xB0; - static constexpr const uint32_t Table_C = 0xC0; - - enum struct Priority { - CdromDmaIrq = 0, - CdromIoIrq = 0, - SyscallException = 0, - - CardSpecificIrq = 1, - VblankIrq = 1, - Timer2Irq = 1, - Timer1Irq = 1, - Timer0Irq = 1, - - PadCardIrq = 2, - - DefInt = 3 - }; - - enum InterruptVerifierResult { - SkipHandler = 0, - ExecuteHandler = 1 - }; - - typedef InterruptVerifierResult (*InterruptVerifier)(); - typedef uint32_t (*InterruptHandler)(uint32_t); - - #pragma pack(push, 1) - struct InterrupCallback { - struct InterrupCallback* next; - InterruptHandler handler_function; - InterruptVerifier verifier_function; - uint32_t notUsed; - }; - #pragma pack(pop) - - #define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table) - - static __always_inline void* memcpy(void *dst, const void *src, size_t len) { - register uint32_t FuncID asm("t1") = 0x2A; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); - } - - static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) { - register uint32_t FuncID asm("t1") = 0x12; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - __syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize); - } - - static __always_inline void StartPad() { - register uint32_t FuncID asm("t1") = 0x13; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - __syscall_function_cast(Table_B, void(*)())(); - } - - static __always_inline void StopPad() { - register uint32_t FuncID asm("t1") = 0x14; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - __syscall_function_cast(Table_B, void(*)())(); - } - - static __always_inline void ChangeClearPad(int32_t _reserved) { - register uint32_t FuncID asm("t1") = 0x5B; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - __syscall_function_cast(Table_B, void(*)(int32_t))(_reserved); - } - - static __always_inline void [[noreturn]] ReturnFromException() { - register uint32_t FuncID asm("t1") = 0x17; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - __syscall_function_cast(Table_B, void(*)())(); - } - - static __always_inline int SysEnqIntRP(Priority prio, InterrupCallback* interElm) { - register uint32_t FuncID asm("t1") = 0x02; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm); - } - - static __always_inline int SysDeqIntRP(Priority prio, InterrupCallback *interElm) { - register uint32_t FuncID asm("t1") = 0x03; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm); - } - - static __always_inline uint32_t EnterCriticalSection() { - register uint32_t FuncID asm("a0") = 0x01; - register uint32_t returnValue asm("v0"); - - __asm__ volatile("syscall" : "=r"(FuncID), "=r"(returnValue) : "r"(FuncID) : "at", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); - return returnValue; - } - - static __always_inline void ExitCriticalSection() { - register uint32_t FuncID asm("a0") = 0x02; - - __asm__ volatile("syscall" : "=r"(FuncID) : "r"(FuncID) : "at", "v0", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); - } - - static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) { - register uint32_t FuncID asm("t1") = 0x07; - - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - __syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec); - } - - static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) { - register uint32_t FuncID asm("t1") = 0x08; - - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler); - } - - static __always_inline int CloseEvent(uint32_t event) { - register uint32_t FuncID asm("t1") = 0x09; - - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event); - } - - static __always_inline int TestEvent(uint32_t event) { - register uint32_t FuncID asm("t1") = 0x0B; - - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - return __syscall_function_cast(Table_B, int (*)(uint32_t))(event); - } - - static __always_inline int EnableEvent(uint32_t event) { - register uint32_t FuncID asm("t1") = 0x0C; - - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - return __syscall_function_cast(Table_B, int (*)(uint32_t))(event); - } - - void printf(const char* txt, ...); - } +#pragma once +#include "../jabyengine_defines.h" + +/* +R0 zr Constant Zero +R1 at Reserved for the assembler +R2-R3 v0-v1 Values for results and expression evaluation +R4-R7 a0-a3 Arguments +R8-R15 t0-t7 Temporaries (not preserved across call) +R16-R23 s0-s7 Saved (preserved across call) +R24-R25 t8-t9 More temporaries (not preserved across call) +R26-R27 k0-k1 Reserved for OS Kernel +R28 gp Global Pointer +R29 sp Stack Pointer +R30 fp Frame Pointer +R31 ra Return address (set by function call) +*/ + +namespace JabyEngine { + namespace SysCall { + static constexpr const uint32_t Table_A = 0xA0; + static constexpr const uint32_t Table_B = 0xB0; + static constexpr const uint32_t Table_C = 0xC0; + + enum struct Priority { + CdromDmaIrq = 0, + CdromIoIrq = 0, + SyscallException = 0, + + CardSpecificIrq = 1, + VblankIrq = 1, + Timer2Irq = 1, + Timer1Irq = 1, + Timer0Irq = 1, + + PadCardIrq = 2, + + DefInt = 3 + }; + + enum InterruptVerifierResult { + SkipHandler = 0, + ExecuteHandler = 1 + }; + + typedef InterruptVerifierResult (*InterruptVerifier)(); + typedef uint32_t (*InterruptHandler)(uint32_t); + + #pragma pack(push, 1) + struct InterrupCallback { + struct InterrupCallback* next; + InterruptHandler handler_function; + InterruptVerifier verifier_function; + uint32_t notUsed; + }; + #pragma pack(pop) + + #define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table) + + static __always_inline void* memcpy(void *dst, const void *src, size_t len) { + register uint32_t FuncID asm("t1") = 0x2A; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); + } + + static __always_inline void InitPad(uint8_t *portA, uint32_t portASize, uint8_t *portB, uint32_t portBSize) { + register uint32_t FuncID asm("t1") = 0x12; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(Table_B, void(*)(uint8_t*, uint32_t, uint8_t*, uint32_t))(portA, portASize, portB, portBSize); + } + + static __always_inline void StartPad() { + register uint32_t FuncID asm("t1") = 0x13; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(Table_B, void(*)())(); + } + + static __always_inline void StopPad() { + register uint32_t FuncID asm("t1") = 0x14; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(Table_B, void(*)())(); + } + + static __always_inline void ChangeClearPad(int32_t _reserved) { + register uint32_t FuncID asm("t1") = 0x5B; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(Table_B, void(*)(int32_t))(_reserved); + } + + static __always_inline void [[noreturn]] ReturnFromException() { + register uint32_t FuncID asm("t1") = 0x17; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + __syscall_function_cast(Table_B, void(*)())(); + } + + static __always_inline int SysEnqIntRP(Priority prio, InterrupCallback* interElm) { + register uint32_t FuncID asm("t1") = 0x02; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm); + } + + static __always_inline int SysDeqIntRP(Priority prio, InterrupCallback *interElm) { + register uint32_t FuncID asm("t1") = 0x03; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(Table_C, int(*)(Priority prio, InterrupCallback *interElm))(prio, interElm); + } + + static __always_inline uint32_t EnterCriticalSection() { + register uint32_t FuncID asm("a0") = 0x01; + register uint32_t returnValue asm("v0"); + + __asm__ volatile("syscall" : "=r"(FuncID), "=r"(returnValue) : "r"(FuncID) : "at", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); + return returnValue; + } + + static __always_inline void ExitCriticalSection() { + register uint32_t FuncID asm("a0") = 0x02; + + __asm__ volatile("syscall" : "=r"(FuncID) : "r"(FuncID) : "at", "v0", "v1", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "memory"); + } + + static __always_inline void DeliverEvent(uint32_t classId, uint32_t spec) { + register uint32_t FuncID asm("t1") = 0x07; + + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + __syscall_function_cast(Table_B, void (*)(uint32_t, uint32_t))(classId, spec); + } + + static __always_inline uint32_t OpenEvent(uint32_t classId, uint32_t spec, uint32_t mode, void (*handler)()) { + register uint32_t FuncID asm("t1") = 0x08; + + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t, uint32_t, uint32_t, void(*)()))(classId, spec, mode, handler); + } + + static __always_inline int CloseEvent(uint32_t event) { + register uint32_t FuncID asm("t1") = 0x09; + + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(event); + } + + static __always_inline int TestEvent(uint32_t event) { + register uint32_t FuncID asm("t1") = 0x0B; + + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + return __syscall_function_cast(Table_B, int (*)(uint32_t))(event); + } + + static __always_inline int EnableEvent(uint32_t event) { + register uint32_t FuncID asm("t1") = 0x0C; + + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + return __syscall_function_cast(Table_B, int (*)(uint32_t))(event); + } + + void printf(const char* txt, ...); + } } \ No newline at end of file diff --git a/include/PSX/Timer/frame_timer.hpp b/include/PSX/Timer/frame_timer.hpp index d3bb0716..b665215e 100644 --- a/include/PSX/Timer/frame_timer.hpp +++ b/include/PSX/Timer/frame_timer.hpp @@ -1,59 +1,59 @@ -#ifndef __JABYENGINE_FRAME_TIMER_HPP__ -#define __JABYENGINE_FRAME_TIMER_HPP__ -#include "frame_time_helper.hpp" -#include - -namespace JabyEngine { - class MasterTime { - __friends: - static uint32_t value; - - public: - static uint32_t read() { - return reinterpret_cast(MasterTime::value); - } - - template - static T read_as() { - return static_cast(MasterTime::read()); - } - }; - - template - class SimpleTimer { - protected: - T value = 0; - - public: - constexpr SimpleTimer() = default; - - bool is_expired_for(T time) const { - return static_cast((MasterTime::read_as() - this->value)) >= time; - } - - void reset() { - this->value = MasterTime::read_as(); - } - }; - - template - class IntervalTimer : public SimpleTimer { - private: - T interval = 0; - - public: - constexpr IntervalTimer() = default; - constexpr IntervalTimer(T interval) : SimpleTimer(), interval(interval) { - } - - void set_interval(T interval) { - this->interval = interval; - } - - bool is_expired() const { - return SimpleTimer::is_expired_for(this->interval); - } - }; -} - +#ifndef __JABYENGINE_FRAME_TIMER_HPP__ +#define __JABYENGINE_FRAME_TIMER_HPP__ +#include "frame_time_helper.hpp" +#include + +namespace JabyEngine { + class MasterTime { + __friends: + static uint32_t value; + + public: + static uint32_t read() { + return reinterpret_cast(MasterTime::value); + } + + template + static T read_as() { + return static_cast(MasterTime::read()); + } + }; + + template + class SimpleTimer { + protected: + T value = 0; + + public: + constexpr SimpleTimer() = default; + + bool is_expired_for(T time) const { + return static_cast((MasterTime::read_as() - this->value)) >= time; + } + + void reset() { + this->value = MasterTime::read_as(); + } + }; + + template + class IntervalTimer : public SimpleTimer { + private: + T interval = 0; + + public: + constexpr IntervalTimer() = default; + constexpr IntervalTimer(T interval) : SimpleTimer(), interval(interval) { + } + + void set_interval(T interval) { + this->interval = interval; + } + + bool is_expired() const { + return SimpleTimer::is_expired_for(this->interval); + } + }; +} + #endif //!__JABYENGINE_FRAME_TIMER_HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h index 53433d59..fc616984 100644 --- a/include/PSX/jabyengine_defines.h +++ b/include/PSX/jabyengine_defines.h @@ -1,26 +1,26 @@ -#ifndef __JABYENGINE_DEFINES__H__ -#define __JABYENGINE_DEFINES__H__ -#include "../stddef.h" - -#define __used __attribute__((used)) -#define __no_align __attribute__((packed)) -#define __no_inline __attribute__((noinline)) -#define __no_return __attribute__((noreturn)) -#define __always_inline __attribute__((always_inline)) -#define __section(name) __attribute__((section(name))) -#define __collect(...) __VA_ARGS__ - -#ifndef __friends - #define __friends private -#endif //!__friends - -#ifdef __cplusplus - #define __constexpr constexpr - #define START_C_FUNCTIONS extern "C" { - #define END_C_FUNCTIONS } -#else - #define __constexpr - #define START_C_FUNCTIONS - #define END_C_FUNCTIONS -#endif +#ifndef __JABYENGINE_DEFINES__H__ +#define __JABYENGINE_DEFINES__H__ +#include "../stddef.h" + +#define __used __attribute__((used)) +#define __no_align __attribute__((packed)) +#define __no_inline __attribute__((noinline)) +#define __no_return __attribute__((noreturn)) +#define __always_inline __attribute__((always_inline)) +#define __section(name) __attribute__((section(name))) +#define __collect(...) __VA_ARGS__ + +#ifndef __friends + #define __friends private +#endif //!__friends + +#ifdef __cplusplus + #define __constexpr constexpr + #define START_C_FUNCTIONS extern "C" { + #define END_C_FUNCTIONS } +#else + #define __constexpr + #define START_C_FUNCTIONS + #define END_C_FUNCTIONS +#endif #endif //!__JABYENGINE_DEFINES__H__ \ No newline at end of file diff --git a/include/stdio.h b/include/stdio.h index a65f8bdb..621daccb 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -1,8 +1,8 @@ -#ifndef __STDIO__H -#define __STDIO__H -#include "PSX/jabyengine_defines.h" - -START_C_FUNCTIONS - int printf(const char* txt, ...) asm("_ZN10JabyEngine7SysCall6printfEPKcz"); -END_C_FUNCTIONS +#ifndef __STDIO__H +#define __STDIO__H +#include "PSX/jabyengine_defines.h" + +START_C_FUNCTIONS + int printf(const char* txt, ...) asm("_ZN10JabyEngine7SysCall6printfEPKcz"); +END_C_FUNCTIONS #endif //!__STDIO__H \ No newline at end of file diff --git a/mkfile/ExportPath.mk b/mkfile/ExportPath.mk index fcc3b8d3..2cbdb7a7 100644 --- a/mkfile/ExportPath.mk +++ b/mkfile/ExportPath.mk @@ -1,2 +1,2 @@ -#Add the JabyEngine tools to path +#Add the JabyEngine tools to path export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH) \ No newline at end of file diff --git a/mkfile/ISOMakefile.mk b/mkfile/ISOMakefile.mk index 3b00d8f8..487f60e0 100644 --- a/mkfile/ISOMakefile.mk +++ b/mkfile/ISOMakefile.mk @@ -1,13 +1,13 @@ -CD_OUTPUT ?= $(ARTIFACT).bin - -$(CD_OUTPUT): always - psxcdgen_ex --list $(ARTIFACT).lba -o $(ARTIFACT) psx bin-cue Config.xml - -all: $(CD_OUTPUT) - -clean: - rm -fr *.bin - rm -fr *.cue - rm -fr *.lba - +CD_OUTPUT ?= $(ARTIFACT).bin + +$(CD_OUTPUT): always + psxcdgen_ex --list $(ARTIFACT).lba -o $(ARTIFACT) psx bin-cue Config.xml + +all: $(CD_OUTPUT) + +clean: + rm -fr *.bin + rm -fr *.cue + rm -fr *.lba + always: ; \ No newline at end of file diff --git a/mkfile/Makefile b/mkfile/Makefile index 39e7961b..a058f5d5 100644 --- a/mkfile/Makefile +++ b/mkfile/Makefile @@ -1,98 +1,98 @@ -SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) -include $(SELF_DIR)ExportPath.mk - -substitute = $(subst $(JABY_ENGINE_DIR)/include/modules,!JABYENGINEMODULES,$(subst ..,!super,$1)) -desubstitute = $(subst !JABYENGINEMODULES,$(JABY_ENGINE_DIR)/include/modules,$(subst !super,..,$1)) - -#Build architecture/variant string, possible values: x86, armv7le, etc... -PLATFORM ?= PSX - -#Build profile, possible values: release, debug, profile, coverage -BUILD_DIR ?= bin -BUILD_PROFILE ?= debug -TV_FORMAT ?= PAL - -CONFIG_NAME ?= $(PLATFORM)-$(BUILD_PROFILE) -OUTPUT_DIR = $(BUILD_DIR)/$(CONFIG_NAME) -TARGET = $(OUTPUT_DIR)/$(ARTIFACT) - -#Compiler definitions -HAS_LINUX_MIPS_GCC = $(shell which mipsel-linux-gnu-gcc > /dev/null 2> /dev/null && echo true || echo false) -ifeq ($(HAS_LINUX_MIPS_GCC),true) -PREFIX ?= mipsel-linux-gnu -FORMAT ?= elf32-tradlittlemips -else -PREFIX ?= mipsel-none-elf -FORMAT ?= elf32-littlemips -endif - -#Take this to PSEXETarget.mk?? -#LDSCRIPT ?= $(PSCX_REDUX_DIR)/ps-exe.ld -#ifneq ($(strip $(OVERLAYSCRIPT)),) -#LDSCRIPT := $(addprefix $(OVERLAYSCRIPT) , -T$(LDSCRIPT)) -#else -#LDSCRIPT := $(addprefix $(PSCX_REDUX_DIR)/default.ld , -T$(LDSCRIPT)) -#endif - -CC = $(PREFIX)-gcc -CXX = $(PREFIX)-g++ -LD = $(CXX) -AR = ar - -#architecture flags -ARCHFLAGS = -march=r2000 -mtune=r2000 -mabi=32 -EL -fno-pic -mno-shared -nostdinc -nostdinc++ -mno-abicalls -mfp32 -mno-llsc -ARCHFLAGS += -fno-stack-protector -nostdlib -ffreestanding - -#Compiler flags for build profiles -CCFLAGS_release += -O3 -CCFLAGS_debug += -O0 - -CXXFLAGS += -fno-exceptions -fno-rtti - -CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections -fdata-sections -CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes -CCFLAGS += -std=c++20 -fmodules-ts -CCFLAGS += $(CCFLAGS_$(BUILD_PROFILE)) -CCFLAGS += $(ARCHFLAGS) -CCFLAGS += $(INCLUDES) -CCFLAGS += -DJABYENGINE_$(TV_FORMAT) - -#Linker flags -LDFLAGS_release += -Os - -LDFLAGS_all += -Wl,-Map=$(TARGET).map -nostdlib -T$(JABY_ENGINE_DIR)/mkfile/psexe.ld -static -Wl,--gc-sections -Wl,--build-id=none -Wl,--no-check-sections -LDFLAGS_all += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT) -LDFLAGS_all += $(LDFLAGS_$(BUILD_PROFILE)) - -LIBS_all += $(LIBS_$(BUILD_PROFILE)) - -DEPS = -Wp,-MMD,$(@:%.o=%.d),-MT,$@ - -#Object files list -MODS += $(call rwildcard,$(JABY_ENGINE_DIR)/include/modules, cxx) -SRCS := $(MODS) $(SRCS) -OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(call substitute,$(basename $(SRCS))))) - -#Compiling rule -.SECONDEXPANSION: -$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.s) - @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< - -.SECONDEXPANSION: -$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.c) - @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< - -.SECONDEXPANSION: -$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cpp) - @mkdir -p $(dir $@) - $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< - -.SECONDEXPANSION: -$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cxx) - @mkdir -p $(dir $@) - $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< - -#Inclusion of dependencies (object files to source and includes) +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)ExportPath.mk + +substitute = $(subst $(JABY_ENGINE_DIR)/include/modules,!JABYENGINEMODULES,$(subst ..,!super,$1)) +desubstitute = $(subst !JABYENGINEMODULES,$(JABY_ENGINE_DIR)/include/modules,$(subst !super,..,$1)) + +#Build architecture/variant string, possible values: x86, armv7le, etc... +PLATFORM ?= PSX + +#Build profile, possible values: release, debug, profile, coverage +BUILD_DIR ?= bin +BUILD_PROFILE ?= debug +TV_FORMAT ?= PAL + +CONFIG_NAME ?= $(PLATFORM)-$(BUILD_PROFILE) +OUTPUT_DIR = $(BUILD_DIR)/$(CONFIG_NAME) +TARGET = $(OUTPUT_DIR)/$(ARTIFACT) + +#Compiler definitions +HAS_LINUX_MIPS_GCC = $(shell which mipsel-linux-gnu-gcc > /dev/null 2> /dev/null && echo true || echo false) +ifeq ($(HAS_LINUX_MIPS_GCC),true) +PREFIX ?= mipsel-linux-gnu +FORMAT ?= elf32-tradlittlemips +else +PREFIX ?= mipsel-none-elf +FORMAT ?= elf32-littlemips +endif + +#Take this to PSEXETarget.mk?? +#LDSCRIPT ?= $(PSCX_REDUX_DIR)/ps-exe.ld +#ifneq ($(strip $(OVERLAYSCRIPT)),) +#LDSCRIPT := $(addprefix $(OVERLAYSCRIPT) , -T$(LDSCRIPT)) +#else +#LDSCRIPT := $(addprefix $(PSCX_REDUX_DIR)/default.ld , -T$(LDSCRIPT)) +#endif + +CC = $(PREFIX)-gcc +CXX = $(PREFIX)-g++ +LD = $(CXX) +AR = ar + +#architecture flags +ARCHFLAGS = -march=r2000 -mtune=r2000 -mabi=32 -EL -fno-pic -mno-shared -nostdinc -nostdinc++ -mno-abicalls -mfp32 -mno-llsc +ARCHFLAGS += -fno-stack-protector -nostdlib -ffreestanding + +#Compiler flags for build profiles +CCFLAGS_release += -O3 +CCFLAGS_debug += -O0 + +CXXFLAGS += -fno-exceptions -fno-rtti + +CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections -fdata-sections +CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes +CCFLAGS += -std=c++20 -fmodules-ts +CCFLAGS += $(CCFLAGS_$(BUILD_PROFILE)) +CCFLAGS += $(ARCHFLAGS) +CCFLAGS += $(INCLUDES) +CCFLAGS += -DJABYENGINE_$(TV_FORMAT) + +#Linker flags +LDFLAGS_release += -Os + +LDFLAGS_all += -Wl,-Map=$(TARGET).map -nostdlib -T$(JABY_ENGINE_DIR)/mkfile/psexe.ld -static -Wl,--gc-sections -Wl,--build-id=none -Wl,--no-check-sections +LDFLAGS_all += $(ARCHFLAGS) -Wl,--oformat=$(FORMAT) +LDFLAGS_all += $(LDFLAGS_$(BUILD_PROFILE)) + +LIBS_all += $(LIBS_$(BUILD_PROFILE)) + +DEPS = -Wp,-MMD,$(@:%.o=%.d),-MT,$@ + +#Object files list +MODS += $(call rwildcard,$(JABY_ENGINE_DIR)/include/modules, cxx) +SRCS := $(MODS) $(SRCS) +OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(call substitute,$(basename $(SRCS))))) + +#Compiling rule +.SECONDEXPANSION: +$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.s) + @mkdir -p $(dir $@) + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< + +.SECONDEXPANSION: +$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.c) + @mkdir -p $(dir $@) + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< + +.SECONDEXPANSION: +$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cpp) + @mkdir -p $(dir $@) + $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< + +.SECONDEXPANSION: +$(OUTPUT_DIR)/%.o: $$(call desubstitute,%.cxx) + @mkdir -p $(dir $@) + $(CXX) -c $(DEPS) -o $@ $(CCFLAGS) $(CXXFLAGS) $< + +#Inclusion of dependencies (object files to source and includes) -include $(OBJS:%.o=%.d) \ No newline at end of file diff --git a/mkfile/PSEXETarget.mk b/mkfile/PSEXETarget.mk index ceef5f28..c92b7ba4 100644 --- a/mkfile/PSEXETarget.mk +++ b/mkfile/PSEXETarget.mk @@ -1,37 +1,37 @@ -#Not intended to be overriden -AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay - -include $(AUTO_OVERLAY_DIR)/Overlays.mk - -#We use the JabyEngine so we will include ourselves -JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE) -JABY_ENGINE_LIB_NAME = JabyEngine_$(TV_FORMAT) - -OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) - -#Linking rule -$(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(AUTO_OVERLAY_DIR)/Overlays.ld - $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -L$(AUTO_OVERLAY_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) - -#Strips the psexe -$(TARGET).psexe: $(TARGET).elf - $(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@ - -#Create overlays -$(OVERLAY_TARGET): $(TARGET).elf - $(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@ - -#Create overlay makefile -$(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG) - @mkdir -p $(AUTO_OVERLAY_DIR) - mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $< - -#Rules section for default compilation and linking -all: $(TARGET).psexe $(OVERLAY_TARGET) - -clean: - rm -fr $(OUTPUT_DIR) - -# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated) -rebuild: clean - $(MAKE) all +#Not intended to be overriden +AUTO_OVERLAY_DIR = $(OUTPUT_DIR)/auto_overlay + +include $(AUTO_OVERLAY_DIR)/Overlays.mk + +#We use the JabyEngine so we will include ourselves +JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE) +JABY_ENGINE_LIB_NAME = JabyEngine_$(TV_FORMAT) + +OVERLAY_TARGET = $(foreach ovl, $(OVERLAYSECTION), $(OUTPUT_DIR)/Overlay$(ovl)) + +#Linking rule +$(TARGET).elf: $(OBJS) $(JABY_ENGINE_LIB_DIR)/lib$(JABY_ENGINE_LIB_NAME).a $(AUTO_OVERLAY_DIR)/Overlays.ld + $(LD) -o $(TARGET).elf $(LDFLAGS_all) $(LDFLAGS) $(OBJS) -L$(JABY_ENGINE_LIB_DIR) -L$(AUTO_OVERLAY_DIR) -l$(JABY_ENGINE_LIB_NAME) $(LIBS) + +#Strips the psexe +$(TARGET).psexe: $(TARGET).elf + $(PREFIX)-objcopy $(addprefix -R , $(OVERLAYSECTION)) -O binary $< $@ + +#Create overlays +$(OVERLAY_TARGET): $(TARGET).elf + $(PREFIX)-objcopy -j $(suffix $@) -O binary $< $@ + +#Create overlay makefile +$(AUTO_OVERLAY_DIR)/Overlays.mk: $(OVERLAY_CONFIG) + @mkdir -p $(AUTO_OVERLAY_DIR) + mkoverlay --mk-file $(AUTO_OVERLAY_DIR)/Overlays.mk --ld-script $(AUTO_OVERLAY_DIR)/Overlays.ld $< + +#Rules section for default compilation and linking +all: $(TARGET).psexe $(OVERLAY_TARGET) + +clean: + rm -fr $(OUTPUT_DIR) + +# For mkoverlay to function correctly this is required (otherwise Overlays.mk is not re-generated) +rebuild: clean + $(MAKE) all diff --git a/mkfile/Wildcard.mk b/mkfile/Wildcard.mk index d86f7509..b16caa2e 100644 --- a/mkfile/Wildcard.mk +++ b/mkfile/Wildcard.mk @@ -1,2 +1,2 @@ -#Macro to expand files recursively: parameters $1 - directory, $2 - extension, i.e. cpp +#Macro to expand files recursively: parameters $1 - directory, $2 - extension, i.e. cpp rwildcard = $(wildcard $(addprefix $1/*.,$2)) $(foreach d,$(wildcard $1/*),$(call rwildcard,$d,$2)) \ No newline at end of file diff --git a/mkfile/psexe.ld b/mkfile/psexe.ld index 441541ec..e2ef2a14 100644 --- a/mkfile/psexe.ld +++ b/mkfile/psexe.ld @@ -1,251 +1,251 @@ -/* - -MIT License - -Copyright (c) 2019 PCSX-Redux authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -OUTPUT_FORMAT("binary") -EXTERN(_ZN10JabyEngine5startEv) -ENTRY(_ZN10JabyEngine5startEv) - -TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; - -MEMORY { - loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 - ram(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 - ram_alt(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 - dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 -} - -__ram_top = ORIGIN(ram) + LENGTH(ram); -__sp = __ram_top - 0x100; - -__dcache = ORIGIN(dcache); -__dcache_top = ORIGIN(dcache) + LENGTH(dcache); - -__bss_len = (__bss_end - __bss_start); -__ftext_len = (__ftext_end - __ftext_start); -__fdata_len = (__planschi_end - __fdata_start); -__persistent_lbas_len = (__persistent_lbas_end - __persistent_lbas_start); - -__stack_start = ORIGIN(ram) + LENGTH(ram); - -SECTIONS { - /DISCARD/ : { *(.MIPS.abiflags) } - - /* Everything is statically linked, so discard PLTs. */ - /DISCARD/ : { *(.rel.iplt) *(.rela.iplt) *(.rel.plt) *(.rela.plt) *(.plt) *(.iplt) } - - /* Discard things that the standard link script drops, too. */ - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.*) *(.comment) } -} - -/*Overlay sections created by mkoverlay*/ -INCLUDE Overlays.ld -SECTIONS { - .planschi __engine_bss_end : SUBALIGN(4) - { - __planschi_start = .; - __boot_loader_start = .; - - *libJabyEngine_*.a:*_boot.o(.text.startup._GLOBAL__*) - *_boot.o(.text.startup._GLOBAL__*) - *libJabyEngine_*.a:*_boot.o(.ctors) - *_boot.o(.ctors) - - *libJabyEngine_*.a:*_boot.o(.text.*) - *_boot.o(.text.*) - *libJabyEngine_*.a:*_boot.o(.rodata*) - *_boot.o(.rodata*) - *libJabyEngine_*.a:*_boot.o(.sdata*) - *_boot.o(.sdata*) - *libJabyEngine_*.a:*_boot.o(.data*) - *_boot.o(.data*) - *libJabyEngine_*.a:*_boot.o(.sbss*) - *_boot.o(.sbss*) - *libJabyEngine_*.a:*_boot.o(.bss*) - *_boot.o(.bss*) - *libJabyEngine_*.a:*_boot.o(*) - *_boot.o(*) - - . = ALIGN(4); - __boot_loader_end = .; - /*Only needed for the PSX BIOS to load the entire game*/ - . = ALIGN(2048); - __planschi_end = .; - } > ram_alt -} - -SECTIONS { - .PSX_EXE_Header : { - /* - 0x0000 - 0x0007 : "PS-X EXE" - */ - BYTE(80); BYTE(83); BYTE(45); BYTE(88); BYTE(32); BYTE(69); BYTE(88); BYTE(69); - - /* 0x0008 - 0x000F : skip text_off and data_off since they're not supported by the PS1 BIOS */ - LONG(0); LONG(0); - - /* 0x0010 - 0x0013 : entry point */ - LONG(ABSOLUTE(_ZN10JabyEngine5startEv)); - - /* 0x0014 - 0x0017 : initial value of $gp */ - LONG(0); - - /* 0x0018 - 0x001B : Memory address to load "text" section to. */ - /* - NOTE: The "text" section is actually all of the "load" - sections of the file including .text, .rodata, .data. - etc. - */ - LONG(TLOAD_ADDR); - - /* 0x001C - 0x001F : size, in bytes, of the "text" section. */ - LONG(__persistent_lbas_len + __ftext_len + __fdata_len); - - /* 0x0020 - 0x002F : - Skip "data_addr", "data_size", "bss_addr" and "bss_size". - None of these are supported by retail PS1 BIOS. - */ - LONG(0); LONG(0); - LONG(0); LONG(0); - - /* 0x0030 - 0x0033 : Initial stack address. */ - LONG(DEFINED(_sp) ? ABSOLUTE(_sp) : 0x801FFF00); - - /* 0x0034 - 0x0037 : Initial stack size, set it to 0. */ - LONG(0); - - /* Skip the remaining fields as they're not supported by the BIOS */ - /* e.g. 2048 header bytes minus whatever we've actually used */ - . = . + 1992; - } > loader - - .persistent_lbas TLOAD_ADDR : { - __persistent_lbas_start = .; - __persistent_lbas = .; - KEEP(*(.header.lbas)) - . = ALIGN(4); - __persistent_lbas_end = .; - } > ram - - __ftext_start = ABSOLUTE(.); - .text : { - __text_start = .; - *(.start) - *(.init) - KEEP (*(SORT_NONE(.fini))) - *(.text.unlikely .text.*_unlikely .text.unlikely.*) - *(.text.exit .text.exit.*) - *(.text.startup .text.startup.*) - *(.text.hot .text.hot.*) - *(.text .stub .text.* .gnu.linkonce.t.*) - - . = ALIGN(16); - KEEP(*(.init)) - . = ALIGN(16); - KEEP(*(.fini)) - . = ALIGN(16); - __text_end = .; - } > ram - __ftext_end = ABSOLUTE(.); - - __fdata_start = ABSOLUTE(.); - .rodata : { - *(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*) - . = ALIGN(16); - __preinit_array_start = .; - KEEP (*(.preinit_array)) - __preinit_array_end = .; - - . = ALIGN(16); - __init_array_start = .; - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - - . = ALIGN(16); - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*crtend.o(.ctors)) - __init_array_end = .; - - . = ALIGN(16); - __fini_array_start = .; - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*crtend.o(.dtors)) - __fini_array_end = .; - __build_id = .; - *(.note.gnu.build-id) - __build_id_end = .; - } > ram - - .rodata1 : { - *(.rodata1) - } > ram - - .data : { - __data_start = .; - *(.a0table) - *(.data .data.* .gnu.linkonce.d.*) - *(.data1) - *(.sdata .sdata.* .gnu.linkonce.s.*) - *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) - *(.got.plt) - *(.got) - __data_end = .; - } > ram - - .engine_bss : { - __engine_bss_start = .; - *libJabyEngine_*.a:*(.dynsbss) - *libJabyEngine_*.a:*(.sbss .sbss.* .gnu.linkonce.sb.*) - *libJabyEngine_*.a:*(.scommon) - *libJabyEngine_*.a:*(.dynbss) - *libJabyEngine_*.a:*(.bss .bss.* .gnu.linkonce.b.*) - *libJabyEngine_*.a:*(COMMON) - . = ALIGN(4); - __engine_bss_end = .; - } > ram - __fdata_end = .; - - .bss __persistent_overlay_end (NOLOAD) : { - __bss_start = .; - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - __bss_end = .; - } > ram - - __heap_start = __bss_end; - __end = .; +/* + +MIT License + +Copyright (c) 2019 PCSX-Redux authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ + +OUTPUT_FORMAT("binary") +EXTERN(_ZN10JabyEngine5startEv) +ENTRY(_ZN10JabyEngine5startEv) + +TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; + +MEMORY { + loader : ORIGIN = (TLOAD_ADDR - 0x800), LENGTH = 2048 + ram(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 + ram_alt(rwx) : ORIGIN = 0x80010000, LENGTH = 2M - 0x10000 + dcache : ORIGIN = 0x1f800000, LENGTH = 0x400 +} + +__ram_top = ORIGIN(ram) + LENGTH(ram); +__sp = __ram_top - 0x100; + +__dcache = ORIGIN(dcache); +__dcache_top = ORIGIN(dcache) + LENGTH(dcache); + +__bss_len = (__bss_end - __bss_start); +__ftext_len = (__ftext_end - __ftext_start); +__fdata_len = (__planschi_end - __fdata_start); +__persistent_lbas_len = (__persistent_lbas_end - __persistent_lbas_start); + +__stack_start = ORIGIN(ram) + LENGTH(ram); + +SECTIONS { + /DISCARD/ : { *(.MIPS.abiflags) } + + /* Everything is statically linked, so discard PLTs. */ + /DISCARD/ : { *(.rel.iplt) *(.rela.iplt) *(.rel.plt) *(.rela.plt) *(.plt) *(.iplt) } + + /* Discard things that the standard link script drops, too. */ + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.*) *(.comment) } +} + +/*Overlay sections created by mkoverlay*/ +INCLUDE Overlays.ld +SECTIONS { + .planschi __engine_bss_end : SUBALIGN(4) + { + __planschi_start = .; + __boot_loader_start = .; + + *libJabyEngine_*.a:*_boot.o(.text.startup._GLOBAL__*) + *_boot.o(.text.startup._GLOBAL__*) + *libJabyEngine_*.a:*_boot.o(.ctors) + *_boot.o(.ctors) + + *libJabyEngine_*.a:*_boot.o(.text.*) + *_boot.o(.text.*) + *libJabyEngine_*.a:*_boot.o(.rodata*) + *_boot.o(.rodata*) + *libJabyEngine_*.a:*_boot.o(.sdata*) + *_boot.o(.sdata*) + *libJabyEngine_*.a:*_boot.o(.data*) + *_boot.o(.data*) + *libJabyEngine_*.a:*_boot.o(.sbss*) + *_boot.o(.sbss*) + *libJabyEngine_*.a:*_boot.o(.bss*) + *_boot.o(.bss*) + *libJabyEngine_*.a:*_boot.o(*) + *_boot.o(*) + + . = ALIGN(4); + __boot_loader_end = .; + /*Only needed for the PSX BIOS to load the entire game*/ + . = ALIGN(2048); + __planschi_end = .; + } > ram_alt +} + +SECTIONS { + .PSX_EXE_Header : { + /* + 0x0000 - 0x0007 : "PS-X EXE" + */ + BYTE(80); BYTE(83); BYTE(45); BYTE(88); BYTE(32); BYTE(69); BYTE(88); BYTE(69); + + /* 0x0008 - 0x000F : skip text_off and data_off since they're not supported by the PS1 BIOS */ + LONG(0); LONG(0); + + /* 0x0010 - 0x0013 : entry point */ + LONG(ABSOLUTE(_ZN10JabyEngine5startEv)); + + /* 0x0014 - 0x0017 : initial value of $gp */ + LONG(0); + + /* 0x0018 - 0x001B : Memory address to load "text" section to. */ + /* + NOTE: The "text" section is actually all of the "load" + sections of the file including .text, .rodata, .data. + etc. + */ + LONG(TLOAD_ADDR); + + /* 0x001C - 0x001F : size, in bytes, of the "text" section. */ + LONG(__persistent_lbas_len + __ftext_len + __fdata_len); + + /* 0x0020 - 0x002F : + Skip "data_addr", "data_size", "bss_addr" and "bss_size". + None of these are supported by retail PS1 BIOS. + */ + LONG(0); LONG(0); + LONG(0); LONG(0); + + /* 0x0030 - 0x0033 : Initial stack address. */ + LONG(DEFINED(_sp) ? ABSOLUTE(_sp) : 0x801FFF00); + + /* 0x0034 - 0x0037 : Initial stack size, set it to 0. */ + LONG(0); + + /* Skip the remaining fields as they're not supported by the BIOS */ + /* e.g. 2048 header bytes minus whatever we've actually used */ + . = . + 1992; + } > loader + + .persistent_lbas TLOAD_ADDR : { + __persistent_lbas_start = .; + __persistent_lbas = .; + KEEP(*(.header.lbas)) + . = ALIGN(4); + __persistent_lbas_end = .; + } > ram + + __ftext_start = ABSOLUTE(.); + .text : { + __text_start = .; + *(.start) + *(.init) + KEEP (*(SORT_NONE(.fini))) + *(.text.unlikely .text.*_unlikely .text.unlikely.*) + *(.text.exit .text.exit.*) + *(.text.startup .text.startup.*) + *(.text.hot .text.hot.*) + *(.text .stub .text.* .gnu.linkonce.t.*) + + . = ALIGN(16); + KEEP(*(.init)) + . = ALIGN(16); + KEEP(*(.fini)) + . = ALIGN(16); + __text_end = .; + } > ram + __ftext_end = ABSOLUTE(.); + + __fdata_start = ABSOLUTE(.); + .rodata : { + *(.rodata .rodata.* .rdata .rdata.* .gnu.linkonce.r.*) + . = ALIGN(16); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(16); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + + . = ALIGN(16); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + __init_array_end = .; + + . = ALIGN(16); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + __fini_array_end = .; + __build_id = .; + *(.note.gnu.build-id) + __build_id_end = .; + } > ram + + .rodata1 : { + *(.rodata1) + } > ram + + .data : { + __data_start = .; + *(.a0table) + *(.data .data.* .gnu.linkonce.d.*) + *(.data1) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) + *(.got.plt) + *(.got) + __data_end = .; + } > ram + + .engine_bss : { + __engine_bss_start = .; + *libJabyEngine_*.a:*(.dynsbss) + *libJabyEngine_*.a:*(.sbss .sbss.* .gnu.linkonce.sb.*) + *libJabyEngine_*.a:*(.scommon) + *libJabyEngine_*.a:*(.dynbss) + *libJabyEngine_*.a:*(.bss .bss.* .gnu.linkonce.b.*) + *libJabyEngine_*.a:*(COMMON) + . = ALIGN(4); + __engine_bss_end = .; + } > ram + __fdata_end = .; + + .bss __persistent_overlay_end (NOLOAD) : { + __bss_start = .; + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + } > ram + + __heap_start = __bss_end; + __end = .; } \ No newline at end of file diff --git a/src/Library/Makefile b/src/Library/Makefile index b54b5a39..77035462 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -1,50 +1,50 @@ -include ../../mkfile/RebuildTarget.mk -JABY_ENGINE_DIR = ../../ - -ARTIFACT = libJabyEngine_$(TV_FORMAT) -BUILD_DIR = bin - -SPLASH_IMAGE = src/BootLoader/splash_image_pal_boot.hpp -SPLASH_IMAGE_NTSC = src/BootLoader/splash_image_ntsc_boot.hpp - -CCFLAGS += -Iinclude -I../../include -D__friends=public -CCFLAGS += -save-temps=obj - -include ../../mkfile/Wildcard.mk -SRCS = $(call rwildcard, src, c cpp s) - -include ../../mkfile/Makefile -LIB_DIR = ../../lib/$(CONFIG_NAME) - -MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS)) - -#$(info $$var is [${MAIN_BOOT_OBJ}]) -#$(info $$var2 is [${MAIN_LIB_OBJS}]) - -#Linking rule -$(TARGET).a: $(MAIN_LIB_OBJS) $(SPLASH_IMAGE) - @mkdir -p $(dir $@) - $(AR) rcs $(TARGET).a $(MAIN_LIB_OBJS) - -#Copy rules -$(LIB_DIR)/$(ARTIFACT).a: $(TARGET).a - @mkdir -p $(LIB_DIR) - cp $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a - -# Improve later -# rule to make the boot image -$(SPLASH_IMAGE): ressources/Splash.png - jaby_engine_fconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ - -$(SPLASH_IMAGE_NTSC): ressources/Splash_ntsc.png - jaby_engine_fconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ - -#Rules section for default compilation and linking -all: $(SPLASH_IMAGE) $(SPLASH_IMAGE_NTSC) $(LIB_DIR)/$(ARTIFACT).a - -clean: - rm -fr $(SPLASH_IMAGE) - rm -fr $(SPLASH_IMAGE_NTSC) - rm -fr $(OUTPUT_DIR) - rm -fr gcm.cache +include ../../mkfile/RebuildTarget.mk +JABY_ENGINE_DIR = ../../ + +ARTIFACT = libJabyEngine_$(TV_FORMAT) +BUILD_DIR = bin + +SPLASH_IMAGE = src/BootLoader/splash_image_pal_boot.hpp +SPLASH_IMAGE_NTSC = src/BootLoader/splash_image_ntsc_boot.hpp + +CCFLAGS += -Iinclude -I../../include -D__friends=public +CCFLAGS += -save-temps=obj + +include ../../mkfile/Wildcard.mk +SRCS = $(call rwildcard, src, c cpp s) + +include ../../mkfile/Makefile +LIB_DIR = ../../lib/$(CONFIG_NAME) + +MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS)) + +#$(info $$var is [${MAIN_BOOT_OBJ}]) +#$(info $$var2 is [${MAIN_LIB_OBJS}]) + +#Linking rule +$(TARGET).a: $(MAIN_LIB_OBJS) $(SPLASH_IMAGE) + @mkdir -p $(dir $@) + $(AR) rcs $(TARGET).a $(MAIN_LIB_OBJS) + +#Copy rules +$(LIB_DIR)/$(ARTIFACT).a: $(TARGET).a + @mkdir -p $(LIB_DIR) + cp $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a + +# Improve later +# rule to make the boot image +$(SPLASH_IMAGE): ressources/Splash.png + jaby_engine_fconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ + +$(SPLASH_IMAGE_NTSC): ressources/Splash_ntsc.png + jaby_engine_fconv --lz4 $< simple-tim full16 | cpp_out --name SplashScreen -o $@ + +#Rules section for default compilation and linking +all: $(SPLASH_IMAGE) $(SPLASH_IMAGE_NTSC) $(LIB_DIR)/$(ARTIFACT).a + +clean: + rm -fr $(SPLASH_IMAGE) + rm -fr $(SPLASH_IMAGE_NTSC) + rm -fr $(OUTPUT_DIR) + rm -fr gcm.cache rm -fr $(LIB_DIR)/$(ARTIFACT).a \ No newline at end of file diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index bf73e1ae..82f91b7e 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -1,53 +1,53 @@ -#include "../../internal-include/BootLoader/boot_loader.hpp" -#include "../../internal-include/CD/cd_internal.hpp" -#include -#include -#include - -namespace JabyEngine { - namespace CD { - namespace internal { - extern SysCall::InterrupCallback callback; - } - } - - namespace boot { - namespace CD { - using JabyEngine::CD::internal::Command; - - void setup() { - static constexpr auto DebugX = 1; - static constexpr auto DebugY = 1; - static constexpr auto DebugScale = 1.0; - - __debug_boot_color_at(::JabyEngine::GPU::Color24::White(), DebugX, DebugY, DebugScale); - SysCall::EnterCriticalSection(); - Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::create()); - Memory_IO::CD_DELAY.write(Memory_IO::CD_DELAY::create()); - - SysCall::SysEnqIntRP(SysCall::Priority::CdromIoIrq, &::JabyEngine::CD::internal::callback); - - CD_IO::PortIndex1::change_to(); - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); - - CD_IO::Interrupt::enable(CD_IO::PortIndex1::InterruptEnable); - - Interrupt::enable_irq(Interrupt::CDROM); - Interrupt::ack_irq(Interrupt::CDROM); - SysCall::ExitCriticalSection(); - - __debug_boot_color_at(::JabyEngine::GPU::Color24::Red(), DebugX, DebugY, DebugScale); - CD_IO::PortIndex0::change_to(); - - __debug_boot_color_at(::JabyEngine::GPU::Color24::Green(), DebugX, DebugY, DebugScale); - Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); - __debug_boot_color_at(::JabyEngine::GPU::Color24::Blue(), DebugX, DebugY, DebugScale); - Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); - __debug_boot_color_at(::JabyEngine::GPU::Color24::Yellow(), DebugX, DebugY, DebugScale); - Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::Init); - - // Demute? - } - } - } +#include "../../internal-include/BootLoader/boot_loader.hpp" +#include "../../internal-include/CD/cd_internal.hpp" +#include +#include +#include + +namespace JabyEngine { + namespace CD { + namespace internal { + extern SysCall::InterrupCallback callback; + } + } + + namespace boot { + namespace CD { + using JabyEngine::CD::internal::Command; + + void setup() { + static constexpr auto DebugX = 1; + static constexpr auto DebugY = 1; + static constexpr auto DebugScale = 1.0; + + __debug_boot_color_at(::JabyEngine::GPU::Color24::White(), DebugX, DebugY, DebugScale); + SysCall::EnterCriticalSection(); + Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::create()); + Memory_IO::CD_DELAY.write(Memory_IO::CD_DELAY::create()); + + SysCall::SysEnqIntRP(SysCall::Priority::CdromIoIrq, &::JabyEngine::CD::internal::callback); + + CD_IO::PortIndex1::change_to(); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + + CD_IO::Interrupt::enable(CD_IO::PortIndex1::InterruptEnable); + + Interrupt::enable_irq(Interrupt::CDROM); + Interrupt::ack_irq(Interrupt::CDROM); + SysCall::ExitCriticalSection(); + + __debug_boot_color_at(::JabyEngine::GPU::Color24::Red(), DebugX, DebugY, DebugScale); + CD_IO::PortIndex0::change_to(); + + __debug_boot_color_at(::JabyEngine::GPU::Color24::Green(), DebugX, DebugY, DebugScale); + Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); + __debug_boot_color_at(::JabyEngine::GPU::Color24::Blue(), DebugX, DebugY, DebugScale); + Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); + __debug_boot_color_at(::JabyEngine::GPU::Color24::Yellow(), DebugX, DebugY, DebugScale); + Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::Init); + + // Demute? + } + } + } } \ No newline at end of file diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 55f86c02..e0215836 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -1,83 +1,83 @@ -#include "../../internal-include/GPU/gpu_internal.hpp" -#include -#include -#include -#include -#include -#include - -#ifdef JABYENGINE_PAL - #include "splash_image_pal_boot.hpp" -#else - #include "splash_image_ntsc_boot.hpp" -#endif //JABYENGINE_PAL - -extern "C" uint32_t __boot_loader_end; - -namespace JabyEngine { - namespace GPU { - namespace internal { - extern SysCall::InterrupCallback callback; - } - } - - namespace boot { - namespace GPU { - using namespace JabyEngine::GPU; - - static void configurate_display() { - // Ideal I hope that an offset of 0,0 will produce a well enough centered picture for every TV - GPU_IO::GP1.write(GPU_IO::Command::DisplayMode(::JabyEngine::GPU::internal::Display::DisplayMode)); - GPU::Display::set_offset(0, 0); - } - - static size_t decompress_logo() { - LZ4Decompressor lz4_decomp(reinterpret_cast(&__boot_loader_end)); - - const auto [progress, bytes_ready] = lz4_decomp.process(ArrayRange(SplashScreen, sizeof(SplashScreen)), true); - switch(progress) { - case Progress::InProgress: - printf("Decompressing still in progress... %llu\n", bytes_ready); - break; - - case Progress::Error: - printf("Error decompressing!!!\n"); - break; - - case Progress::Done: - printf("Done decompressing: %llu Bytes ready\n", bytes_ready); - break; - } - - return bytes_ready; - } - - void display_logo() { - const auto bytes_ready = decompress_logo(); - - // Upload SplashScreen picture - auto state = FileProcessor::create(&__boot_loader_end, SimpleTIM(32, 0, 0, 0)); - state.process(bytes_ready); - - // Duplicate DisplayBuffer content - ::JabyEngine::GPU::internal::copy_vram_to_vram({PositionU16::create(0, Display::Height), SizeU16::create(Display::Width, Display::Height)}, PositionU16::create(0, 0)); - - Display::enable(); - } - - void setup() { - GPU_IO::GP1.write(GPU_IO::Command::Reset()); - configurate_display(); - ::JabyEngine::GPU::internal::Display::exchange_buffer_and_display(); - - GPU::internal::wait_ready_for_CMD(); - GPU::internal::quick_fill_fast(Color24::Black(), {PositionU16::create(0, 0), SizeU16::create(Display::Width, Display::Height)}); - - SysCall::EnterCriticalSection(); - SysCall::SysEnqIntRP(SysCall::Priority::VblankIrq, &::JabyEngine::GPU::internal::callback); - Interrupt::enable_irq(Interrupt::VBlank); - SysCall::ExitCriticalSection(); - } - } - } +#include "../../internal-include/GPU/gpu_internal.hpp" +#include +#include +#include +#include +#include +#include + +#ifdef JABYENGINE_PAL + #include "splash_image_pal_boot.hpp" +#else + #include "splash_image_ntsc_boot.hpp" +#endif //JABYENGINE_PAL + +extern "C" uint32_t __boot_loader_end; + +namespace JabyEngine { + namespace GPU { + namespace internal { + extern SysCall::InterrupCallback callback; + } + } + + namespace boot { + namespace GPU { + using namespace JabyEngine::GPU; + + static void configurate_display() { + // Ideal I hope that an offset of 0,0 will produce a well enough centered picture for every TV + GPU_IO::GP1.write(GPU_IO::Command::DisplayMode(::JabyEngine::GPU::internal::Display::DisplayMode)); + GPU::Display::set_offset(0, 0); + } + + static size_t decompress_logo() { + LZ4Decompressor lz4_decomp(reinterpret_cast(&__boot_loader_end)); + + const auto [progress, bytes_ready] = lz4_decomp.process(ArrayRange(SplashScreen, sizeof(SplashScreen)), true); + switch(progress) { + case Progress::InProgress: + printf("Decompressing still in progress... %llu\n", bytes_ready); + break; + + case Progress::Error: + printf("Error decompressing!!!\n"); + break; + + case Progress::Done: + printf("Done decompressing: %llu Bytes ready\n", bytes_ready); + break; + } + + return bytes_ready; + } + + void display_logo() { + const auto bytes_ready = decompress_logo(); + + // Upload SplashScreen picture + auto state = FileProcessor::create(&__boot_loader_end, SimpleTIM(32, 0, 0, 0)); + state.process(bytes_ready); + + // Duplicate DisplayBuffer content + ::JabyEngine::GPU::internal::copy_vram_to_vram({PositionU16::create(0, Display::Height), SizeU16::create(Display::Width, Display::Height)}, PositionU16::create(0, 0)); + + Display::enable(); + } + + void setup() { + GPU_IO::GP1.write(GPU_IO::Command::Reset()); + configurate_display(); + ::JabyEngine::GPU::internal::Display::exchange_buffer_and_display(); + + GPU::internal::wait_ready_for_CMD(); + GPU::internal::quick_fill_fast(Color24::Black(), {PositionU16::create(0, 0), SizeU16::create(Display::Width, Display::Height)}); + + SysCall::EnterCriticalSection(); + SysCall::SysEnqIntRP(SysCall::Priority::VblankIrq, &::JabyEngine::GPU::internal::callback); + Interrupt::enable_irq(Interrupt::VBlank); + SysCall::ExitCriticalSection(); + } + } + } } \ No newline at end of file diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index a1f0e168..72ad2083 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -1,141 +1,141 @@ -#include "../../internal-include/CD/cd_internal.hpp" -#include -#include -#include - -namespace JabyEngine { - namespace CD { - namespace internal { - static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); - - static SysCall::InterruptVerifierResult interrupt_verifier(); - static uint32_t interrupt_handler(uint32_t); - - static SectorBufferAllocator sector_allocator; - static uint32_t cur_lba; - static uint32_t dst_lba; - - CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; - uint8_t cmd_interrupt_bit = 0; - State current_state = State::Free; - SysCall::InterrupCallback callback = { - .next = nullptr, - .handler_function = interrupt_handler, - .verifier_function = interrupt_verifier - }; - - static void pause_cd() { - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Pause); - } - - // Requires Index0 - static void read_cd(uint32_t lba) { - const auto loc = CDTimeStamp::from(lba); - - Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); - Command::send(CD_IO::Command::ReadN); - current_state = State::Reading; - } - - static void read_sector_dma(CD_IO::DataSector& sector) { - static const auto WaitSectorReady = []() { - while(!CD_IO::IndexStatus.read().is_set(CD_IO::IndexStatus::HasDataFifoData)); - }; - - static const auto ReadSector = [](uint32_t* dst) { - DMA_IO::CDROM.set_adr(reinterpret_cast(dst)); - DMA_IO::CDROM.block_ctrl.write(DMA_IO::BCR::SyncMode0::for_cd()); - DMA_IO::CDROM.channel_ctrl.write(DMA_IO::CHCHR::StartCDROM()); - - DMA_IO::CDROM.wait(); - - CD_IO::PortIndex0::Request.write(CD_IO::Request::reset()); - }; - - WaitSectorReady(); - ReadSector(sector.data); - } - - static void read_sector_to(CD_IO::DataSector& sector) { - CD_IO::PortIndex0::change_to(); - CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data()); - - // We only support DMA rn - read_sector_dma(sector); - - // Do we ever want to support reading via IO Port? - // Doesn't seem to important when we can use DMA - } - - static SysCall::InterruptVerifierResult interrupt_verifier() { - if(Interrupt::is_irq(Interrupt::CDROM)) { - return SysCall::InterruptVerifierResult::ExecuteHandler; - } - - else { - return SysCall::InterruptVerifierResult::SkipHandler; - } - } - - static uint32_t interrupt_handler(uint32_t) { - const auto old_status = CD_IO::IndexStatus.read(); - - CD_IO::PortIndex1::change_to(); - const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); - last_interrupt = cur_irq; - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); - - cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); - if(cur_irq == CD_IO::Interrupt::DataReady) { - // Obtain sector content here - auto* sector = sector_allocator.allocate_sector(); - if(sector) { - //Now obtain sector - read_sector_to(*sector); - - cur_lba++; - if(cur_lba == dst_lba) { - current_state = State::Done; - pause_cd(); - } - } - - else { - current_state = State::BufferFull; - pause_cd(); - } - } - - else if(cur_irq == CD_IO::Interrupt::DiskError) { - current_state = State::Error; - } - - // No masking required because we can only write bit 0 - 2 - CD_IO::IndexStatus.write(old_status); - Interrupt::ack_irq(Interrupt::CDROM); - SysCall::ReturnFromException(); - __builtin_unreachable(); - } - - void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) { - cur_lba = file_info.get_lba(); - dst_lba = cur_lba + file_info.get_size_in_sectors(); - sector_allocator = buffer_allocator; - - Command::wait_completed(); - CD_IO::PortIndex0::change_to(); - Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); - - read_cd(cur_lba); - } - - void continue_reading() { - if(current_state == State::BufferFull) { - Command::wait_completed(); - read_cd(cur_lba); - } - } - } - } +#include "../../internal-include/CD/cd_internal.hpp" +#include +#include +#include + +namespace JabyEngine { + namespace CD { + namespace internal { + static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); + + static SysCall::InterruptVerifierResult interrupt_verifier(); + static uint32_t interrupt_handler(uint32_t); + + static SectorBufferAllocator sector_allocator; + static uint32_t cur_lba; + static uint32_t dst_lba; + + CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; + uint8_t cmd_interrupt_bit = 0; + State current_state = State::Free; + SysCall::InterrupCallback callback = { + .next = nullptr, + .handler_function = interrupt_handler, + .verifier_function = interrupt_verifier + }; + + static void pause_cd() { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Pause); + } + + // Requires Index0 + static void read_cd(uint32_t lba) { + const auto loc = CDTimeStamp::from(lba); + + Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); + Command::send(CD_IO::Command::ReadN); + current_state = State::Reading; + } + + static void read_sector_dma(CD_IO::DataSector& sector) { + static const auto WaitSectorReady = []() { + while(!CD_IO::IndexStatus.read().is_set(CD_IO::IndexStatus::HasDataFifoData)); + }; + + static const auto ReadSector = [](uint32_t* dst) { + DMA_IO::CDROM.set_adr(reinterpret_cast(dst)); + DMA_IO::CDROM.block_ctrl.write(DMA_IO::BCR::SyncMode0::for_cd()); + DMA_IO::CDROM.channel_ctrl.write(DMA_IO::CHCHR::StartCDROM()); + + DMA_IO::CDROM.wait(); + + CD_IO::PortIndex0::Request.write(CD_IO::Request::reset()); + }; + + WaitSectorReady(); + ReadSector(sector.data); + } + + static void read_sector_to(CD_IO::DataSector& sector) { + CD_IO::PortIndex0::change_to(); + CD_IO::PortIndex0::Request.write(CD_IO::Request::want_data()); + + // We only support DMA rn + read_sector_dma(sector); + + // Do we ever want to support reading via IO Port? + // Doesn't seem to important when we can use DMA + } + + static SysCall::InterruptVerifierResult interrupt_verifier() { + if(Interrupt::is_irq(Interrupt::CDROM)) { + return SysCall::InterruptVerifierResult::ExecuteHandler; + } + + else { + return SysCall::InterruptVerifierResult::SkipHandler; + } + } + + static uint32_t interrupt_handler(uint32_t) { + const auto old_status = CD_IO::IndexStatus.read(); + + CD_IO::PortIndex1::change_to(); + const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); + last_interrupt = cur_irq; + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + + cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); + if(cur_irq == CD_IO::Interrupt::DataReady) { + // Obtain sector content here + auto* sector = sector_allocator.allocate_sector(); + if(sector) { + //Now obtain sector + read_sector_to(*sector); + + cur_lba++; + if(cur_lba == dst_lba) { + current_state = State::Done; + pause_cd(); + } + } + + else { + current_state = State::BufferFull; + pause_cd(); + } + } + + else if(cur_irq == CD_IO::Interrupt::DiskError) { + current_state = State::Error; + } + + // No masking required because we can only write bit 0 - 2 + CD_IO::IndexStatus.write(old_status); + Interrupt::ack_irq(Interrupt::CDROM); + SysCall::ReturnFromException(); + __builtin_unreachable(); + } + + void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) { + cur_lba = file_info.get_lba(); + dst_lba = cur_lba + file_info.get_size_in_sectors(); + sector_allocator = buffer_allocator; + + Command::wait_completed(); + CD_IO::PortIndex0::change_to(); + Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); + + read_cd(cur_lba); + } + + void continue_reading() { + if(current_state == State::BufferFull) { + Command::wait_completed(); + read_cd(cur_lba); + } + } + } + } } \ No newline at end of file diff --git a/src/Library/src/File/Processor/simplehelper.hpp b/src/Library/src/File/Processor/simplehelper.hpp index a04de427..983233d8 100644 --- a/src/Library/src/File/Processor/simplehelper.hpp +++ b/src/Library/src/File/Processor/simplehelper.hpp @@ -1,25 +1,25 @@ -#ifndef __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__ -#define __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__ - -#include - -namespace JabyEngine { - namespace FileProcessor { - namespace Helper { - template - static void simple_read(T& dst, State::Configuration& config) { - static constexpr size_t T_SIZE = sizeof(T); - - dst = *reinterpret_cast(config.data_adr); - config.processed(T_SIZE); - } - - template - static Progress exchange_and_execute_process_function(State::GenericProcessRoutine process_routine, State::Configuration& config, T& state) { - config.process_routine = reinterpret_cast(process_routine); - return process_routine(config, state); - } - } - } -} +#ifndef __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__ +#define __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__ + +#include + +namespace JabyEngine { + namespace FileProcessor { + namespace Helper { + template + static void simple_read(T& dst, State::Configuration& config) { + static constexpr size_t T_SIZE = sizeof(T); + + dst = *reinterpret_cast(config.data_adr); + config.processed(T_SIZE); + } + + template + static Progress exchange_and_execute_process_function(State::GenericProcessRoutine process_routine, State::Configuration& config, T& state) { + config.process_routine = reinterpret_cast(process_routine); + return process_routine(config, state); + } + } + } +} #endif // !__JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__ \ No newline at end of file diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 64f81e53..781ed3e5 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,102 +1,102 @@ -#include "../../internal-include/GPU/gpu_internal.hpp" -#include -#include -#include - -namespace JabyEngine { - namespace GPU { - uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 - - namespace internal { - static SysCall::InterruptVerifierResult interrupt_verifier(); - static uint32_t interrupt_handler(uint32_t); - - static uint8_t vsync_counter = 0; - - SysCall::InterrupCallback callback = { - .next = nullptr, - .handler_function = interrupt_handler, - .verifier_function = interrupt_verifier - }; - - static SysCall::InterruptVerifierResult interrupt_verifier() { - if(Interrupt::is_irq(Interrupt::VBlank)) { - return SysCall::InterruptVerifierResult::ExecuteHandler; - } - - else { - return SysCall::InterruptVerifierResult::SkipHandler; - } - } - - static uint32_t interrupt_handler(uint32_t) { - vsync_counter++; - MasterTime::value++; - - Interrupt::ack_irq(Interrupt::VBlank); - SysCall::ReturnFromException(); - __builtin_unreachable(); - } - - uint32_t Display :: exchange_buffer_and_display() { - const uint16_t draw_area_y = (PublicDisplay::Height*PublicDisplay::current_id); - - GPU::internal::set_draw_area(GPU::PositionU16::create(0, draw_area_y)); - PublicDisplay::current_id ^= 1; - GPU_IO::GP1.write(GPU_IO::Command::DisplayArea(GPU::PositionU16::create(0, static_cast((PublicDisplay::Height*PublicDisplay::current_id))))); - return draw_area_y; - } - - void wait_vsync(uint8_t syncs) { - volatile auto& vsync_count = reinterpret_cast(vsync_counter); - const uint8_t dst_value = vsync_count + syncs; - - while(vsync_count != dst_value); - } - - void render(const uint32_t* data, size_t words) { - wait_ready_for_CMD(); - for(size_t n = 0; n < words; n++) { - GPU_IO::GP0.write({data[n]}); - } - } - - void render_dma(const uint32_t* data) { - wait_ready_for_CMD(); - // DPCR already enabled - GPU_IO::GP1.write(GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU)); - DMA_IO::GPU.set_adr(reinterpret_cast(data)); - DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR::SyncMode2::for_gpu_cmd()); - DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPULinked()); - } - } - - #ifndef USE_NO$PSX - void Display :: set_offset(uint16_t x, uint16_t y) { - x += 78; - y += 43; - - GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); - GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height)); - } - #else - void Display :: set_offset(uint16_t x, uint16_t y) { - GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8))); - GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2))); - } - #endif //USE_NO$PSX - - uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen) { - // Waits for finish FIFO - internal::wait_ready_for_CMD(); - - internal::wait_vsync(syncs); - const int16_t draw_offset_y = internal::Display::exchange_buffer_and_display(); - internal::set_draw_offset(GPU::PositionI16::create(0, draw_offset_y)); - if(clear_screen) { - internal::quick_fill_fast(Color24::Black(), AreaU16::create(0, static_cast(draw_offset_y), Display::Width, Display::Height)); - } - return Display::current_id; - } - } +#include "../../internal-include/GPU/gpu_internal.hpp" +#include +#include +#include + +namespace JabyEngine { + namespace GPU { + uint8_t Display :: current_id = 1; //< Setup will call exchange and set it to 0 + + namespace internal { + static SysCall::InterruptVerifierResult interrupt_verifier(); + static uint32_t interrupt_handler(uint32_t); + + static uint8_t vsync_counter = 0; + + SysCall::InterrupCallback callback = { + .next = nullptr, + .handler_function = interrupt_handler, + .verifier_function = interrupt_verifier + }; + + static SysCall::InterruptVerifierResult interrupt_verifier() { + if(Interrupt::is_irq(Interrupt::VBlank)) { + return SysCall::InterruptVerifierResult::ExecuteHandler; + } + + else { + return SysCall::InterruptVerifierResult::SkipHandler; + } + } + + static uint32_t interrupt_handler(uint32_t) { + vsync_counter++; + MasterTime::value++; + + Interrupt::ack_irq(Interrupt::VBlank); + SysCall::ReturnFromException(); + __builtin_unreachable(); + } + + uint32_t Display :: exchange_buffer_and_display() { + const uint16_t draw_area_y = (PublicDisplay::Height*PublicDisplay::current_id); + + GPU::internal::set_draw_area(GPU::PositionU16::create(0, draw_area_y)); + PublicDisplay::current_id ^= 1; + GPU_IO::GP1.write(GPU_IO::Command::DisplayArea(GPU::PositionU16::create(0, static_cast((PublicDisplay::Height*PublicDisplay::current_id))))); + return draw_area_y; + } + + void wait_vsync(uint8_t syncs) { + volatile auto& vsync_count = reinterpret_cast(vsync_counter); + const uint8_t dst_value = vsync_count + syncs; + + while(vsync_count != dst_value); + } + + void render(const uint32_t* data, size_t words) { + wait_ready_for_CMD(); + for(size_t n = 0; n < words; n++) { + GPU_IO::GP0.write({data[n]}); + } + } + + void render_dma(const uint32_t* data) { + wait_ready_for_CMD(); + // DPCR already enabled + GPU_IO::GP1.write(GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU)); + DMA_IO::GPU.set_adr(reinterpret_cast(data)); + DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR::SyncMode2::for_gpu_cmd()); + DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPULinked()); + } + } + + #ifndef USE_NO$PSX + void Display :: set_offset(uint16_t x, uint16_t y) { + x += 78; + y += 43; + + GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); + GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height)); + } + #else + void Display :: set_offset(uint16_t x, uint16_t y) { + GPU_IO::GP1.write(GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8))); + GPU_IO::GP1.write(GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2))); + } + #endif //USE_NO$PSX + + uint8_t swap_buffers_vsync(uint8_t syncs, bool clear_screen) { + // Waits for finish FIFO + internal::wait_ready_for_CMD(); + + internal::wait_vsync(syncs); + const int16_t draw_offset_y = internal::Display::exchange_buffer_and_display(); + internal::set_draw_offset(GPU::PositionI16::create(0, draw_offset_y)); + if(clear_screen) { + internal::quick_fill_fast(Color24::Black(), AreaU16::create(0, static_cast(draw_offset_y), Display::Width, Display::Height)); + } + return Display::current_id; + } + } } \ No newline at end of file diff --git a/src/Library/src/syscall_printf.s b/src/Library/src/syscall_printf.s index 4324da91..2f8cdf27 100644 --- a/src/Library/src/syscall_printf.s +++ b/src/Library/src/syscall_printf.s @@ -1,12 +1,12 @@ - .set push - .set noreorder - .section .text, "ax", @progbits - .align 2 - .global _ZN10JabyEngine7SysCall6printfEPKcz - .type _ZN10JabyEngine7SysCall6printfEPKcz, @function - -_ZN10JabyEngine7SysCall6printfEPKcz: - li $t2, 0xa0 - jr $t2 - li $t1, 0x3f + .set push + .set noreorder + .section .text, "ax", @progbits + .align 2 + .global _ZN10JabyEngine7SysCall6printfEPKcz + .type _ZN10JabyEngine7SysCall6printfEPKcz, @function + +_ZN10JabyEngine7SysCall6printfEPKcz: + li $t2, 0xa0 + jr $t2 + li $t1, 0x3f \ No newline at end of file