From da5b10c8d90732b48a44661638881b956ef54044 Mon Sep 17 00:00:00 2001 From: Jaby Date: Wed, 26 Apr 2023 19:09:07 +0200 Subject: [PATCH] Add busy loop code and make HighResTimer work on demand rather automatically or ifdefed --- include/PSX/Timer/high_res_timer.hpp | 87 ++++++++++++----------- include/PSX/jabyengine_config.hpp | 8 --- include/PSX/jabyengine_defines.h | 1 - lib/Makefile | 10 +-- src/Library/Makefile | 3 +- src/Library/src/BootLoader/start_boot.cpp | 5 -- src/Library/src/BootLoader/timer_boot.cpp | 62 +++++++--------- src/Library/src/Timer/high_res_timer.cpp | 60 ++++++++-------- src/Library/src/busyloop.s | 26 +++++++ src/Library/src/syscall_printf.s | 2 +- 10 files changed, 131 insertions(+), 133 deletions(-) delete mode 100644 include/PSX/jabyengine_config.hpp create mode 100644 src/Library/src/busyloop.s diff --git a/include/PSX/Timer/high_res_timer.hpp b/include/PSX/Timer/high_res_timer.hpp index 9ae8141d..1621838f 100644 --- a/include/PSX/Timer/high_res_timer.hpp +++ b/include/PSX/Timer/high_res_timer.hpp @@ -1,6 +1,7 @@ #ifndef __JABYENGINE_HIGH_RES_TIMER_HPP__ #define __JABYENGINE_HIGH_RES_TIMER_HPP__ #include "../jabyengine_defines.h" +#include #include namespace JabyEngine { @@ -24,51 +25,57 @@ namespace JabyEngine { } }; - #ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - class HighResTime { - public: - class TimeStamp { - private: - uint16_t counter_10ms_value; - uint16_t fraction; - - constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) { - } - - constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) { - return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); - } - - constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { - return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); - } - - public: - constexpr size_t microseconds_to(const TimeStamp& end) const { - return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); - } - - constexpr size_t milliseconds_to(const TimeStamp& end) const { - return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); - } - friend class HighResTime; - }; - + class HighResTime { + public: + class TimeStamp { private: - static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us(CPUTicks::Frequency_Hz_Div8, 100.0); - static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 1.0); - static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 10.0); + uint16_t counter_10ms_value; + uint16_t fraction; - static volatile uint16_t global_counter_10ms; + constexpr TimeStamp(uint16_t counter_10ms_value, uint16_t fraction) : counter_10ms_value(counter_10ms_value), fraction(fraction) { + } + + constexpr static size_t to_us(uint16_t counter_10ms_value, uint16_t fraction) { + return counter_10ms_value*(10*1000) + ((fraction/HighResTime::TicksFor100us)*100); + } + + constexpr static size_t to_ms(uint16_t counter_10ms_value, uint16_t fraction) { + return counter_10ms_value*10 + (fraction/HighResTime::TicksFor1ms); + } public: - HighResTime() = delete; - ~HighResTime() = delete; - - static TimeStamp get_time_stamp() { - return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); + constexpr size_t microseconds_to(const TimeStamp& end) const { + return TimeStamp::to_us((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); } + + constexpr size_t milliseconds_to(const TimeStamp& end) const { + return TimeStamp::to_ms((end.counter_10ms_value - this->counter_10ms_value), (end.fraction - this->fraction)); + } + friend class HighResTime; }; - #endif //JABYENGINE_USE_HIGH_PERCISION_TIMER + + private: + static constexpr uint16_t TicksFor100us = CPUTicks::ticks_per_us(CPUTicks::Frequency_Hz_Div8, 100.0); + static constexpr uint16_t TicksFor1ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 1.0); + static constexpr uint16_t TicksFor10ms = CPUTicks::ticks_per_ms(CPUTicks::Frequency_Hz_Div8, 10.0); + + static volatile uint16_t global_counter_10ms; + + public: + HighResTime() = delete; + ~HighResTime() = delete; + + static void enable() { + Interrupt::enable_irq(Interrupt::Timer2); + } + + static void disable() { + Interrupt::disable_irq(Interrupt::Timer2); + } + + static TimeStamp get_time_stamp() { + return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); + } + }; } #endif //!__JABYENGINE_HIGH_RES_TIMER_HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_config.hpp b/include/PSX/jabyengine_config.hpp deleted file mode 100644 index 5d2ed50d..00000000 --- a/include/PSX/jabyengine_config.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JABYENGINE_CONFIG_HPP__ -#define __JABYENGINE_CONFIG_HPP__ - #ifdef USE_CUSTOM_CONFIG - #include - #else - #define JABYENGINE_USE_HIGH_PERCISION_TIMER - #endif //USE_CUSTOM_CONFIG -#endif //!__JABYENGINE_CONFIG_HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h index 8c838cb7..224f1708 100644 --- a/include/PSX/jabyengine_defines.h +++ b/include/PSX/jabyengine_defines.h @@ -1,6 +1,5 @@ #ifndef __JABYENGINE_DEFINES__H__ #define __JABYENGINE_DEFINES__H__ -#include "jabyengine_config.hpp" #include "../stddef.h" #define __used __attribute__((used)) diff --git a/lib/Makefile b/lib/Makefile index 5b262c51..b0d342f8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -46,11 +46,7 @@ CCFLAGS_debug += -O0 CXXFLAGS += -fno-exceptions -fno-rtti -USE_FUNCTION_SECTIONS ?= true -ifeq ($(USE_FUNCTION_SECTIONS),true) -CCFLAGS += -ffunction-sections -endif -CCFLAGS += -mno-gpopt -fomit-frame-pointer +CCFLAGS += -mno-gpopt -fomit-frame-pointer -ffunction-sections CCFLAGS += -fno-builtin -fno-strict-aliasing -Wno-attributes CCFLAGS += -std=c++20 CCFLAGS += $(ARCHFLAGS) @@ -76,11 +72,11 @@ OBJS = $(addprefix $(OUTPUT_DIR)/,$(addsuffix .o, $(subst ..,!super,$(basename $ #Compiling rule $(OUTPUT_DIR)/%.o: %.s @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(OUTPUT_DIR)/%.o: %.c @mkdir -p $(dir $@) - $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $(CCFLAGS) $< + $(CC) -c $(DEPS) -o $@ $(CCFLAGS) $< $(OUTPUT_DIR)/%.o: %.cpp @mkdir -p $(dir $@) diff --git a/src/Library/Makefile b/src/Library/Makefile index 4183fabe..d4563cd1 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -10,8 +10,7 @@ CCFLAGS += -Iinclude -I../../include CCFLAGS += -save-temps=obj include ../../lib/Wildcard.mk -SRCS = $(call rwildcard, src, c cpp) -SRCS += src/syscall_printf.asm +SRCS = $(call rwildcard, src, c cpp s) include ../../lib/Makefile LIB_DIR = ../../lib/$(CONFIG_NAME) diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 111c5fbf..cc0e4629 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -21,15 +21,10 @@ namespace JabyEngine { CD::setup(); Timer::setup(); - const auto start = HighResTime::get_time_stamp(); - printf("Start...\n"); GPU::setup(); GPU::display_logo(); - const auto end = HighResTime::get_time_stamp(); - printf("GPU setup took %ims %ius\n", start.milliseconds_to(end), start.microseconds_to(end)); //Pause?? - SPU::setup(); } } diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp index 201e41ba..c0a8a492 100644 --- a/src/Library/src/BootLoader/timer_boot.cpp +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -1,46 +1,34 @@ -#include -#ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - #include - #include - #define private public - #include - #undef private +#include +#include +#define private public +#include +#undef private - namespace JabyEngine { +namespace JabyEngine { + namespace Timer { + extern InterrupCallback IRQCallback; + } + + namespace boot { namespace Timer { - extern InterrupCallback IRQCallback; - } + using namespace JabyEngine::Timer; + + void setup() { + using namespace Timer_IO; - namespace boot { - namespace Timer { - using namespace JabyEngine::Timer; - - void setup() { - using namespace Timer_IO; + static constexpr auto Mode = CounterMode_t::from(CounterMode_t::FreeRun, Counter2_v::SyncMode::FreeRun, CounterMode_t::ResetAfterTarget, CounterMode_t::IRQAtTarget, CounterMode_t::IRQEveryTime, CounterMode_t::IRQPulse, Counter2_v::Source::System_Clock_Div_8); - static constexpr auto Mode = CounterMode_t::from(CounterMode_t::FreeRun, Counter2_v::SyncMode::FreeRun, CounterMode_t::ResetAfterTarget, CounterMode_t::IRQAtTarget, CounterMode_t::IRQEveryTime, CounterMode_t::IRQPulse, Counter2_v::Source::System_Clock_Div_8); + // We disable the IRQ here so it can be enabled by user demand later + // Having the interrupt fire every 10ms will slow us down slightly so we only do it on demand + Interrupt::disable_irq(Interrupt::Timer2); - Interrupt::disable_irq(Interrupt::Timer2); + __syscall_EnterCriticalSection(); + __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); + __syscall_ExitCriticalSection(); - __syscall_EnterCriticalSection(); - __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); - __syscall_ExitCriticalSection(); - - Counter2.set_target_value(HighResTime::TicksFor10ms); - Counter2.set_mode(Mode); - - Interrupt::enable_irq(Interrupt::Timer2); - } + Counter2.set_target_value(HighResTime::TicksFor10ms); + Counter2.set_mode(Mode); } } } -#else - namespace JabyEngine { - namespace boot { - namespace Timer { - void setup() { - } - } - } - } -#endif //JABYENGINE_USE_HIGH_PERCISION_TIMER \ No newline at end of file +} \ No newline at end of file diff --git a/src/Library/src/Timer/high_res_timer.cpp b/src/Library/src/Timer/high_res_timer.cpp index 7a7fd3d9..45f5d650 100644 --- a/src/Library/src/Timer/high_res_timer.cpp +++ b/src/Library/src/Timer/high_res_timer.cpp @@ -1,38 +1,34 @@ -#include -#ifdef JABYENGINE_USE_HIGH_PERCISION_TIMER - #define private public - #include - #include - #include - #include - #undef private +#define private public +#include +#include +#include +#undef private - namespace JabyEngine { - volatile uint16_t HighResTime :: global_counter_10ms = 0; +namespace JabyEngine { + volatile uint16_t HighResTime :: global_counter_10ms = 0; - namespace Timer { - static InterruptVerifierResult interrupt_verifier() { - if(Interrupt::is_irq(Interrupt::Timer2)) { - return InterruptVerifierResult::ExecuteHandler; - } - - else { - return InterruptVerifierResult::SkipHandler; - } + namespace Timer { + static InterruptVerifierResult interrupt_verifier() { + if(Interrupt::is_irq(Interrupt::Timer2)) { + return InterruptVerifierResult::ExecuteHandler; } - - static void interrupt_handler(uint32_t) { - HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; - - Interrupt::ack_irq(Interrupt::Timer2); - __syscall_ReturnFromException(); + + else { + return InterruptVerifierResult::SkipHandler; } - - InterrupCallback IRQCallback = { - .next = nullptr, - .handler_function = reinterpret_cast(interrupt_handler), - .verifier_function = interrupt_verifier - }; } + + static void interrupt_handler(uint32_t) { + HighResTime::global_counter_10ms = HighResTime::global_counter_10ms + 1; + + Interrupt::ack_irq(Interrupt::Timer2); + __syscall_ReturnFromException(); + } + + InterrupCallback IRQCallback = { + .next = nullptr, + .handler_function = reinterpret_cast(interrupt_handler), + .verifier_function = interrupt_verifier + }; } -#endif //JABYENGINE_USE_HIGH_PERCISION_TIMER \ No newline at end of file +} \ No newline at end of file diff --git a/src/Library/src/busyloop.s b/src/Library/src/busyloop.s new file mode 100644 index 00000000..91e5daad --- /dev/null +++ b/src/Library/src/busyloop.s @@ -0,0 +1,26 @@ + .set noreorder + .section .text, "ax", @progbits + .align 2 + .global busy_loop + .type busy_loop, @function + +busy_loop: + sw $a0, 0($sp) + lw $v0, 0($sp) + lw $v1, 0($sp) + nop + addiu $v1, -1 + beqz $v0, early_exit + sw $v1, 0($sp) + +busy_loop_loop: + lw $v0, 0($sp) + lw $v1, 0($sp) + nop + addiu $v1, -1 + bnez $v0, busy_loop_loop + sw $v1, 0($sp) + +early_exit: + jr $ra + nop diff --git a/src/Library/src/syscall_printf.s b/src/Library/src/syscall_printf.s index 08d7c540..eaf86b84 100644 --- a/src/Library/src/syscall_printf.s +++ b/src/Library/src/syscall_printf.s @@ -1,6 +1,6 @@ .set push .set noreorder -#.section .ramtext, "ax", @progbits + .section .text, "ax", @progbits .align 2 .global __syscall_printf .type __syscall_printf, @function