From 0618aa1fb77e891d3632f8bacc20a4826a702a27 Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 9 May 2024 14:13:28 +0200 Subject: [PATCH 1/8] Support CDDA auto-repeat --- include/PSX/Audio/CDDA.hpp | 2 +- include/PSX/System/IOPorts/cd_io.hpp | 1 + src/Library/src/Audio/CDDA.cpp | 14 +++++--- src/Library/src/CD/cd.cpp | 52 ++++++++++++++++++---------- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/include/PSX/Audio/CDDA.hpp b/include/PSX/Audio/CDDA.hpp index bea2d1d6..acb6fc89 100644 --- a/include/PSX/Audio/CDDA.hpp +++ b/include/PSX/Audio/CDDA.hpp @@ -15,7 +15,7 @@ namespace JabyEngine { TrackList get_tracks(); void play(uint8_t track); - void pause(); + void stop(); void push_play(); void pop_play(); diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 8c1038bf..1ea6ecf0 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -160,6 +160,7 @@ namespace JabyEngine { static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge}; static constexpr Desc GetLocP{0x11, Interrupt::Type::Acknowledge}; static constexpr Desc GetTN{0x13, Interrupt::Type::Acknowledge}; + static constexpr Desc GetTD{0x14, Interrupt::Type::Acknowledge}; }; static constexpr auto IORegister1Adr = 0x1F801801; diff --git a/src/Library/src/Audio/CDDA.cpp b/src/Library/src/Audio/CDDA.cpp index 527e5ec4..8888ae88 100644 --- a/src/Library/src/Audio/CDDA.cpp +++ b/src/Library/src/Audio/CDDA.cpp @@ -1,11 +1,11 @@ #include "../../internal-include/CD/cd_internal.hpp" #include -#include namespace JabyEngine { namespace CDDA { namespace CD = JabyEngine::CD::internal; + static CD::CDTimeStamp playing_track; static CD::CDTimeStamp last_track; TrackList get_tracks() { @@ -28,16 +28,22 @@ namespace JabyEngine { void play(uint8_t track) { CD::enable_CDDA(); // < Command waits + + CD::Command::send_wait(CD_IO::Command::GetTD, track); + const auto stats = CD_IO::PortIndex0::ResponseFifo.read().raw; + playing_track.min = CD_IO::PortIndex0::ResponseFifo.read().raw; + playing_track.sec = CD_IO::PortIndex0::ResponseFifo.read().raw; + CD::Command::send(CD_IO::Command::Play, track); } - void pause() { + void stop() { CD::Command::wait_completed(); CD::Command::send(CD_IO::Command::Pause); } void push_play() { - pause(); + stop(); CD::Command::wait_completed(); CD::Command::send_wait(CD_IO::Command::GetLocP); @@ -53,8 +59,8 @@ namespace JabyEngine { void pop_play() { CD::Command::wait_completed(); - CD::Command::send_wait(CD_IO::Command::SetLoc, last_track.min, last_track.sec, last_track.sector); CD::enable_CDDA(); // < Command waits + CD::Command::send_wait(CD_IO::Command::SetLoc, last_track.min, last_track.sec, last_track.sector); CD::Command::send(CD_IO::Command::Play); } } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index df38ae1f..6205ca71 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -6,7 +6,7 @@ namespace JabyEngine { namespace CD { namespace internal { - static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::CDDA); + static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); static constexpr auto DataSectorMode = CD_IO::Mode::from(CD_IO::Mode::DoubleSpeed, CD_IO::Mode::DataSector); static SysCall::InterruptVerifierResult interrupt_verifier(); @@ -88,28 +88,42 @@ namespace JabyEngine { 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); + switch(cur_irq) { + case 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; + cur_lba++; + if(cur_lba == dst_lba) { + current_state = State::Done; + pause_cd(); + } + } + + else { + current_state = State::BufferFull; pause_cd(); } - } + } break; - else { - current_state = State::BufferFull; - pause_cd(); - } - } + case CD_IO::Interrupt::DataEnd: { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); - else if(cur_irq == CD_IO::Interrupt::DiskError) { - current_state = State::Error; + CD_IO::PortIndex1::change_to(); + while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Play); + } break; + + case CD_IO::Interrupt::DiskError: { + current_state = State::Error; + } break; } // No masking required because we can only write bit 0 - 2 @@ -141,7 +155,7 @@ namespace JabyEngine { void enable_CDDA() { Command::wait_completed(); CD_IO::PortIndex0::change_to(); - Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); + Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); } } } From afc594221ce0b0f4d8e8ef58d2c09f8974f09e9d Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 9 May 2024 19:31:28 +0200 Subject: [PATCH 2/8] Clean-up code a bit --- src/Library/internal-include/CD/cd_internal.hpp | 5 ++--- src/Library/src/CD/cd.cpp | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 79e9efcc..71ce373c 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -4,9 +4,8 @@ namespace JabyEngine { namespace CD { namespace internal { - extern State current_state; - extern CD_IO::Interrupt::Type last_interrupt; - extern uint8_t cmd_interrupt_bit; + extern State current_state; + extern uint8_t cmd_interrupt_bit; struct Command { static void wait_completed() { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 6205ca71..49e4874f 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -16,7 +16,6 @@ namespace JabyEngine { 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 = { @@ -84,7 +83,6 @@ namespace JabyEngine { 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); From 02ab2198d05b55dbce0783d2e005bdb50afe40d6 Mon Sep 17 00:00:00 2001 From: Jaby Date: Thu, 9 May 2024 23:15:04 +0200 Subject: [PATCH 3/8] Somehow works?! --- include/PSX/System/syscalls.hpp | 50 ++++++++++++ src/Library/src/CD/cd.cpp | 133 ++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index df0694a5..987b948b 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -45,6 +45,34 @@ namespace JabyEngine { extern const Version version; } + struct TCB { + uint32_t status; + uint32_t unused; + uint32_t reg[32]; + uint32_t epc; + uint32_t hi; + uint32_t lo; + uint32_t sr; + uint32_t cause; + uint32_t unused2[6]; + }; + + struct PCB { + TCB* current_tcb; + }; + + static __always_inline TCB* get_tcb_of_th(uint32_t id) { + return reinterpret_cast((*reinterpret_cast(0x110)) + (id*4)); + } + + static __always_inline void set_tcb(TCB* adr) { + reinterpret_cast(0x108)->current_tcb = adr; + } + + static __always_inline TCB& get_current_tcb() { + return *reinterpret_cast(0x108)->current_tcb; + } + namespace SysCall { static constexpr const uint32_t Table_A = 0xA0; static constexpr const uint32_t Table_B = 0xB0; @@ -92,6 +120,28 @@ namespace JabyEngine { return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); } + static __always_inline uint32_t OpenTh(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) { + register uint32_t FuncID asm("t1") = 0x0E; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(Table_B, uint32_t(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp); + } + + static __always_inline uint32_t ChangeTh(uint32_t thread) { + register uint32_t FuncID asm("t1") = 0x10; + __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); + + return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(thread); + } + + static __always_inline int changeThreadSubFunction(uint32_t address) { + register int n asm("a0") = 3; + register int tcb asm("a1") = address; + register int r asm("v0"); + __asm__ volatile("syscall\n" : "=r"(r) : "r"(n), "r"(tcb) : "memory"); + return r; +} + 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)); diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 49e4874f..ba41bf14 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -2,8 +2,96 @@ #include #include #include +#include +struct Registers { + union { + struct { + uint32_t r0, at, v0, v1, a0, a1, a2, a3; + uint32_t t0, t1, t2, t3, t4, t5, t6, t7; + uint32_t s0, s1, s2, s3, s4, s5, s6, s7; + uint32_t t8, t9, k0, k1, gp, sp, fp, ra; + } n; + uint32_t r[32]; + } GPR; + uint32_t returnPC; + uint32_t hi, lo; + uint32_t SR; + uint32_t Cause; +}; + +struct Thread { + uint32_t flags, flags2; + struct Registers registers; + uint32_t unknown[9]; +}; + +struct Process { + struct Thread* thread; +}; + +struct Globals { + /* 100 */ struct HandlersStorage* handlersArray; + /* 104 */ uint32_t handlersArraySize; + /* 108 */ struct Process* processes; + /* 10c */ uint32_t processBlockSize; + /* 110 */ struct Thread* threads; + /* 114 */ uint32_t threadBlockSize; + /* 118 */ uint32_t xxx_06; + /* 11c */ uint32_t xxx_07; + /* 120 */ struct EventInfo* events; + /* 124 */ uint32_t eventsSize; + /* 128 */ uint32_t xxx_0a; + /* 12c */ uint32_t xxx_0b; + /* 130 */ uint32_t xxx_0c; + /* 134 */ uint32_t xxx_0d; + /* 138 */ uint32_t xxx_0e; + /* 13c */ uint32_t xxx_0f; + /* 140 */ struct File* files; + /* 144 */ uint32_t filesSize; + /* 148 */ uint32_t xxx_12; + /* 14c */ uint32_t xxx_13; + /* 150 */ struct Device* devices; + /* 154 */ struct Device* devicesEnd; + /* 158 */ uint32_t xxx_16; + /* 15c */ uint32_t xxx_17; + /* 160 */ uint32_t xxx_18; + /* 164 */ uint32_t xxx_19; + /* 168 */ uint32_t xxx_1a; + /* 16c */ uint32_t xxx_1b; + /* 170 */ uint32_t xxx_1c; + /* 174 */ uint32_t xxx_1d; + /* 178 */ uint32_t xxx_1e; + /* 17c */ uint32_t xxx_1f; +}; + +Globals *__globals; namespace JabyEngine { + struct ToT { + unsigned long *head; + long size; +}; + +struct TCBH { + TCB *entry; /* NULL */ + long flag; +}; + +TCBH *exec_TCB; +TCB *mainFlow; + +inline unsigned short getSystemTableNumber(uint32_t thread) +{ + return (thread & 0xFFFF); +} + +inline TCB* getTCB(uint32_t thread) +{ + return (TCB*) (((ToT*)0x100)[2]).head + getSystemTableNumber(thread); +} + +int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32_t)&__globals->threads[threadId & 0xffff]); } + namespace CD { namespace internal { static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); @@ -12,6 +100,9 @@ namespace JabyEngine { static SysCall::InterruptVerifierResult interrupt_verifier(); static uint32_t interrupt_handler(uint32_t); + static uint32_t stack[1024]; + static uint32_t thread = 0; + static SectorBufferAllocator sector_allocator; static uint32_t cur_lba; static uint32_t dst_lba; @@ -108,6 +199,17 @@ namespace JabyEngine { } break; case CD_IO::Interrupt::DataEnd: { + + //set_tcb(get_tcb_of_th(thread)); + + /*printf("EPC: 0x%p; SR: 0x%p\n", get_current_tcb().reg[31], get_current_tcb().sr); + get_current_tcb().reg[31] = (uint32_t)(void(*)())[]() { + printf("Wuff! Now crash!\n"); + while(true); + }; + printf("EPC: 0x%p; SR: 0x%p\n", get_current_tcb().reg[31], get_current_tcb().sr); while(true);*/ + //SysCall::ReturnFromException(); + CD_IO::PortIndex0::change_to(); Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); @@ -127,6 +229,11 @@ namespace JabyEngine { // No masking required because we can only write bit 0 - 2 CD_IO::IndexStatus.write(old_status); Interrupt::ack_irq(Interrupt::CDROM); + + if(thread != 0) { + //changeThread(thread); + exec_TCB->entry = reinterpret_cast(&__globals->threads[thread & 0xffff]); + } SysCall::ReturnFromException(); __builtin_unreachable(); } @@ -150,7 +257,33 @@ namespace JabyEngine { } } + + void enable_CDDA() { + if(thread == 0) { + __globals = reinterpret_cast(0x100); + ToT *table = (ToT*)0x100; + exec_TCB = (TCBH*)table[1].head; + mainFlow = exec_TCB->entry; + + SysCall::EnterCriticalSection(); + thread = SysCall::OpenTh([]() { + printf("Hallo!\n"); + printf("Me: 0x%p - 0x%p\n", get_tcb_of_th(thread), &get_current_tcb()); + + exec_TCB->entry = mainFlow; + SysCall::ReturnFromException(); + //changeThread(0); + }, reinterpret_cast(0x80010000), reinterpret_cast(mainFlow->reg[28])); + SysCall::ExitCriticalSection(); + + printf("Raw: %x, TCB: %i\n", thread, thread & 0xFFFF); + //__globals->threads[thread & 0xffff].registers.SR = 0x404; + + //mainFlow = exec_TCB->entry; + //changeThread(thread); + } + Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); From acd4402c566d8601999d038cc389846da32870fc Mon Sep 17 00:00:00 2001 From: Jaby Date: Sun, 12 May 2024 13:45:45 +0200 Subject: [PATCH 4/8] Make music loop --- src/Library/src/CD/cd.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index ba41bf14..6d7792b0 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -210,15 +210,12 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 printf("EPC: 0x%p; SR: 0x%p\n", get_current_tcb().reg[31], get_current_tcb().sr); while(true);*/ //SysCall::ReturnFromException(); - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); - - CD_IO::PortIndex1::change_to(); - while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); - - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Play); + if(thread != 0) { + //changeThread(thread); + printf("About to change...\n"); + exec_TCB->entry = reinterpret_cast(&__globals->threads[thread & 0xffff]); + printf("Changed!\n"); + } } break; case CD_IO::Interrupt::DiskError: { @@ -229,11 +226,8 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 // No masking required because we can only write bit 0 - 2 CD_IO::IndexStatus.write(old_status); Interrupt::ack_irq(Interrupt::CDROM); - - if(thread != 0) { - //changeThread(thread); - exec_TCB->entry = reinterpret_cast(&__globals->threads[thread & 0xffff]); - } + Interrupt::enable_irq(Interrupt::CDROM); + printf("RET-E\n"); SysCall::ReturnFromException(); __builtin_unreachable(); } @@ -257,8 +251,6 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 } } - - void enable_CDDA() { if(thread == 0) { __globals = reinterpret_cast(0x100); @@ -271,6 +263,14 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 printf("Hallo!\n"); printf("Me: 0x%p - 0x%p\n", get_tcb_of_th(thread), &get_current_tcb()); + printf("Blubb!\n"); + CD_IO::PortIndex0::change_to(); + printf("Schwupp!\n"); + Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); + printf("Mupp\n"); + Command::send(CD_IO::Command::Play); + printf("Done!!\n"); + exec_TCB->entry = mainFlow; SysCall::ReturnFromException(); //changeThread(0); From b0a552249d9f414efd05f291872f70d25440f328 Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 13 May 2024 21:46:42 +0200 Subject: [PATCH 5/8] Use original code instead of frankensteining --- include/PSX/System/syscalls.hpp | 43 +++++++++--- mkfile/psexe.ld | 12 +++- src/Library/src/CD/cd.cpp | 112 +------------------------------- 3 files changed, 45 insertions(+), 122 deletions(-) diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index 987b948b..6dd5d74e 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -54,24 +54,41 @@ namespace JabyEngine { uint32_t lo; uint32_t sr; uint32_t cause; - uint32_t unused2[6]; + uint32_t unused2[9]; }; struct PCB { TCB* current_tcb; }; - static __always_inline TCB* get_tcb_of_th(uint32_t id) { - return reinterpret_cast((*reinterpret_cast(0x110)) + (id*4)); - } + struct ToT { + using ExCB = void; + using EvCB = void; + using FCB = void; - static __always_inline void set_tcb(TCB* adr) { - reinterpret_cast(0x108)->current_tcb = adr; - } + ExCB* exception_chain; + uint32_t exception_chain_size; + PCB* processes; + uint32_t processes_size; + TCB* threads; + uint32_t threads_size; + uint32_t reserved_0; + uint32_t reserved_1; + EvCB* events; + uint32_t events_size; + uint32_t reserved_2; + uint32_t reserved_3; + uint32_t reserved_4; + uint32_t reserved_5; + uint32_t reserved_6; + uint32_t reserved_7; + FCB* files; + uint32_t files_size; + uint32_t reserved_8; + uint32_t reserved_9; + }; - static __always_inline TCB& get_current_tcb() { - return *reinterpret_cast(0x108)->current_tcb; - } + extern ToT table_of_tables; namespace SysCall { static constexpr const uint32_t Table_A = 0xA0; @@ -113,6 +130,12 @@ namespace JabyEngine { #define __syscall_function_cast(table, ...) reinterpret_cast<__VA_ARGS__>(table) + static __always_inline uint32_t* get_gp() { + uint32_t* gp; + __asm__("sw $gp, %0" : "=m"(gp)); + return gp; + } + 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)); diff --git a/mkfile/psexe.ld b/mkfile/psexe.ld index cde05fcb..d1fef6ec 100644 --- a/mkfile/psexe.ld +++ b/mkfile/psexe.ld @@ -31,10 +31,11 @@ ENTRY(_ZN10JabyEngine5startEv) TLOAD_ADDR = DEFINED(TLOAD_ADDR) ? TLOAD_ADDR : 0x80010000; MEMORY { + bios : ORIGIN = 0x100, LENGTH = 0x500 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(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); @@ -50,7 +51,12 @@ __persistent_lbas_len = (__persistent_lbas_end - __persistent_lbas_start); __stack_start = ORIGIN(ram) + LENGTH(ram); + SECTIONS { + .bios (NOLOAD) : { + _ZN10JabyEngine15table_of_tablesE = .; + } > bios + /DISCARD/ : { *(.MIPS.abiflags) } /* Everything is statically linked, so discard PLTs. */ diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 6d7792b0..7d557d51 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -3,95 +3,8 @@ #include #include #include -struct Registers { - union { - struct { - uint32_t r0, at, v0, v1, a0, a1, a2, a3; - uint32_t t0, t1, t2, t3, t4, t5, t6, t7; - uint32_t s0, s1, s2, s3, s4, s5, s6, s7; - uint32_t t8, t9, k0, k1, gp, sp, fp, ra; - } n; - uint32_t r[32]; - } GPR; - uint32_t returnPC; - uint32_t hi, lo; - uint32_t SR; - uint32_t Cause; -}; - -struct Thread { - uint32_t flags, flags2; - struct Registers registers; - uint32_t unknown[9]; -}; - -struct Process { - struct Thread* thread; -}; - -struct Globals { - /* 100 */ struct HandlersStorage* handlersArray; - /* 104 */ uint32_t handlersArraySize; - /* 108 */ struct Process* processes; - /* 10c */ uint32_t processBlockSize; - /* 110 */ struct Thread* threads; - /* 114 */ uint32_t threadBlockSize; - /* 118 */ uint32_t xxx_06; - /* 11c */ uint32_t xxx_07; - /* 120 */ struct EventInfo* events; - /* 124 */ uint32_t eventsSize; - /* 128 */ uint32_t xxx_0a; - /* 12c */ uint32_t xxx_0b; - /* 130 */ uint32_t xxx_0c; - /* 134 */ uint32_t xxx_0d; - /* 138 */ uint32_t xxx_0e; - /* 13c */ uint32_t xxx_0f; - /* 140 */ struct File* files; - /* 144 */ uint32_t filesSize; - /* 148 */ uint32_t xxx_12; - /* 14c */ uint32_t xxx_13; - /* 150 */ struct Device* devices; - /* 154 */ struct Device* devicesEnd; - /* 158 */ uint32_t xxx_16; - /* 15c */ uint32_t xxx_17; - /* 160 */ uint32_t xxx_18; - /* 164 */ uint32_t xxx_19; - /* 168 */ uint32_t xxx_1a; - /* 16c */ uint32_t xxx_1b; - /* 170 */ uint32_t xxx_1c; - /* 174 */ uint32_t xxx_1d; - /* 178 */ uint32_t xxx_1e; - /* 17c */ uint32_t xxx_1f; -}; - -Globals *__globals; namespace JabyEngine { - struct ToT { - unsigned long *head; - long size; -}; - -struct TCBH { - TCB *entry; /* NULL */ - long flag; -}; - -TCBH *exec_TCB; -TCB *mainFlow; - -inline unsigned short getSystemTableNumber(uint32_t thread) -{ - return (thread & 0xFFFF); -} - -inline TCB* getTCB(uint32_t thread) -{ - return (TCB*) (((ToT*)0x100)[2]).head + getSystemTableNumber(thread); -} - -int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32_t)&__globals->threads[threadId & 0xffff]); } - namespace CD { namespace internal { static constexpr auto AudioSectorMode = CD_IO::Mode::from(CD_IO::Mode::SingleSpeed, CD_IO::Mode::AutoPauseTrack, CD_IO::Mode::CDDA); @@ -213,7 +126,7 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 if(thread != 0) { //changeThread(thread); printf("About to change...\n"); - exec_TCB->entry = reinterpret_cast(&__globals->threads[thread & 0xffff]); + table_of_tables.processes->current_tcb = &table_of_tables.threads[thread&0xFFFF]; printf("Changed!\n"); } } break; @@ -226,8 +139,6 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 // No masking required because we can only write bit 0 - 2 CD_IO::IndexStatus.write(old_status); Interrupt::ack_irq(Interrupt::CDROM); - Interrupt::enable_irq(Interrupt::CDROM); - printf("RET-E\n"); SysCall::ReturnFromException(); __builtin_unreachable(); } @@ -253,35 +164,18 @@ int changeThread(int threadId) { return SysCall::changeThreadSubFunction((uint32 void enable_CDDA() { if(thread == 0) { - __globals = reinterpret_cast(0x100); - ToT *table = (ToT*)0x100; - exec_TCB = (TCBH*)table[1].head; - mainFlow = exec_TCB->entry; - SysCall::EnterCriticalSection(); thread = SysCall::OpenTh([]() { printf("Hallo!\n"); - printf("Me: 0x%p - 0x%p\n", get_tcb_of_th(thread), &get_current_tcb()); - printf("Blubb!\n"); CD_IO::PortIndex0::change_to(); - printf("Schwupp!\n"); Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); - printf("Mupp\n"); Command::send(CD_IO::Command::Play); - printf("Done!!\n"); - exec_TCB->entry = mainFlow; + table_of_tables.processes->current_tcb = &table_of_tables.threads[0]; SysCall::ReturnFromException(); - //changeThread(0); - }, reinterpret_cast(0x80010000), reinterpret_cast(mainFlow->reg[28])); + }, reinterpret_cast(0x80010000), SysCall::get_gp()); SysCall::ExitCriticalSection(); - - printf("Raw: %x, TCB: %i\n", thread, thread & 0xFFFF); - //__globals->threads[thread & 0xffff].registers.SR = 0x404; - - //mainFlow = exec_TCB->entry; - //changeThread(thread); } Command::wait_completed(); From 5f450709617d2191ee90548299d15dd449435b3e Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 13 May 2024 22:29:23 +0200 Subject: [PATCH 6/8] Unlock user mode in callback (buggy in XEBRA?) --- src/Library/src/CD/cd.cpp | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 7d557d51..e1674654 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -112,18 +112,7 @@ namespace JabyEngine { } break; case CD_IO::Interrupt::DataEnd: { - - //set_tcb(get_tcb_of_th(thread)); - - /*printf("EPC: 0x%p; SR: 0x%p\n", get_current_tcb().reg[31], get_current_tcb().sr); - get_current_tcb().reg[31] = (uint32_t)(void(*)())[]() { - printf("Wuff! Now crash!\n"); - while(true); - }; - printf("EPC: 0x%p; SR: 0x%p\n", get_current_tcb().reg[31], get_current_tcb().sr); while(true);*/ - //SysCall::ReturnFromException(); - - if(thread != 0) { + if(thread != 0 && table_of_tables.processes->current_tcb == &table_of_tables.threads[0]) { //changeThread(thread); printf("About to change...\n"); table_of_tables.processes->current_tcb = &table_of_tables.threads[thread&0xFFFF]; @@ -169,13 +158,18 @@ namespace JabyEngine { printf("Hallo!\n"); CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); + printf("Wait...\n"); + Command::send_wait(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); + printf("Done!\n"); Command::send(CD_IO::Command::Play); table_of_tables.processes->current_tcb = &table_of_tables.threads[0]; SysCall::ReturnFromException(); - }, reinterpret_cast(0x80010000), SysCall::get_gp()); + }, &stack[1023], SysCall::get_gp()); SysCall::ExitCriticalSection(); + + table_of_tables.threads[thread&0xFFFF].sr = table_of_tables.threads[0].sr; + printf(">>> 0x%X\n", table_of_tables.threads[0].sr); } Command::wait_completed(); From 9ec82eba029f635bd0280fc469a16ac1083e972a Mon Sep 17 00:00:00 2001 From: Jaby Date: Wed, 15 May 2024 19:48:55 +0200 Subject: [PATCH 7/8] Fix casing for 'Support' folder --- examples/PoolBox/PoolBox.code-workspace | 2 +- examples/PoolBox/application/Makefile | 2 +- mkfile/PSEXETarget.mk | 2 +- support/src/Makefile | 2 +- template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace | 2 +- template/JabyEngine-PSX_Game/application/Makefile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/PoolBox/PoolBox.code-workspace b/examples/PoolBox/PoolBox.code-workspace index 2939de43..540f55ec 100644 --- a/examples/PoolBox/PoolBox.code-workspace +++ b/examples/PoolBox/PoolBox.code-workspace @@ -93,7 +93,7 @@ "settings": { "C_Cpp.default.includePath": [ "${env:JABY_ENGINE_PATH}/include", - "${env:JABY_ENGINE_PATH}/Support/include" + "${env:JABY_ENGINE_PATH}/support/include" ], "C_Cpp.default.compilerPath": "", "C_Cpp.default.cStandard": "c17", diff --git a/examples/PoolBox/application/Makefile b/examples/PoolBox/application/Makefile index 4ad6e032..cd3f4824 100644 --- a/examples/PoolBox/application/Makefile +++ b/examples/PoolBox/application/Makefile @@ -3,7 +3,7 @@ OVERLAY_CONFIG = Overlays.json include $(JABY_ENGINE_DIR)/mkfile/common/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) -INCLUDES += -I$(JABY_ENGINE_DIR)/Support/include -I$(JABY_ENGINE_DIR)/include +INCLUDES += -I$(JABY_ENGINE_DIR)/support/include -I$(JABY_ENGINE_DIR)/include CCFLAGS += -save-temps=obj SUPPORT_LIBS += FontWriter diff --git a/mkfile/PSEXETarget.mk b/mkfile/PSEXETarget.mk index 85632fa6..ac315988 100644 --- a/mkfile/PSEXETarget.mk +++ b/mkfile/PSEXETarget.mk @@ -5,7 +5,7 @@ include $(AUTO_OVERLAY_DIR)/Overlays.mk include $(JABY_ENGINE_DIR)/mkfile/common/CustomConfigHelper.mk JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE)/$(CUSTOM_CONFIG) -JABY_ENGINE_SUPPORT_LIB_DIR = $(JABY_ENGINE_DIR)/Support/lib/PSX-$(BUILD_PROFILE) +JABY_ENGINE_SUPPORT_LIB_DIR = $(JABY_ENGINE_DIR)/support/lib/PSX-$(BUILD_PROFILE) JABY_ENGINE_SUPPORT_LIBS = $(addprefix -l,$(SUPPORT_LIBS)) JABY_ENGINE_SUPPORT_DEPS = $(addsuffix .a,$(addprefix $(JABY_ENGINE_SUPPORT_LIB_DIR)/lib,$(SUPPORT_LIBS))) JABY_ENGINE_LIB_NAME = JabyEngine_$(PSX_TV_FORMAT) diff --git a/support/src/Makefile b/support/src/Makefile index c5efff53..923279d5 100644 --- a/support/src/Makefile +++ b/support/src/Makefile @@ -1,5 +1,5 @@ FontWriter: always - $(MAKE) -C $(JABY_ENGINE_DIR)/Support/src/FontWriter $(MAKECMDGOALS) + $(MAKE) -C $(JABY_ENGINE_DIR)/support/src/FontWriter $(MAKECMDGOALS) all: FontWriter diff --git a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace index 866a6c77..4e1124dc 100644 --- a/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace +++ b/template/JabyEngine-PSX_Game/#{ProjectName}.code-workspace @@ -93,7 +93,7 @@ "settings": { "C_Cpp.default.includePath": [ "${env:JABY_ENGINE_PATH}/include", - "${env:JABY_ENGINE_PATH}/Support/include" + "${env:JABY_ENGINE_PATH}/support/include" ], "C_Cpp.default.compilerPath": "", "C_Cpp.default.cStandard": "c17", diff --git a/template/JabyEngine-PSX_Game/application/Makefile b/template/JabyEngine-PSX_Game/application/Makefile index 6432cda9..2de33a7b 100644 --- a/template/JabyEngine-PSX_Game/application/Makefile +++ b/template/JabyEngine-PSX_Game/application/Makefile @@ -4,7 +4,7 @@ include $(JABY_ENGINE_DIR)/mkfile/common/Wildcard.mk SRCS = $(call rwildcard, src, c cpp) INCLUDES += -I$(JABY_ENGINE_DIR)/include -#INCLUDES += -I$(JABY_ENGINE_DIR)/Support/include +#INCLUDES += -I$(JABY_ENGINE_DIR)/support/include #Example for using Support libs #SUPPORT_LIBS += FontWriter From 4dab38239f64f2cb6567164564f7a49253cc7a6a Mon Sep 17 00:00:00 2001 From: Jaby Date: Wed, 15 May 2024 21:43:12 +0200 Subject: [PATCH 8/8] Support VSync callback --- .../PoolBox/application/src/application.cpp | 6 +++ include/PSX/System/callbacks.hpp | 20 +++++++++ include/PSX/System/syscalls.hpp | 20 ++------- include/PSX/System/threads.hpp | 43 +++++++++++++++++++ .../BootLoader/boot_loader.hpp | 4 ++ .../System/callbacks_internal.hpp | 21 +++++++++ src/Library/src/BootLoader/callbacks_boot.cpp | 21 +++++++++ src/Library/src/BootLoader/start_boot.cpp | 2 +- src/Library/src/CD/cd.cpp | 38 ++++------------ src/Library/src/GPU/gpu.cpp | 4 +- src/Library/src/System/callbacks.cpp | 26 +++++++++++ 11 files changed, 156 insertions(+), 49 deletions(-) create mode 100644 include/PSX/System/callbacks.hpp create mode 100644 include/PSX/System/threads.hpp create mode 100644 src/Library/internal-include/System/callbacks_internal.hpp create mode 100644 src/Library/src/BootLoader/callbacks_boot.cpp create mode 100644 src/Library/src/System/callbacks.cpp diff --git a/examples/PoolBox/application/src/application.cpp b/examples/PoolBox/application/src/application.cpp index e2ff39e6..902ca15e 100644 --- a/examples/PoolBox/application/src/application.cpp +++ b/examples/PoolBox/application/src/application.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include using namespace JabyEngine; @@ -155,6 +156,10 @@ namespace LoadingScene { static void run() { if(old_state_changer != state_changer) { printf("Loading new state...\n"); + + Callback::VSyncCallback::install([]() { + printf("Still loading...\n"); + }); update(); GPU::swap_buffers_vsync(1); @@ -165,6 +170,7 @@ namespace LoadingScene { state_changer.asset_load(); old_state_changer = state_changer; CDDA::pop_play(); + Callback::VSyncCallback::uninstall(); } state_changer.main(); diff --git a/include/PSX/System/callbacks.hpp b/include/PSX/System/callbacks.hpp new file mode 100644 index 00000000..ae6e950c --- /dev/null +++ b/include/PSX/System/callbacks.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "syscalls.hpp" + +namespace JabyEngine { + namespace Callback { + struct VSyncCallback { + using Function = void (*)(); + + static Function callback; + + static void install(Function function) { + VSyncCallback::callback = function; + } + + static void uninstall() { + VSyncCallback::install(nullptr); + } + }; + } +} \ No newline at end of file diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index 6dd5d74e..92c64a29 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -118,6 +118,7 @@ namespace JabyEngine { typedef InterruptVerifierResult (*InterruptVerifier)(); typedef uint32_t (*InterruptHandler)(uint32_t); + using ThreadHandle = uint32_t; #pragma pack(push, 1) struct InterrupCallback { @@ -143,28 +144,13 @@ namespace JabyEngine { return __syscall_function_cast(Table_A, void*(*)(void*, const void*, size_t))(dst, src, len); } - static __always_inline uint32_t OpenTh(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) { + static __always_inline ThreadHandle OpenThread(void (*thread_func)(), uint32_t* stack_ptr, uint32_t* gp) { register uint32_t FuncID asm("t1") = 0x0E; __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - return __syscall_function_cast(Table_B, uint32_t(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp); + return __syscall_function_cast(Table_B, ThreadHandle(*)(void(*)(), uint32_t*, uint32_t*))(thread_func, stack_ptr, gp); } - static __always_inline uint32_t ChangeTh(uint32_t thread) { - register uint32_t FuncID asm("t1") = 0x10; - __asm__ volatile("" : "=r"(FuncID) : "r"(FuncID)); - - return __syscall_function_cast(Table_B, uint32_t(*)(uint32_t))(thread); - } - - static __always_inline int changeThreadSubFunction(uint32_t address) { - register int n asm("a0") = 3; - register int tcb asm("a1") = address; - register int r asm("v0"); - __asm__ volatile("syscall\n" : "=r"(r) : "r"(n), "r"(tcb) : "memory"); - return r; -} - 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)); diff --git a/include/PSX/System/threads.hpp b/include/PSX/System/threads.hpp new file mode 100644 index 00000000..1ee97422 --- /dev/null +++ b/include/PSX/System/threads.hpp @@ -0,0 +1,43 @@ +#pragma once +#include "syscalls.hpp" + +namespace JabyEngine { + struct Thread { + static constexpr uint32_t idx_from_handle(SysCall::ThreadHandle thread) { + return thread & 0xFFFF; + } + + static void prepare_next(SysCall::ThreadHandle thread) { + table_of_tables.processes->current_tcb = &table_of_tables.threads[idx_from_handle(thread)]; + } + + static void execute_next() { + SysCall::ReturnFromException(); + } + + static void set_kernel_mode_for(SysCall::ThreadHandle handle) { + table_of_tables.threads[idx_from_handle(handle)].sr = 0x0; + } + + static void set_user_mode_for(SysCall::ThreadHandle handle) { + table_of_tables.threads[idx_from_handle(handle)].sr = 0x40000404; + } + }; + + struct MainThread { + static void prepare_if_main(SysCall::ThreadHandle handle) { + if(table_of_tables.processes->current_tcb == &table_of_tables.threads[0]) { + Thread::prepare_next(handle); + } + } + + static void prepare_restore() { + Thread::prepare_next(0); + } + + static void restore() { + MainThread::prepare_restore(); + Thread::execute_next(); + } + }; +} \ No newline at end of file diff --git a/src/Library/internal-include/BootLoader/boot_loader.hpp b/src/Library/internal-include/BootLoader/boot_loader.hpp index 38b3ac0f..49b5a6ea 100644 --- a/src/Library/internal-include/BootLoader/boot_loader.hpp +++ b/src/Library/internal-include/BootLoader/boot_loader.hpp @@ -8,6 +8,10 @@ namespace JabyEngine { void identify(); } + namespace Callbacks { + void setup(); + } + namespace CD { void setup(); } diff --git a/src/Library/internal-include/System/callbacks_internal.hpp b/src/Library/internal-include/System/callbacks_internal.hpp new file mode 100644 index 00000000..6664e202 --- /dev/null +++ b/src/Library/internal-include/System/callbacks_internal.hpp @@ -0,0 +1,21 @@ +#pragma once +#include + +namespace JabyEngine { + namespace Callback { + namespace internal { + namespace VSync { + static constexpr size_t StackSize = 64; + + extern SysCall::ThreadHandle thread_handle; + extern uint32_t stack[StackSize]; + void routine(); + + static void execute() { + MainThread::prepare_if_main(VSync::thread_handle); + Thread::execute_next(); + } + } + } + } +} diff --git a/src/Library/src/BootLoader/callbacks_boot.cpp b/src/Library/src/BootLoader/callbacks_boot.cpp new file mode 100644 index 00000000..7c5fb44b --- /dev/null +++ b/src/Library/src/BootLoader/callbacks_boot.cpp @@ -0,0 +1,21 @@ +#include "../../internal-include/BootLoader/boot_loader.hpp" +#include "../../internal-include/System/callbacks_internal.hpp" + +namespace JabyEngine { + namespace boot { + namespace Callbacks { + namespace InternalCallback = JabyEngine::Callback::internal; + + void setup() { + SysCall::EnterCriticalSection(); + InternalCallback::VSync::thread_handle = SysCall::OpenThread( + InternalCallback::VSync::routine, + &InternalCallback::VSync::stack[InternalCallback::VSync::StackSize - 1], + SysCall::get_gp() + ); + Thread::set_user_mode_for(InternalCallback::VSync::thread_handle); + SysCall::ExitCriticalSection(); + } + } + } +} \ No newline at end of file diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index c97c659e..4c85bae2 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -47,6 +47,7 @@ namespace JabyEngine { static constexpr auto DebugScale = 1.0; BIOS::identify(); + Callbacks::setup(); __debug_boot_color_at(::JabyEngine::GPU::Color24::Grey(), DebugX, DebugY, DebugScale); DMA::setup(); @@ -69,7 +70,6 @@ namespace JabyEngine { test_bios_font(); test_gte_scale(); - //Pause?? SPU::setup(); } } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index e1674654..39d3f992 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -13,9 +13,6 @@ namespace JabyEngine { static SysCall::InterruptVerifierResult interrupt_verifier(); static uint32_t interrupt_handler(uint32_t); - static uint32_t stack[1024]; - static uint32_t thread = 0; - static SectorBufferAllocator sector_allocator; static uint32_t cur_lba; static uint32_t dst_lba; @@ -112,12 +109,15 @@ namespace JabyEngine { } break; case CD_IO::Interrupt::DataEnd: { - if(thread != 0 && table_of_tables.processes->current_tcb == &table_of_tables.threads[0]) { - //changeThread(thread); - printf("About to change...\n"); - table_of_tables.processes->current_tcb = &table_of_tables.threads[thread&0xFFFF]; - printf("Changed!\n"); - } + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); + + CD_IO::PortIndex1::change_to(); + while(CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag) != CD_IO::Interrupt::Acknowledge); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Play); } break; case CD_IO::Interrupt::DiskError: { @@ -152,26 +152,6 @@ namespace JabyEngine { } void enable_CDDA() { - if(thread == 0) { - SysCall::EnterCriticalSection(); - thread = SysCall::OpenTh([]() { - printf("Hallo!\n"); - - CD_IO::PortIndex0::change_to(); - printf("Wait...\n"); - Command::send_wait(CD_IO::Command::SetLoc, static_cast(0x0), static_cast(0x09), static_cast(0x0)); - printf("Done!\n"); - Command::send(CD_IO::Command::Play); - - table_of_tables.processes->current_tcb = &table_of_tables.threads[0]; - SysCall::ReturnFromException(); - }, &stack[1023], SysCall::get_gp()); - SysCall::ExitCriticalSection(); - - table_of_tables.threads[thread&0xFFFF].sr = table_of_tables.threads[0].sr; - printf(">>> 0x%X\n", table_of_tables.threads[0].sr); - } - Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, AudioSectorMode); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index bd692544..e84edb7e 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,4 +1,5 @@ #include "../../internal-include/GPU/gpu_internal.hpp" +#include "../../internal-include/System/callbacks_internal.hpp" #include #include #include @@ -40,8 +41,7 @@ namespace JabyEngine { MasterTime::value++; Interrupt::ack_irq(Interrupt::VBlank); - SysCall::ReturnFromException(); - __builtin_unreachable(); + Callback::internal::VSync::execute(); } uint32_t Display :: exchange_buffer_and_display() { diff --git a/src/Library/src/System/callbacks.cpp b/src/Library/src/System/callbacks.cpp new file mode 100644 index 00000000..d71da9b5 --- /dev/null +++ b/src/Library/src/System/callbacks.cpp @@ -0,0 +1,26 @@ +#include "../../internal-include/System/callbacks_internal.hpp" +#include + +#include + +namespace JabyEngine { + namespace Callback { + VSyncCallback::Function VSyncCallback :: callback = nullptr; + + namespace internal { + namespace VSync { + SysCall::ThreadHandle thread_handle = 0; + uint32_t stack[StackSize] = {0}; + + void routine() { + while(true) { + if(VSyncCallback::callback) { + VSyncCallback::callback(); + } + MainThread::restore(); + } + } + } + } + } +} \ No newline at end of file