From d9ab571e8bf5857d2a367084139b63f9e009e525 Mon Sep 17 00:00:00 2001 From: Jaby Date: Mon, 3 Jun 2024 21:58:32 +0200 Subject: [PATCH] Improve Interrupt Code --- include/PSX/System/syscalls.hpp | 22 ++-- src/Library/src/BootLoader/cd_boot.cpp | 4 +- src/Library/src/BootLoader/gpu_boot.cpp | 4 +- src/Library/src/BootLoader/timer_boot.cpp | 4 +- src/Library/src/CD/cd.cpp | 119 ++++++++++------------ src/Library/src/GPU/gpu.cpp | 26 ++--- src/Library/src/Timer/high_res_timer.cpp | 21 ++-- 7 files changed, 88 insertions(+), 112 deletions(-) diff --git a/include/PSX/System/syscalls.hpp b/include/PSX/System/syscalls.hpp index 92c64a29..46fb8436 100644 --- a/include/PSX/System/syscalls.hpp +++ b/include/PSX/System/syscalls.hpp @@ -121,11 +121,15 @@ namespace JabyEngine { using ThreadHandle = uint32_t; #pragma pack(push, 1) - struct InterrupCallback { - struct InterrupCallback* next; - InterruptHandler handler_function; - InterruptVerifier verifier_function; - uint32_t notUsed; + struct InterruptCallback { + struct InterruptCallback* next; + InterruptHandler handler_function; + InterruptVerifier verifier_function; + uint32_t notUsed; + + static constexpr InterruptCallback from_single_function(InterruptVerifier verifier) { + return InterruptCallback{nullptr, nullptr, verifier, 0}; + } }; #pragma pack(pop) @@ -186,18 +190,18 @@ namespace JabyEngine { __syscall_function_cast(Table_B, void(*)())(); } - static __always_inline int SysEnqIntRP(Priority prio, InterrupCallback* interElm) { + static __always_inline int SysEnqIntRP(Priority prio, InterruptCallback* 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); + return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm); } - static __always_inline int SysDeqIntRP(Priority prio, InterrupCallback *interElm) { + static __always_inline int SysDeqIntRP(Priority prio, InterruptCallback *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); + return __syscall_function_cast(Table_C, int(*)(Priority prio, InterruptCallback *interElm))(prio, interElm); } static __always_inline uint32_t EnterCriticalSection() { diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index 71d5f50e..b8accbd6 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -7,7 +7,7 @@ namespace JabyEngine { namespace CD { namespace internal { - extern SysCall::InterrupCallback callback; + extern SysCall::InterruptCallback irq_callback; } } @@ -25,7 +25,7 @@ namespace JabyEngine { 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); + SysCall::SysEnqIntRP(SysCall::Priority::CdromIoIrq, &::JabyEngine::CD::internal::irq_callback); CD_IO::PortIndex1::change_to(); CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index b0e5a406..65e41da8 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -20,7 +20,7 @@ extern "C" uint32_t __boot_loader_end; namespace JabyEngine { namespace GPU { namespace internal { - extern SysCall::InterrupCallback callback; + extern SysCall::InterruptCallback irq_callback; } namespace SJIS { @@ -100,7 +100,7 @@ namespace JabyEngine { 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); + SysCall::SysEnqIntRP(SysCall::Priority::VblankIrq, &::JabyEngine::GPU::internal::irq_callback); Interrupt::enable_irq(Interrupt::VBlank); SysCall::ExitCriticalSection(); } diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp index b5ab4e07..a8d833c3 100644 --- a/src/Library/src/BootLoader/timer_boot.cpp +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -4,7 +4,7 @@ namespace JabyEngine { namespace Timer { - extern SysCall::InterrupCallback IRQCallback; + extern SysCall::InterruptCallback irq_callback; } namespace boot { @@ -21,7 +21,7 @@ namespace JabyEngine { Interrupt::disable_irq(Interrupt::Timer2); SysCall::EnterCriticalSection(); - SysCall::SysEnqIntRP(SysCall::Priority::Timer2Irq, &IRQCallback); + SysCall::SysEnqIntRP(SysCall::Priority::Timer2Irq, &irq_callback); SysCall::ExitCriticalSection(); Counter2.set_target_value(HighResTime::TicksFor10ms); diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index ee678cda..901d54e0 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -32,19 +32,14 @@ namespace JabyEngine { namespace IRQ { static SysCall::InterruptVerifierResult verifier(); - static uint32_t handler(uint32_t); } static SectorBufferAllocator sector_allocator; static File cur_file; - uint8_t cmd_interrupt_bit = 0; - State current_state = State::Ready; - SysCall::InterrupCallback callback = { - .next = nullptr, - .handler_function = IRQ::handler, - .verifier_function = IRQ::verifier - }; + uint8_t cmd_interrupt_bit = 0; + State current_state = State::Ready; + auto irq_callback = SysCall::InterruptCallback::from_single_function(IRQ::verifier); static BCDTimeStamp send_read_cmd0(uint32_t lba, CD_IO::Command::Desc desc) { const auto loc = BCDTimeStamp::from(lba); @@ -102,68 +97,64 @@ namespace JabyEngine { static SysCall::InterruptVerifierResult verifier() { if(Interrupt::is_irq(Interrupt::CDROM)) { - return SysCall::InterruptVerifierResult::ExecuteHandler; + 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); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + CD_IO::PortIndex0::change_to(); + + cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); + + if(current_state != State::XAMode) { + 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_to0(sector->data, CD_IO::DataSector::SizeBytes); + + if(cur_file.done_processing()) { + current_state = State::Done; + pause(); + } + } + + else { + current_state = State::BufferFull; + pause(); + } + } break; + + case CD_IO::Interrupt::DataEnd: { + // TODO: Fix this!! This is a freaking static time + resume_at0(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0}); + Command::send(CD_IO::Command::Play); + } break; + + case CD_IO::Interrupt::DiskError: { + current_state = State::Error; + } break; + } + } + + else { + current_state = CDXA::interrupt_handler(cur_irq); + } + + // 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(); } else { return SysCall::InterruptVerifierResult::SkipHandler; } } - - static uint32_t 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); - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); - CD_IO::PortIndex0::change_to(); - - cmd_interrupt_bit = bit::clear(cmd_interrupt_bit, cur_irq); - - if(current_state != State::XAMode) { - 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_to0(sector->data, CD_IO::DataSector::SizeBytes); - - if(cur_file.done_processing()) { - current_state = State::Done; - pause(); - } - } - - else { - current_state = State::BufferFull; - pause(); - } - } break; - - case CD_IO::Interrupt::DataEnd: { - // TODO: Fix this!! This is a freaking static time - resume_at0(BCDTimeStamp{.min = 0x0, .sec = 0x09, .sector = 0x0}); - Command::send(CD_IO::Command::Play); - } break; - - case CD_IO::Interrupt::DiskError: { - current_state = State::Error; - } break; - } - } - - else { - current_state = CDXA::interrupt_handler(cur_irq); - } - - // 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) { diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 86579d29..2b2c634f 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -15,19 +15,19 @@ namespace JabyEngine { } 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 - }; + auto irq_callback = SysCall::InterruptCallback::from_single_function(interrupt_verifier); static SysCall::InterruptVerifierResult interrupt_verifier() { if(Interrupt::is_irq(Interrupt::VBlank)) { - return SysCall::InterruptVerifierResult::ExecuteHandler; + vsync_counter++; + MasterTime::value++; + + Interrupt::ack_irq(Interrupt::VBlank); + //Callback::internal::VSync::execute(); + SysCall::ReturnFromException(); + __builtin_unreachable(); } else { @@ -35,16 +35,6 @@ namespace JabyEngine { } } - static uint32_t interrupt_handler(uint32_t) { - vsync_counter++; - MasterTime::value++; - - Interrupt::ack_irq(Interrupt::VBlank); - //Callback::internal::VSync::execute(); - SysCall::ReturnFromException(); - __builtin_unreachable(); - } - uint32_t Display :: exchange_buffer_and_display() { static constexpr uint16_t TexturePageHeight = 256; diff --git a/src/Library/src/Timer/high_res_timer.cpp b/src/Library/src/Timer/high_res_timer.cpp index 8b81b63c..bf00ad40 100644 --- a/src/Library/src/Timer/high_res_timer.cpp +++ b/src/Library/src/Timer/high_res_timer.cpp @@ -8,26 +8,17 @@ namespace JabyEngine { namespace Timer { static SysCall::InterruptVerifierResult interrupt_verifier() { if(Interrupt::is_irq(Interrupt::Timer2)) { - return SysCall::InterruptVerifierResult::ExecuteHandler; + HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; + + Interrupt::ack_irq(Interrupt::Timer2); + SysCall::ReturnFromException(); + __builtin_unreachable(); } else { return SysCall::InterruptVerifierResult::SkipHandler; } } - - static uint32_t interrupt_handler(uint32_t) { - HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; - - Interrupt::ack_irq(Interrupt::Timer2); - SysCall::ReturnFromException(); - __builtin_unreachable(); - } - - SysCall::InterrupCallback IRQCallback = { - .next = nullptr, - .handler_function = interrupt_handler, - .verifier_function = interrupt_verifier - }; + auto irq_callback = SysCall::InterruptCallback::from_single_function(interrupt_verifier); } } \ No newline at end of file