Disable auto crlf
This commit is contained in:
parent
9e235a310c
commit
6d4916178c
|
@ -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
|
|
@ -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: ;
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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<typename T>
|
||||
using GenericProcessRoutine = Progress (*)(Configuration&, T&);
|
||||
|
||||
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
||||
|
||||
struct Configuration {
|
||||
ProcessRoutine process_routine = nullptr;
|
||||
const uint8_t* data_adr = nullptr;
|
||||
size_t data_bytes = 0ull;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline Configuration from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) {
|
||||
return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr};
|
||||
}
|
||||
|
||||
constexpr void processed(size_t bytes) {
|
||||
this->data_adr += bytes;
|
||||
this->data_bytes -= bytes;
|
||||
}
|
||||
};
|
||||
|
||||
__friends:
|
||||
Configuration config;
|
||||
Reserved reserved;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline State from(const T& reserved, const uint8_t* data_adr, GenericProcessRoutine<T> process_routine) {
|
||||
return {Configuration::from(process_routine, data_adr), *reinterpret_cast<const Reserved*>(&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<typename T>
|
||||
using GenericProcessRoutine = Progress (*)(Configuration&, T&);
|
||||
|
||||
typedef GenericProcessRoutine<Reserved> ProcessRoutine;
|
||||
|
||||
struct Configuration {
|
||||
ProcessRoutine process_routine = nullptr;
|
||||
const uint8_t* data_adr = nullptr;
|
||||
size_t data_bytes = 0ull;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline Configuration from(GenericProcessRoutine<T> process_routine, const uint8_t* data_adr) {
|
||||
return {reinterpret_cast<ProcessRoutine>(process_routine), data_adr};
|
||||
}
|
||||
|
||||
constexpr void processed(size_t bytes) {
|
||||
this->data_adr += bytes;
|
||||
this->data_bytes -= bytes;
|
||||
}
|
||||
};
|
||||
|
||||
__friends:
|
||||
Configuration config;
|
||||
Reserved reserved;
|
||||
|
||||
template<typename T>
|
||||
static __always_inline State from(const T& reserved, const uint8_t* data_adr, GenericProcessRoutine<T> process_routine) {
|
||||
return {Configuration::from(process_routine, data_adr), *reinterpret_cast<const Reserved*>(&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);
|
||||
}
|
||||
}
|
|
@ -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, ...);
|
||||
}
|
||||
}
|
|
@ -1,59 +1,59 @@
|
|||
#ifndef __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#define __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#include "frame_time_helper.hpp"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace JabyEngine {
|
||||
class MasterTime {
|
||||
__friends:
|
||||
static uint32_t value;
|
||||
|
||||
public:
|
||||
static uint32_t read() {
|
||||
return reinterpret_cast<volatile uint32_t&>(MasterTime::value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T read_as() {
|
||||
return static_cast<T>(MasterTime::read());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SimpleTimer {
|
||||
protected:
|
||||
T value = 0;
|
||||
|
||||
public:
|
||||
constexpr SimpleTimer() = default;
|
||||
|
||||
bool is_expired_for(T time) const {
|
||||
return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->value = MasterTime::read_as<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class IntervalTimer : public SimpleTimer<T> {
|
||||
private:
|
||||
T interval = 0;
|
||||
|
||||
public:
|
||||
constexpr IntervalTimer() = default;
|
||||
constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) {
|
||||
}
|
||||
|
||||
void set_interval(T interval) {
|
||||
this->interval = interval;
|
||||
}
|
||||
|
||||
bool is_expired() const {
|
||||
return SimpleTimer<T>::is_expired_for(this->interval);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#define __JABYENGINE_FRAME_TIMER_HPP__
|
||||
#include "frame_time_helper.hpp"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace JabyEngine {
|
||||
class MasterTime {
|
||||
__friends:
|
||||
static uint32_t value;
|
||||
|
||||
public:
|
||||
static uint32_t read() {
|
||||
return reinterpret_cast<volatile uint32_t&>(MasterTime::value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T read_as() {
|
||||
return static_cast<T>(MasterTime::read());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class SimpleTimer {
|
||||
protected:
|
||||
T value = 0;
|
||||
|
||||
public:
|
||||
constexpr SimpleTimer() = default;
|
||||
|
||||
bool is_expired_for(T time) const {
|
||||
return static_cast<T>((MasterTime::read_as<T>() - this->value)) >= time;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
this->value = MasterTime::read_as<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class IntervalTimer : public SimpleTimer<T> {
|
||||
private:
|
||||
T interval = 0;
|
||||
|
||||
public:
|
||||
constexpr IntervalTimer() = default;
|
||||
constexpr IntervalTimer(T interval) : SimpleTimer<T>(), interval(interval) {
|
||||
}
|
||||
|
||||
void set_interval(T interval) {
|
||||
this->interval = interval;
|
||||
}
|
||||
|
||||
bool is_expired() const {
|
||||
return SimpleTimer<T>::is_expired_for(this->interval);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif //!__JABYENGINE_FRAME_TIMER_HPP__
|
|
@ -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__
|
|
@ -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
|
|
@ -1,2 +1,2 @@
|
|||
#Add the JabyEngine tools to path
|
||||
#Add the JabyEngine tools to path
|
||||
export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH)
|
|
@ -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: ;
|
194
mkfile/Makefile
194
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)
|
|
@ -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
|
||||
|
|
|
@ -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))
|
500
mkfile/psexe.ld
500
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 = .;
|
||||
}
|
|
@ -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
|
|
@ -1,53 +1,53 @@
|
|||
#include "../../internal-include/BootLoader/boot_loader.hpp"
|
||||
#include "../../internal-include/CD/cd_internal.hpp"
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/IOPorts/memory_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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 <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/IOPorts/memory_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +1,83 @@
|
|||
#include "../../internal-include/GPU/gpu_internal.hpp"
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/Auxiliary/lz4_decompressor.hpp>
|
||||
#include <PSX/File/Processor/file_processor.hpp>
|
||||
#include <PSX/GPU/gpu.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
#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<uint8_t*>(&__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 <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/Auxiliary/lz4_decompressor.hpp>
|
||||
#include <PSX/File/Processor/file_processor.hpp>
|
||||
#include <PSX/GPU/gpu.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
#include <stdio.h>
|
||||
|
||||
#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<uint8_t*>(&__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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,141 +1,141 @@
|
|||
#include "../../internal-include/CD/cd_internal.hpp"
|
||||
#include <PSX/System/IOPorts/dma_io.hpp>
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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::PortIndex0>(CD_IO::Command::Pause);
|
||||
}
|
||||
|
||||
// Requires Index0
|
||||
static void read_cd(uint32_t lba) {
|
||||
const auto loc = CDTimeStamp::from(lba);
|
||||
|
||||
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd());
|
||||
Command::send<CD_IO::PortIndex0>(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<uintptr_t>(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::PortIndex0>(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 <PSX/System/IOPorts/dma_io.hpp>
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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::PortIndex0>(CD_IO::Command::Pause);
|
||||
}
|
||||
|
||||
// Requires Index0
|
||||
static void read_cd(uint32_t lba) {
|
||||
const auto loc = CDTimeStamp::from(lba);
|
||||
|
||||
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd());
|
||||
Command::send<CD_IO::PortIndex0>(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<uintptr_t>(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::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode);
|
||||
|
||||
read_cd(cur_lba);
|
||||
}
|
||||
|
||||
void continue_reading() {
|
||||
if(current_state == State::BufferFull) {
|
||||
Command::wait_completed();
|
||||
read_cd(cur_lba);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +1,25 @@
|
|||
#ifndef __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__
|
||||
#define __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__
|
||||
|
||||
#include <PSX/File/Processor/file_processor.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
namespace Helper {
|
||||
template<typename T>
|
||||
static void simple_read(T& dst, State::Configuration& config) {
|
||||
static constexpr size_t T_SIZE = sizeof(T);
|
||||
|
||||
dst = *reinterpret_cast<const T*>(config.data_adr);
|
||||
config.processed(T_SIZE);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::Configuration& config, T& state) {
|
||||
config.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine);
|
||||
return process_routine(config, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__
|
||||
#define __JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__
|
||||
|
||||
#include <PSX/File/Processor/file_processor.hpp>
|
||||
|
||||
namespace JabyEngine {
|
||||
namespace FileProcessor {
|
||||
namespace Helper {
|
||||
template<typename T>
|
||||
static void simple_read(T& dst, State::Configuration& config) {
|
||||
static constexpr size_t T_SIZE = sizeof(T);
|
||||
|
||||
dst = *reinterpret_cast<const T*>(config.data_adr);
|
||||
config.processed(T_SIZE);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static Progress exchange_and_execute_process_function(State::GenericProcessRoutine<T> process_routine, State::Configuration& config, T& state) {
|
||||
config.process_routine = reinterpret_cast<State::ProcessRoutine>(process_routine);
|
||||
return process_routine(config, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !__JABYENGINE_INTERNAL_SIMPLE_HELPER_HPP__
|
|
@ -1,102 +1,102 @@
|
|||
#include "../../internal-include/GPU/gpu_internal.hpp"
|
||||
#include <PSX/Timer/frame_timer.hpp>
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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<uint16_t>((PublicDisplay::Height*PublicDisplay::current_id)))));
|
||||
return draw_area_y;
|
||||
}
|
||||
|
||||
void wait_vsync(uint8_t syncs) {
|
||||
volatile auto& vsync_count = reinterpret_cast<volatile uint8_t&>(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<uintptr_t>(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<uint16_t>(draw_offset_y), Display::Width, Display::Height));
|
||||
}
|
||||
return Display::current_id;
|
||||
}
|
||||
}
|
||||
#include "../../internal-include/GPU/gpu_internal.hpp"
|
||||
#include <PSX/Timer/frame_timer.hpp>
|
||||
#include <PSX/System/IOPorts/interrupt_io.hpp>
|
||||
#include <PSX/System/syscalls.hpp>
|
||||
|
||||
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<uint16_t>((PublicDisplay::Height*PublicDisplay::current_id)))));
|
||||
return draw_area_y;
|
||||
}
|
||||
|
||||
void wait_vsync(uint8_t syncs) {
|
||||
volatile auto& vsync_count = reinterpret_cast<volatile uint8_t&>(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<uintptr_t>(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<uint16_t>(draw_offset_y), Display::Width, Display::Height));
|
||||
}
|
||||
return Display::current_id;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue