From 45371bc2f03d3f348c8b4d9b726bd5336bd597a8 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 3 Mar 2023 14:33:29 +0100 Subject: [PATCH 01/47] Simulated load of a file --- include/PSX/Auxiliary/circular_buffer.hpp | 4 +- .../PSX/File/Processor/cd_file_processor.hpp | 13 +++--- include/PSX/System/IOPorts/cd_io.hpp | 12 +++++ src/Library/include/CD/cd_internal.hpp | 16 +++++-- src/Library/include/CD/cd_types.hpp | 21 +++------ src/Library/src/CD/cd.cpp | 45 +++++++++++++++---- .../src/File/Processor/cd_file_processor.cpp | 33 +++++++++++--- 7 files changed, 106 insertions(+), 38 deletions(-) diff --git a/include/PSX/Auxiliary/circular_buffer.hpp b/include/PSX/Auxiliary/circular_buffer.hpp index eaba8814..82ace72d 100644 --- a/include/PSX/Auxiliary/circular_buffer.hpp +++ b/include/PSX/Auxiliary/circular_buffer.hpp @@ -17,10 +17,12 @@ namespace JabyEngine { public: FastCircularBuffer() = default; - void setup(T* buffer_start_adr) { + size_t setup(T* buffer_start_adr) { this->start_adr = buffer_start_adr; this->read_idx = 0; this->write_idx = 0; + + return (sizeof(T)*ElementCount); } T* allocate() { diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index a1b4be58..09f6abc6 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -1,7 +1,9 @@ #ifndef __JABYENGINE_CD_FILE_PROCESSOR_HPP__ #define __JABYENGINE_CD_FILE_PROCESSOR_HPP__ #include "../../AutoLBA/auto_lba.hpp" +#include "../../Auxiliary/circular_buffer.hpp" #include "../../Auxiliary/lz4_decompressor.hpp" +#include "../../System/IOPorts/cd_io.hpp" #include "../cd_file_types.hpp" #include "file_processor.hpp" @@ -16,11 +18,12 @@ namespace JabyEngine { }; private: - FileProcessor::State file_pro_state; - LZ4Decompressor lz4_decomp; - JobArray jobs; - uint8_t* work_area = nullptr; - const AutoLBAEntry* lba = nullptr; + FileProcessor::State file_pro_state; + FastCircularBuffer circular_buffer; + LZ4Decompressor lz4_decomp; + JobArray jobs; + uint8_t* work_area = nullptr; + const AutoLBAEntry* lba = nullptr; void start_cur_job(); diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 2833467d..416fdbab 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -4,6 +4,18 @@ namespace JabyEngine { namespace CD_IO { + struct DataSector { + static constexpr size_t SizeBytes = 2048; + static constexpr size_t SizeWords = (SizeBytes/sizeof(uint32_t)); + + uint32_t data[SizeWords]; + + template + static constexpr T words_to_sectors(T size) { + return (size + static_cast(DataSector::SizeWords - 1))/static_cast(DataSector::SizeWords); + } + }; + enum Index { Index0 = 0, Index1 = 1, diff --git a/src/Library/include/CD/cd_internal.hpp b/src/Library/include/CD/cd_internal.hpp index 73469ce7..0eed478a 100644 --- a/src/Library/include/CD/cd_internal.hpp +++ b/src/Library/include/CD/cd_internal.hpp @@ -1,16 +1,24 @@ #ifndef __JABYENGINE_CD_INTERNAL_HPP__ #define __JABYENGINE_CD_INTERNAL_HPP__ #include "cd_types.hpp" -#include namespace JabyEngine { namespace CD { namespace internal { - extern VolatilePOD last_interrupt; + extern CD_IO::Interrupt::Type last_interrupt; + extern State current_state; + + static CD_IO::Interrupt::Type read_last_interrupt() { + return const_cast(last_interrupt); + } + + static State read_current_state() { + return const_cast(current_state); + } struct Command { static void wait_until(CD_IO::Interrupt::Type irq) { - while(last_interrupt.read() != irq); + while(read_last_interrupt() != irq); } template @@ -38,7 +46,7 @@ namespace JabyEngine { } }; - State read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); + void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); } } } diff --git a/src/Library/include/CD/cd_types.hpp b/src/Library/include/CD/cd_types.hpp index 9beb22bf..01c7214d 100644 --- a/src/Library/include/CD/cd_types.hpp +++ b/src/Library/include/CD/cd_types.hpp @@ -2,6 +2,7 @@ #define __JABYENGINE_INTERNAL_CD_TYPES_HPP__ #include #include +#include #include namespace JabyEngine { @@ -16,30 +17,18 @@ namespace JabyEngine { Error, }; - struct DataSector { - static constexpr size_t SizeBytes = 2048; - static constexpr size_t SizeWords = (SizeBytes/sizeof(uint32_t)); - - uint32_t data[SizeWords]; - - template - static constexpr T words_to_sectors(T size) { - return (size + static_cast(DataSector::SizeWords - 1))/static_cast(DataSector::SizeWords); - } - }; - struct FileInfo { uint16_t lba; uint16_t sectors; static constexpr FileInfo from(const AutoLBAEntry& entry) { - return FileInfo{entry.lba, DataSector::words_to_sectors(entry.size_words)}; + return FileInfo{entry.lba, CD_IO::DataSector::words_to_sectors(entry.size_words)}; } }; class SectorBufferAllocator { private: - typedef DataSector* (*AllocatorFunction)(void* ctx); + typedef CD_IO::DataSector* (*AllocatorFunction)(void* ctx); private: void* ctx = nullptr; @@ -54,6 +43,10 @@ namespace JabyEngine { static constexpr SectorBufferAllocator create(void* obj, AllocatorFunction function) { return SectorBufferAllocator(obj, function); } + + inline CD_IO::DataSector* allocate_sector() const { + return this->allocate(this->ctx); + } }; struct CDTimeStamp { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 859172e3..24769bb1 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -25,20 +25,46 @@ namespace JabyEngine { static uint16_t sectors_left; static InterruptVerifierResult interrupt_verifier() { + static const auto pause = []() { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Pause); + }; + if(Interrupt::is_irq(Interrupt::CDROM)) { const uint8_t old_idx = (CD_IO::IndexStatus.read() & 0x3); CD_IO::PortIndex1::change_to(); const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlagRegister); - last_interrupt.write(cur_irq); + last_interrupt = cur_irq; CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlagRegister); if(cur_irq == CD_IO::Interrupt::DataReady) { - sectors_left--; - if(sectors_left == 0) { - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Pause); + //Obtain sector content here + auto* sector = sector_allocator.allocate_sector(); + if(sector) { + //Now obtain sector + static const char SimpleStr[] = "CD-Drive: This is a test string"; + + char* test_str = reinterpret_cast(sector->data); + for(size_t n = 0; n < sizeof(SimpleStr); n++) { + test_str[n] = SimpleStr[n]; + } + + sectors_left--; + if(sectors_left == 0) { + current_state = State::Done; + pause(); + } } + + else { + current_state = State::BufferFull; + pause(); + } + } + + else if(cur_irq == CD_IO::Interrupt::DiskError) { + current_state = State::Error; } CD_IO::IndexStatus.write({old_idx}); @@ -55,14 +81,15 @@ namespace JabyEngine { __syscall_ReturnFromException(); } - VolatilePOD last_interrupt{CD_IO::Interrupt::Type::None}; + CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; + State current_state = State::Free; InterrupCallback callback = { .next = nullptr, .handler_function = reinterpret_cast(interrupt_handler), .verifier_function = interrupt_verifier }; - State read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { + void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { sector_allocator = buffer_allocator; sectors_left = file_info.sectors; @@ -73,9 +100,9 @@ namespace JabyEngine { Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); Command::send(CD_IO::Command::ReadN); + current_state = State::Reading; + printf("Now reading: %i\n", file_info.lba); - printf("I'm not fully implemented! %s\n", __FUNCTION__); - return State::Error; } } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 62bc2c8f..635a1be8 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -7,11 +7,13 @@ namespace JabyEngine { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; - const auto& cur_lba = this->lba[this->jobs.files->rel_lba_idx]; + const auto& cur_job = *this->jobs.files; + const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; - CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, [](void* ctx) -> CD::internal::DataSector* { - printf("Blubb?!\n"); - return nullptr; + CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* { + CDFileProcessor &self = *reinterpret_cast(ctx); + + return self.circular_buffer.allocate(); })); printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); @@ -19,13 +21,34 @@ namespace JabyEngine { void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) { this->lba = const_cast(lba); - this->work_area = work_area; + this->work_area = (work_area + this->circular_buffer.setup(reinterpret_cast(work_area))); this->jobs = jobs; CDFileProcessor::start_cur_job(); } Progress CDFileProcessor :: process() { + switch(CD::internal::read_current_state()) { + case CD::internal::State::Done: + // Need to start next job? + // Does the user trigger this? + printf("Done: %i\n", this->circular_buffer.has_data()); + return Progress::Done; + + case CD::internal::State::BufferFull: + // We have to process data and unpause the CD drive + // Error case for now + return Progress::Error; + + case CD::internal::State::Reading: + // Do we have data? Use it! + return Progress::InProgress; + + case CD::internal::State::Error: + // Error for real! + return Progress::Error; + } + return Progress::Error; } } \ No newline at end of file From d8e7772ee54c2655a36194e652df4934ca2037a5 Mon Sep 17 00:00:00 2001 From: jaby Date: Fri, 3 Mar 2023 17:30:45 +0100 Subject: [PATCH 02/47] Improve CircularBuffer again --- include/PSX/Auxiliary/circular_buffer.hpp | 91 +++++++++---------- .../PSX/File/Processor/cd_file_processor.hpp | 12 +-- .../src/File/Processor/cd_file_processor.cpp | 12 ++- 3 files changed, 58 insertions(+), 57 deletions(-) diff --git a/include/PSX/Auxiliary/circular_buffer.hpp b/include/PSX/Auxiliary/circular_buffer.hpp index 82ace72d..c68f3631 100644 --- a/include/PSX/Auxiliary/circular_buffer.hpp +++ b/include/PSX/Auxiliary/circular_buffer.hpp @@ -3,68 +3,61 @@ #include "array_range.hpp" namespace JabyEngine { - template - class FastCircularBuffer { - private: - T* start_adr = nullptr; - size_t read_idx = 0; - size_t write_idx = 0; + template + class CircularBuffer { + private: + T* start_adr = nullptr; + T* end_adr = nullptr; + T* read_adr = nullptr; + T* write_adr = nullptr; - static size_t increment(size_t cur_idx, size_t step) { - return ((cur_idx + step) & (ElementCount - 1)); + T* increment(T* cur_element) const { + cur_element += 1; + if(cur_element == this->end_adr) { + return this->start_adr; } - public: - FastCircularBuffer() = default; - - size_t setup(T* buffer_start_adr) { - this->start_adr = buffer_start_adr; - this->read_idx = 0; - this->write_idx = 0; + return cur_element; + } - return (sizeof(T)*ElementCount); - } + public: + CircularBuffer() = default; + + T* setup(T* buffer_start_adr, size_t elements) { + this->start_adr = buffer_start_adr; + this->end_adr = &buffer_start_adr[elements]; - T* allocate() { - const auto new_idx = FastCircularBuffer::increment(this->write_idx, 1); - if(new_idx != this->read_idx) { - auto* dst = (this->start_adr + this->write_idx); - - this->write_idx = new_idx; - return dst; - } + this->read_adr = this->start_adr; + this->write_adr = this->start_adr; + return this->end_adr; + } + T* allocate() { + T* cur_adr = this->write_adr; + T* next_adr = CircularBuffer::increment(cur_adr); + if(next_adr == this->read_adr) { return nullptr; } - const T* pop() { - if(this->write_idx != this->read_idx) { - const auto* src = (this->start_adr + this->read_idx); - FastCircularBuffer::drop(1); - - return src; - } - - return nullptr; + else { + this->write_adr = next_adr; + return cur_adr; } + } - void drop(size_t elements) { - this->read_idx = FastCircularBuffer::increment(this->read_idx, elements); + T* get_next() const { + return this->read_adr; + } + + void pop() { + if(CircularBuffer::has_data()) { + this->read_adr = CircularBuffer::increment(this->read_adr); } + } - constexpr ArrayRange get_first_continious() const { - return {&this->start_adr[this->read_idx], (this->write_idx >= this->read_idx) ? (this->write_idx - this->read_idx) : (ElementCount - this->read_idx)}; - } - - constexpr ArrayRange get_second_continious() const { - return {this->start_adr, (this->write_idx < this->read_idx) ? this->write_idx : 0}; - } - - constexpr bool has_data() const { - return (this->read_idx != this->write_idx); - } - - static_assert(ElementCount == 2 || ElementCount == 4 || ElementCount == 8 || ElementCount == 16 || ElementCount == 32 || ElementCount == 64 || ElementCount == 128 || ElementCount == 256, "ElementCount for FastCircularBuffer must be power of 2"); + constexpr bool has_data() const { + return (this->read_adr != this->write_adr); + } }; } diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index 09f6abc6..bd05a252 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -18,12 +18,12 @@ namespace JabyEngine { }; private: - FileProcessor::State file_pro_state; - FastCircularBuffer circular_buffer; - LZ4Decompressor lz4_decomp; - JobArray jobs; - uint8_t* work_area = nullptr; - const AutoLBAEntry* lba = nullptr; + FileProcessor::State file_pro_state; + CircularBuffer circular_buffer; + LZ4Decompressor lz4_decomp; + JobArray jobs; + uint8_t* work_area = nullptr; + const AutoLBAEntry* lba = nullptr; void start_cur_job(); diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 635a1be8..41c79ecd 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -21,18 +21,25 @@ namespace JabyEngine { void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) { this->lba = const_cast(lba); - this->work_area = (work_area + this->circular_buffer.setup(reinterpret_cast(work_area))); + this->work_area = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), 5)); this->jobs = jobs; CDFileProcessor::start_cur_job(); } Progress CDFileProcessor :: process() { + const auto test_print = [this](){ + if(this->circular_buffer.has_data()) { + printf("Got-Data: %s\n", this->circular_buffer.get_next()); + this->circular_buffer.pop(); + } + }; + switch(CD::internal::read_current_state()) { case CD::internal::State::Done: // Need to start next job? // Does the user trigger this? - printf("Done: %i\n", this->circular_buffer.has_data()); + test_print(); return Progress::Done; case CD::internal::State::BufferFull: @@ -42,6 +49,7 @@ namespace JabyEngine { case CD::internal::State::Reading: // Do we have data? Use it! + test_print(); return Progress::InProgress; case CD::internal::State::Error: From 46aedaa0675a7c0285e9aee73abe6d90b1f01b5c Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 14 Mar 2023 22:33:49 +0100 Subject: [PATCH 03/47] New concept for IOPorts --- include/PSX/System/IOPorts/ioport.hpp | 12 ++++++++++++ include/PSX/System/IOPorts/memory_io.hpp | 15 +++++++++++---- src/Library/src/BootLoader/cd_boot.cpp | 12 +++++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index bec6bf78..f877828b 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -3,6 +3,18 @@ #include "../../Auxiliary/complex_bitmap.hpp" namespace JabyEngine { + template + struct NormalValue { + typedef T Value; + typedef T NakedValue; + }; + + template + struct VolatileValue { + typedef volatile T Value; + typedef T NakedValue; + }; + template struct VolatilePOD { volatile T raw; diff --git a/include/PSX/System/IOPorts/memory_io.hpp b/include/PSX/System/IOPorts/memory_io.hpp index 104b8d5f..1a701858 100644 --- a/include/PSX/System/IOPorts/memory_io.hpp +++ b/include/PSX/System/IOPorts/memory_io.hpp @@ -4,11 +4,16 @@ namespace JabyEngine { namespace Memory_IO { - struct COM_DELAY { - typedef uint32_t Type; + template typename T> + struct COM_DELAY_base { + T::Value value; - static constexpr uint32_t SetupValue = 0x1325; + void setup() { + this->value = 0x1325; + } }; + typedef COM_DELAY_base COM_DELAY_v; + typedef COM_DELAY_base COM_DELAY_t; struct CD_DELAY { typedef uint32_t Type; @@ -16,7 +21,9 @@ namespace JabyEngine { static constexpr uint32_t SetupValue = 0x20943; }; - __declare_io_port_global_simple(COM_DELAY::Type, COM_DELAY, 0x1F801020); + static auto& COM_DELAY = *reinterpret_cast(0x1F801020); + + //__declare_io_port_global_simple(COM_DELAY::Type, COM_DELAY, 0x1F801020); __declare_io_port_global_simple(CD_DELAY::Type, CD_DELAY, 0x1F801018); } } diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index 66a79fe2..9f6e7aa6 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -16,7 +16,17 @@ namespace JabyEngine { void setup() { __syscall_EnterCriticalSection(); - Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::SetupValue); + Memory_IO::COM_DELAY.setup(); + Memory_IO::COM_DELAY.setup(); + Memory_IO::COM_DELAY.setup(); + + Memory_IO::COM_DELAY_t b{Memory_IO::COM_DELAY.value}; + + b.setup(); + b.setup(); + b.setup(); + + //Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::SetupValue); Memory_IO::CD_DELAY.write(Memory_IO::CD_DELAY::SetupValue); __syscall_SysEnqIntRP(CdromIoIrq, &::JabyEngine::CD::internal::callback); From 218b8e0e3b3a0ad74eebf6818286ee36abf0f7b6 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 14 Mar 2023 22:53:32 +0100 Subject: [PATCH 04/47] Refine new IO port concept --- include/PSX/System/IOPorts/ioport.hpp | 21 +++++++++++++----- include/PSX/System/IOPorts/memory_io.hpp | 27 +++++++++--------------- src/Library/src/BootLoader/cd_boot.cpp | 12 +---------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index f877828b..1d1afa3c 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -6,17 +6,28 @@ namespace JabyEngine { template struct NormalValue { typedef T Value; - typedef T NakedValue; }; template struct VolatileValue { typedef volatile T Value; - typedef T NakedValue; }; - + + #define __declare_new_io_port(name, adr) \ + typedef name##_io_base name##_v; \ + typedef name##_io_base name##_t; \ + static auto& name = *reinterpret_cast(adr) + + #define __declare_io_type(name, type, ...) \ + template typename T> \ + struct name##_io_base { \ + T::Value value; \ + \ + __VA_ARGS__ \ + } + template - struct VolatilePOD { + struct __attribute__((deprecated)) VolatilePOD { volatile T raw; constexpr T read() const { @@ -30,7 +41,7 @@ namespace JabyEngine { // For use with ComplexBitMaps or what else satisfies this API template - struct VolatileBitMapPOD { + struct __attribute__((deprecated)) VolatileBitMapPOD { typedef typename T::UnderlyingType Raw; VolatilePOD pod; diff --git a/include/PSX/System/IOPorts/memory_io.hpp b/include/PSX/System/IOPorts/memory_io.hpp index 1a701858..162c1d75 100644 --- a/include/PSX/System/IOPorts/memory_io.hpp +++ b/include/PSX/System/IOPorts/memory_io.hpp @@ -4,27 +4,20 @@ namespace JabyEngine { namespace Memory_IO { - template typename T> - struct COM_DELAY_base { - T::Value value; - + __declare_io_type(COM_DELAY, uint32_t, void setup() { this->value = 0x1325; - } - }; - typedef COM_DELAY_base COM_DELAY_v; - typedef COM_DELAY_base COM_DELAY_t; + } + ); - struct CD_DELAY { - typedef uint32_t Type; + __declare_io_type(CD_DELAY, uint32_t, + void setup() { + this->value = 0x20943; + } + ); - static constexpr uint32_t SetupValue = 0x20943; - }; - - static auto& COM_DELAY = *reinterpret_cast(0x1F801020); - - //__declare_io_port_global_simple(COM_DELAY::Type, COM_DELAY, 0x1F801020); - __declare_io_port_global_simple(CD_DELAY::Type, CD_DELAY, 0x1F801018); + __declare_new_io_port(COM_DELAY, 0x1F801020); + __declare_new_io_port(CD_DELAY, 0x1F801018); } } diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index 9f6e7aa6..c7507534 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -17,17 +17,7 @@ namespace JabyEngine { void setup() { __syscall_EnterCriticalSection(); Memory_IO::COM_DELAY.setup(); - Memory_IO::COM_DELAY.setup(); - Memory_IO::COM_DELAY.setup(); - - Memory_IO::COM_DELAY_t b{Memory_IO::COM_DELAY.value}; - - b.setup(); - b.setup(); - b.setup(); - - //Memory_IO::COM_DELAY.write(Memory_IO::COM_DELAY::SetupValue); - Memory_IO::CD_DELAY.write(Memory_IO::CD_DELAY::SetupValue); + Memory_IO::CD_DELAY.setup(); __syscall_SysEnqIntRP(CdromIoIrq, &::JabyEngine::CD::internal::callback); From ed71af970bcc951a2008568dbf28e40d07bd4e36 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 15 Mar 2023 21:20:16 +0100 Subject: [PATCH 05/47] Support assignment of values --- include/PSX/System/IOPorts/ioport.hpp | 10 +++++++++- include/PSX/System/IOPorts/memory_io.hpp | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 1d1afa3c..cd1e7a37 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -21,9 +21,17 @@ namespace JabyEngine { #define __declare_io_type(name, type, ...) \ template typename T> \ struct name##_io_base { \ - T::Value value; \ + T::Value raw_value; \ \ + name##_io_base(type value) : raw_value(value) {} \ __VA_ARGS__ \ + \ + void operator=(type value) { \ + this->raw_value = value; \ + } \ + type operator*() const { \ + return this->raw_value; \ + } \ } template diff --git a/include/PSX/System/IOPorts/memory_io.hpp b/include/PSX/System/IOPorts/memory_io.hpp index 162c1d75..dd884d23 100644 --- a/include/PSX/System/IOPorts/memory_io.hpp +++ b/include/PSX/System/IOPorts/memory_io.hpp @@ -6,13 +6,13 @@ namespace JabyEngine { namespace Memory_IO { __declare_io_type(COM_DELAY, uint32_t, void setup() { - this->value = 0x1325; + this->raw_value = 0x1325; } ); __declare_io_type(CD_DELAY, uint32_t, void setup() { - this->value = 0x20943; + this->raw_value = 0x20943; } ); From e11e475802056190f67a98044affbbc4d414f9cf Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 15 Mar 2023 21:38:55 +0100 Subject: [PATCH 06/47] Support a form of setting bits easily --- include/PSX/System/IOPorts/ioport.hpp | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index cd1e7a37..97f1fbdd 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -3,6 +3,24 @@ #include "../../Auxiliary/complex_bitmap.hpp" namespace JabyEngine { + struct IOBitUnset { + size_t pos; + + constexpr IOBitUnset(size_t bit_pos) : pos(bit_pos) { + } + }; + + struct IOBitSet { + size_t pos; + + constexpr IOBitSet(size_t bit_pos) : pos(bit_pos) { + } + + constexpr IOBitUnset operator!() const { + return IOBitUnset(this->pos); + } + }; + template struct NormalValue { typedef T Value; @@ -26,6 +44,24 @@ namespace JabyEngine { name##_io_base(type value) : raw_value(value) {} \ __VA_ARGS__ \ \ + void set(IOBitSet bit) { \ + this->raw_value = bit::set(this->raw_value, bit.pos); \ + } \ + void set(IOBitUnset bit) { \ + this->raw_value = bit::clear(this->raw_value, bit.pos); \ + } \ + \ + \ + void clear(IOBitSet bit) { \ + this->raw_value = bit::clear(this->raw_value, bit.pos); \ + } \ + \ + \ + bool is_set(IOBitSet bit) const { \ + return bit::is_set(this->raw_value, bit.pos);\ + } \ + \ + \ void operator=(type value) { \ this->raw_value = value; \ } \ From 9659cc6ad56850f0cfa689bc222021fe378cf122 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 16 Mar 2023 22:20:43 +0100 Subject: [PATCH 07/47] Support IOPortValues --- include/PSX/Auxiliary/bits.hpp | 4 +-- include/PSX/System/IOPorts/ioport.hpp | 45 +++++++++++++++++++++--- include/PSX/System/IOPorts/memory_io.hpp | 2 ++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/include/PSX/Auxiliary/bits.hpp b/include/PSX/Auxiliary/bits.hpp index 935d2700..8ef3a671 100644 --- a/include/PSX/Auxiliary/bits.hpp +++ b/include/PSX/Auxiliary/bits.hpp @@ -37,12 +37,12 @@ namespace JabyEngine { template static constexpr T set_normalized(T raw_value, T value, size_t start_bit, size_t length) { - return (clear_normalized(raw_value, start_bit, length) | (value << start_bit)); + return (clear_normalized(raw_value, start_bit, length) | (crop_value(value, length) << start_bit)); } template static constexpr T get_normalized(T raw_value, size_t start_bit, size_t length) { - return (raw_value & range_mask(start_bit, length)) >> start_bit; + return crop_value((raw_value & range_mask(start_bit, length)) >> start_bit, length); } } diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 97f1fbdd..7253482d 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -1,19 +1,20 @@ #ifndef __JABYENGINE_IOPORT_HPP__ #define __JABYENGINE_IOPORT_HPP__ #include "../../Auxiliary/complex_bitmap.hpp" +#include "../../Auxiliary/types.hpp" namespace JabyEngine { struct IOBitUnset { - size_t pos; + uint16_t pos; - constexpr IOBitUnset(size_t bit_pos) : pos(bit_pos) { + constexpr IOBitUnset(uint16_t bit_pos) : pos(bit_pos) { } }; struct IOBitSet { - size_t pos; + uint16_t pos; - constexpr IOBitSet(size_t bit_pos) : pos(bit_pos) { + constexpr IOBitSet(uint16_t bit_pos) : pos(bit_pos) { } constexpr IOBitUnset operator!() const { @@ -21,6 +22,26 @@ namespace JabyEngine { } }; + struct IOValueSet { + template + using IOValueSetPair = pair; + + uint16_t pos; + uint16_t length; + + constexpr IOValueSet(uint16_t pos, uint16_t length) : pos(pos), length(length) { + } + + static constexpr IOValueSet from_to(uint16_t first_bit, uint16_t last_bit) { + return IOValueSet(first_bit, (last_bit - first_bit) + 1); + } + + template + constexpr IOValueSetPair with(T value) const { + return {*this, value}; + } + }; + template struct NormalValue { typedef T Value; @@ -47,10 +68,23 @@ namespace JabyEngine { void set(IOBitSet bit) { \ this->raw_value = bit::set(this->raw_value, bit.pos); \ } \ + \ void set(IOBitUnset bit) { \ this->raw_value = bit::clear(this->raw_value, bit.pos); \ } \ \ + void set(IOValueSet bits, type value) { \ + this->raw_value = bit::value::set_normalized(this->raw_value, value, bits.pos, bits.length); \ + } \ + \ + void set(const IOValueSet::IOValueSetPair& value) { \ + this->set(value.first, value.second); \ + } \ + \ + type get(IOValueSet bits) const { \ + return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ + } \ + \ \ void clear(IOBitSet bit) { \ this->raw_value = bit::clear(this->raw_value, bit.pos); \ @@ -58,13 +92,14 @@ namespace JabyEngine { \ \ bool is_set(IOBitSet bit) const { \ - return bit::is_set(this->raw_value, bit.pos);\ + return bit::is_set(this->raw_value, bit.pos); \ } \ \ \ void operator=(type value) { \ this->raw_value = value; \ } \ + \ type operator*() const { \ return this->raw_value; \ } \ diff --git a/include/PSX/System/IOPorts/memory_io.hpp b/include/PSX/System/IOPorts/memory_io.hpp index dd884d23..bf142144 100644 --- a/include/PSX/System/IOPorts/memory_io.hpp +++ b/include/PSX/System/IOPorts/memory_io.hpp @@ -5,6 +5,8 @@ namespace JabyEngine { namespace Memory_IO { __declare_io_type(COM_DELAY, uint32_t, + static constexpr auto CodyValue = IOValueSet::from_to(2, 4); + void setup() { this->raw_value = 0x1325; } From 5fc4c2dc44b73e31ec32bf15c105fc5f317745b9 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 16 Mar 2023 22:26:45 +0100 Subject: [PATCH 08/47] Forgot to remove Cody --- include/PSX/System/IOPorts/memory_io.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/PSX/System/IOPorts/memory_io.hpp b/include/PSX/System/IOPorts/memory_io.hpp index bf142144..dd884d23 100644 --- a/include/PSX/System/IOPorts/memory_io.hpp +++ b/include/PSX/System/IOPorts/memory_io.hpp @@ -5,8 +5,6 @@ namespace JabyEngine { namespace Memory_IO { __declare_io_type(COM_DELAY, uint32_t, - static constexpr auto CodyValue = IOValueSet::from_to(2, 4); - void setup() { this->raw_value = 0x1325; } From 47484a8056c35b9637f731fbda4f5aa0c67fa3c5 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 18 Mar 2023 15:02:21 +0100 Subject: [PATCH 09/47] Make IOPort constexpr --- include/PSX/System/IOPorts/ioport.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 7253482d..d6d95578 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -60,25 +60,31 @@ namespace JabyEngine { #define __declare_io_type(name, type, ...) \ template typename T> \ struct name##_io_base { \ - T::Value raw_value; \ + T::Value raw_value = 0; \ \ - name##_io_base(type value) : raw_value(value) {} \ + constexpr name##_io_base() = default; \ + \ + constexpr name##_io_base(type value) : raw_value(value) {} \ __VA_ARGS__ \ \ - void set(IOBitSet bit) { \ + constexpr name##_io_base& set(IOBitSet bit) { \ this->raw_value = bit::set(this->raw_value, bit.pos); \ + return *this; \ } \ \ - void set(IOBitUnset bit) { \ + constexpr name##_io_base& set(IOBitUnset bit) { \ this->raw_value = bit::clear(this->raw_value, bit.pos); \ + return *this; \ } \ \ - void set(IOValueSet bits, type value) { \ + constexpr name##_io_base& set(IOValueSet bits, type value) { \ this->raw_value = bit::value::set_normalized(this->raw_value, value, bits.pos, bits.length); \ + return *this; \ } \ \ - void set(const IOValueSet::IOValueSetPair& value) { \ + constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ this->set(value.first, value.second); \ + return *this; \ } \ \ type get(IOValueSet bits) const { \ @@ -86,8 +92,9 @@ namespace JabyEngine { } \ \ \ - void clear(IOBitSet bit) { \ + constexpr name##_io_base& clear(IOBitSet bit) { \ this->raw_value = bit::clear(this->raw_value, bit.pos); \ + return *this; \ } \ \ \ From 33b5d4d3b768ca2d52ade578b647c84448ebda9a Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 18 Mar 2023 16:04:05 +0100 Subject: [PATCH 10/47] Convert Timer IO --- include/PSX/System/IOPorts/ioport.hpp | 39 ++++--- include/PSX/System/IOPorts/timer_io.hpp | 118 ++++++++++++---------- include/PSX/Timer/high_res_timer.hpp | 2 +- src/Library/src/BootLoader/timer_boot.cpp | 6 +- 4 files changed, 97 insertions(+), 68 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index d6d95578..72880b16 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -53,19 +53,23 @@ namespace JabyEngine { }; #define __declare_new_io_port(name, adr) \ - typedef name##_io_base name##_v; \ - typedef name##_io_base name##_t; \ static auto& name = *reinterpret_cast(adr) +/*constexpr name##_io_base() = default; \ + \ + constexpr name##_io_base(type value) : raw_value(value) {} \ + \*/ + #define __declare_io_type(name, type, ...) \ template typename T> \ struct name##_io_base { \ T::Value raw_value = 0; \ \ - constexpr name##_io_base() = default; \ - \ - constexpr name##_io_base(type value) : raw_value(value) {} \ __VA_ARGS__ \ + template \ + static constexpr name##_io_base from(const ARGS&...args) { \ + return name##_io_base().set_va(args...); \ + } \ \ constexpr name##_io_base& set(IOBitSet bit) { \ this->raw_value = bit::set(this->raw_value, bit.pos); \ @@ -87,7 +91,15 @@ namespace JabyEngine { return *this; \ } \ \ - type get(IOValueSet bits) const { \ + template \ + constexpr name##_io_base& set_va(const S& head) { \ + return this->set(head); \ + } \ + template \ + constexpr name##_io_base& set_va(const S& head, const ARGS&...tail) { \ + return this->set(head).set_va(tail...); \ + } \ + constexpr type get(IOValueSet bits) const { \ return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ } \ \ @@ -98,22 +110,25 @@ namespace JabyEngine { } \ \ \ - bool is_set(IOBitSet bit) const { \ + constexpr bool is_set(IOBitSet bit) const { \ return bit::is_set(this->raw_value, bit.pos); \ } \ \ \ - void operator=(type value) { \ + constexpr void operator=(type value) { \ this->raw_value = value; \ } \ \ - type operator*() const { \ + constexpr type operator*() const { \ return this->raw_value; \ } \ - } + }; \ + \ + typedef name##_io_base name##_v; \ + typedef name##_io_base name##_t \ template - struct __attribute__((deprecated)) VolatilePOD { + struct VolatilePOD { volatile T raw; constexpr T read() const { @@ -127,7 +142,7 @@ namespace JabyEngine { // For use with ComplexBitMaps or what else satisfies this API template - struct __attribute__((deprecated)) VolatileBitMapPOD { + struct VolatileBitMapPOD { typedef typename T::UnderlyingType Raw; VolatilePOD pod; diff --git a/include/PSX/System/IOPorts/timer_io.hpp b/include/PSX/System/IOPorts/timer_io.hpp index c8ff6e96..8343f70b 100644 --- a/include/PSX/System/IOPorts/timer_io.hpp +++ b/include/PSX/System/IOPorts/timer_io.hpp @@ -4,94 +4,108 @@ namespace JabyEngine { namespace Timer_IO { - struct CounterMode : public ComplexBitMap { - static constexpr auto SyncEnable = Bit(0); + __declare_io_type(CounterMode, uint32_t, + static constexpr auto SyncEnable = IOBitSet(0); static constexpr auto FreeRun = !SyncEnable; - static constexpr auto SyncMode = BitRange::from_to(1, 2); - static constexpr auto ResetAfterTarget = Bit(3); - static constexpr auto IRQAtTarget = Bit(4); - static constexpr auto IRQAtMax = Bit(5); - static constexpr auto IRQEveryTime = Bit(6); + static constexpr auto SyncMode = IOValueSet::from_to(1, 2); + static constexpr auto ResetAfterTarget = IOBitSet(3); + static constexpr auto IRQAtTarget = IOBitSet(4); + static constexpr auto IRQAtMax = IOBitSet(5); + static constexpr auto IRQEveryTime = IOBitSet(6); static constexpr auto IRQOneShot = !IRQEveryTime; - static constexpr auto IRQToggle = Bit(7); + static constexpr auto IRQToggle = IOBitSet(7); static constexpr auto IRQPulse = !IRQToggle; - static constexpr auto ClockSource = BitRange::from_to(8, 9); - static constexpr auto HasIRQRequest = Bit(10); - static constexpr auto IsTargetReached = Bit(11); - static constexpr auto IsMaxReached = Bit(12); - }; + static constexpr auto ClockSource = IOValueSet::from_to(8, 9); + static constexpr auto HasIRQRequest = IOBitSet(10); + static constexpr auto IsTargetReached = IOBitSet(11); + static constexpr auto IsMaxReached = IOBitSet(12); + ); - struct CounterTarget : public ComplexBitMap { - static constexpr auto CounterTargetValue = BitRange::from_to(0, 15); - }; + __declare_io_type(CounterTarget, uint32_t, + static constexpr auto CounterTargetValue = IOValueSet::from_to(0, 15); + ); - struct CounterValue : public ComplexBitMap { - static constexpr auto Value = BitRange::from_to(0, 15); - }; + __declare_io_type(CounterValue, uint32_t, + static constexpr auto Value = IOValueSet::from_to(0, 15); + ); struct __no_align Counter { - VolatileBitMapPOD value; - VolatileBitMapPOD mode; - VolatileBitMapPOD target; + CounterValue_v value; + CounterMode_v mode; + CounterTarget_v target; + private: uint32_t _unused; + + public: + constexpr uint16_t get_current_value() const { + return this->value.get(CounterValue_v::Value); + } + + constexpr void set_target_value(uint16_t value) { + this->target.set(CounterTarget_v::CounterTargetValue, value); + } + + constexpr void set_mode(CounterMode_t mode) { + this->mode = *mode; + } }; static constexpr uintptr_t counter_base_adr(size_t ID) { return (0x1F801100 + (ID*0x10)); } - struct __no_align Counter0 : public Counter { + struct __no_align Counter0_v : public Counter { struct SyncMode { - static constexpr auto Pause_During_Hblank = CounterMode::SyncMode.with(0); - static constexpr auto Zero_At_Hblank = CounterMode::SyncMode.with(1); - static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = CounterMode::SyncMode.with(2); - static constexpr auto Pause_Until_Hblank_Then_Freerun = CounterMode::SyncMode.with(3); + static constexpr auto Pause_During_Hblank = CounterMode_v::SyncMode.with(0u); + static constexpr auto Zero_At_Hblank = CounterMode_v::SyncMode.with(1u); + static constexpr auto Zero_At_Hblank_Pause_Outside_Hblank = CounterMode_v::SyncMode.with(2u); + static constexpr auto Pause_Until_Hblank_Then_Freerun = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto Dot_Clock = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(2); - static constexpr auto Dot_Clock_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto Dot_Clock = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(2u); + static constexpr auto Dot_Clock_Too = CounterMode_v::ClockSource.with(3u); }; }; - struct __no_align Counter1 : public Counter { + struct __no_align Counter1_v : public Counter { struct SyncMode { - static constexpr auto Pause_During_Vblank = CounterMode::SyncMode.with(0); - static constexpr auto Zero_At_Vblank = CounterMode::SyncMode.with(1); - static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = CounterMode::SyncMode.with(2); - static constexpr auto Pause_Until_Vblank_Then_Freerun = CounterMode::SyncMode.with(3); + static constexpr auto Pause_During_Vblank = CounterMode_v::SyncMode.with(0u); + static constexpr auto Zero_At_Vblank = CounterMode_v::SyncMode.with(1u); + static constexpr auto Zero_At_Vblank_Pause_Outside_Vblank = CounterMode_v::SyncMode.with(2u); + static constexpr auto Pause_Until_Vblank_Then_FreeRun = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto Hblank = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(2); - static constexpr auto Hblank_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto Hblank = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(2u); + static constexpr auto Hblank_Too = CounterMode_v::ClockSource.with(3u); }; }; - struct __no_align Counter2 : public Counter { + struct __no_align Counter2_v : public Counter { struct SyncMode { - static constexpr auto Stop_Counter = CounterMode::SyncMode.with(0); - static constexpr auto Freerun = CounterMode::SyncMode.with(1); - static constexpr auto Freerun_Too = CounterMode::SyncMode.with(2); - static constexpr auto Stop_Counter_Too = CounterMode::SyncMode.with(3); + static constexpr auto Stop_Counter = CounterMode_v::SyncMode.with(0u); + static constexpr auto FreeRun = CounterMode_v::SyncMode.with(1u); + static constexpr auto FreeRun_Too = CounterMode_v::SyncMode.with(2u); + static constexpr auto Stop_Counter_Too = CounterMode_v::SyncMode.with(3u); }; struct Source { - static constexpr auto System_Clock = CounterMode::ClockSource.with(0); - static constexpr auto System_Clock_Too = CounterMode::ClockSource.with(1); - static constexpr auto System_Clock_Div_8 = CounterMode::ClockSource.with(2); - static constexpr auto System_Clock_Div_8_Too = CounterMode::ClockSource.with(3); + static constexpr auto System_Clock = CounterMode_v::ClockSource.with(0u); + static constexpr auto System_Clock_Too = CounterMode_v::ClockSource.with(1u); + static constexpr auto System_Clock_Div_8 = CounterMode_v::ClockSource.with(2u); + static constexpr auto System_Clock_Div_8_Too = CounterMode_v::ClockSource.with(3u); }; }; - __declare_io_port_global_struct(struct Counter0, Counter0, counter_base_adr(0)); - __declare_io_port_global_struct(struct Counter1, Counter1, counter_base_adr(1)); - __declare_io_port_global_struct(struct Counter2, Counter2, counter_base_adr(2)); + __declare_new_io_port(Counter0, counter_base_adr(0)); + __declare_new_io_port(Counter1, counter_base_adr(1)); + __declare_new_io_port(Counter2, counter_base_adr(2)); } } diff --git a/include/PSX/Timer/high_res_timer.hpp b/include/PSX/Timer/high_res_timer.hpp index 7cb78e5c..9ae8141d 100644 --- a/include/PSX/Timer/high_res_timer.hpp +++ b/include/PSX/Timer/high_res_timer.hpp @@ -66,7 +66,7 @@ namespace JabyEngine { ~HighResTime() = delete; static TimeStamp get_time_stamp() { - return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.value.read(Timer_IO::CounterValue::Value)); + return TimeStamp(HighResTime::global_counter_10ms, Timer_IO::Counter2.get_current_value()); } }; #endif //JABYENGINE_USE_HIGH_PERCISION_TIMER diff --git a/src/Library/src/BootLoader/timer_boot.cpp b/src/Library/src/BootLoader/timer_boot.cpp index 0d348a79..201e41ba 100644 --- a/src/Library/src/BootLoader/timer_boot.cpp +++ b/src/Library/src/BootLoader/timer_boot.cpp @@ -18,7 +18,7 @@ void setup() { using namespace Timer_IO; - static constexpr auto Mode = CounterMode::with(CounterMode::FreeRun, Counter2::SyncMode::Freerun, CounterMode::ResetAfterTarget, CounterMode::IRQAtTarget, CounterMode::IRQEveryTime, CounterMode::IRQPulse, Counter2::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); Interrupt::disable_irq(Interrupt::Timer2); @@ -26,8 +26,8 @@ __syscall_SysEnqIntRP(Timer2Irq, &IRQCallback); __syscall_ExitCriticalSection(); - Counter2.target.write(CounterTarget::CounterTargetValue.with(HighResTime::TicksFor10ms)); - Counter2.mode.write({Mode}); + Counter2.set_target_value(HighResTime::TicksFor10ms); + Counter2.set_mode(Mode); Interrupt::enable_irq(Interrupt::Timer2); } From bc5164ce048bb1d99ab9b09cbec67f5584d273ba Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 18 Mar 2023 17:13:45 +0100 Subject: [PATCH 11/47] Converted SPU IO --- include/PSX/System/IOPorts/ioport.hpp | 32 ++--- include/PSX/System/IOPorts/spu_io.hpp | 158 ++++++++++++------------ src/Library/src/BootLoader/spu_boot.cpp | 53 ++++---- 3 files changed, 126 insertions(+), 117 deletions(-) diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 72880b16..8d24f618 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -52,18 +52,20 @@ namespace JabyEngine { typedef volatile T Value; }; - #define __declare_new_io_port(name, adr) \ - static auto& name = *reinterpret_cast(adr) + #define __declare_new_named_io_port(type, name, adr) \ + static inline auto& name = *reinterpret_cast(adr) -/*constexpr name##_io_base() = default; \ - \ - constexpr name##_io_base(type value) : raw_value(value) {} \ - \*/ + #define __declare_new_io_port(name, adr) \ + __declare_new_named_io_port(name, name, adr) + + #define __declare_new_io_port_array(name, adr, size) \ + static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) #define __declare_io_type(name, type, ...) \ template typename T> \ struct name##_io_base { \ T::Value raw_value = 0; \ + typedef name##_io_base Self; \ \ __VA_ARGS__ \ template \ @@ -173,12 +175,11 @@ namespace JabyEngine { }; struct __no_align ubus32_t { - typedef ComplexBitMap Base16; + __declare_io_type(uint16_t, uint16_t,); + uint16_t_v low; + uint16_t_v high; - VolatileBitMapPOD low; - VolatileBitMapPOD high; - - constexpr ubus32_t(uint32_t value) { + constexpr ubus32_t(uint32_t value) : low{0}, high{0} { *this = value; } @@ -187,12 +188,15 @@ namespace JabyEngine { } constexpr operator uint32_t() const { - return ((this->high.read_raw() << 16) | this->low.read_raw()); + const uint32_t high = *this->high; + const uint32_t low = *this->low; + + return ((high << 16) | low); } constexpr ubus32_t& operator=(uint32_t value) { - this->low.write_raw(value & 0xFFFF); - this->high.write_raw(value >> 16); + this->low = (value & 0xFFFF); + this->high = (value >> 16); return *this; } diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index 0e582749..b5451779 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -25,60 +25,64 @@ namespace JabyEngine { //0..3 = +7, +6, +5, +4 or -6, -7, -6, -5 typedef uint8_t Step; - typedef int16_t SimpleVolume; + typedef int16_t SimpleVolume; + typedef volatile int16_t SimpleVolume_v; - struct SampleRate : public ComplexBitMap { - static constexpr SampleRate from_HZ(double freq) { + typedef volatile uint16_t Adr_v; + typedef volatile uint16_t DataTransferControl_v; + + __declare_io_type(SampleRate, uint16_t, + static constexpr Self from_HZ(double freq) { //4096 == 44100Hz constexpr double Base = (4096.0 / 44100.0); return {static_cast((freq*Base))}; } - }; + ); - struct SweepVolume : public ComplexBitMap { + __declare_io_type(SweepVolume, int16_t, // For Volume Mode - static constexpr auto SweepEnable = Bit(15); + static constexpr auto SweepEnable = IOBitSet(15); static constexpr auto VolumeEnable = !SweepEnable; - static constexpr auto Volume = BitRange::from_to(0, 14); + static constexpr auto Volume = IOValueSet::from_to(0, 14); // For Sweep Mode - static constexpr auto SweepMode = Bit(14); - static constexpr auto SweepDirection = Bit(13); - static constexpr auto SweepPhase = Bit(12); - static constexpr auto SweepShift = BitRange::from_to(2, 6); - static constexpr auto SweepStep = BitRange::from_to(0, 1); + static constexpr auto SweepMode = IOBitSet(14); + static constexpr auto SweepDirection = IOBitSet(13); + static constexpr auto SweepPhase = IOBitSet(12); + static constexpr auto SweepShift = IOValueSet::from_to(2, 6); + static constexpr auto SweepStep = IOValueSet::from_to(0, 1); + ); + + __declare_io_type(SR, uint16_t, + static constexpr auto SustainMode = IOBitSet(31 - 16); + static constexpr auto SustainDirection = IOBitSet(30 - 16); + static constexpr auto SustainShift = IOValueSet::from_to((24 - 16), (28 - 16)); + static constexpr auto SustainStep = IOValueSet::from_to((22 - 16), (23 - 16)); + static constexpr auto ReleaseMode = IOBitSet(21 - 16); + static constexpr auto ReleaseShift = IOValueSet::from_to((16 - 16), (20 - 16)); + ); + + __declare_io_type(AD, uint16_t, + static constexpr auto AttackMode = IOBitSet(15); + static constexpr auto AttackShift = IOValueSet::from_to(10, 14); + static constexpr auto AttackStep = IOValueSet::from_to(8, 9); + static constexpr auto DecayShift = IOValueSet::from_to(4, 7); + static constexpr auto SustainLevel = IOValueSet::from_to(0, 3); + ); + + struct __no_align Voice_v { + SweepVolume_v volumeLeft; //Offset: 0x0 + SweepVolume_v volumeRight; //Offset: 0x2 + SampleRate_v sampleRate; //Offset: 0x4; + Adr_v adr; //Offset: 0x6 + AD_v ad; //Offset: 0x8 + SR_v sr; //Offset: 0xA + SimpleVolume_v currentVolume; //Offset: 0xC + Adr_v repeatAdr; //Offset: 0xE }; - struct SR : public ComplexBitMap { - static constexpr auto SustainMode = Bit(31 - 16); - static constexpr auto SustainDirection = Bit(30 - 16); - static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16)); - static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16)); - static constexpr auto ReleaseMode = Bit(21 - 16); - static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); - }; - - struct AD : public ComplexBitMap { - static constexpr auto AttackMode = Bit(15); - static constexpr auto AttackShift = BitRange::from_to(10, 14); - static constexpr auto AttackStep = BitRange::from_to(8, 9); - static constexpr auto DecayShift = BitRange::from_to(4, 7); - static constexpr auto SustainLevel = BitRange::from_to(0, 3); - }; - - struct __no_align Voice { - VolatileBitMapPOD volumeLeft; //Offset: 0x0 - VolatileBitMapPOD volumeRight; //Offset: 0x2 - VolatileBitMapPOD sampleRate; //Offset: 0x4; - VolatilePOD adr; //Offset: 0x6 - VolatileBitMapPOD ad; //Offset: 0x8 - VolatileBitMapPOD sr; //Offset: 0xA - VolatilePOD currentVolume; //Offset: 0xC - VolatilePOD repeatAdr; //Offset: 0xE - }; - - struct ControlRegister : public ComplexBitMap { + __declare_io_type(ControlRegister, uint16_t, enum RAMTransferMode { Stop = 0, ManualWrite = 1, @@ -86,30 +90,30 @@ namespace JabyEngine { DMARead = 3 }; - static constexpr auto Enable = Bit(15); - static constexpr auto Unmute = Bit(14); - static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13); - static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9); - static constexpr auto ReverbMasterEnable = Bit(7); - static constexpr auto IRQ9Enable = Bit(6); - static constexpr auto TransferMode = BitRange::from_to(4, 5); - static constexpr auto ExternalAudioReverb = Bit(3); - static constexpr auto CDAudioReverb = Bit(2); - static constexpr auto ExternalAudioEnable = Bit(1); - static constexpr auto CDAudioEnable = Bit(0); - }; + static constexpr auto Enable = IOBitSet(15); + static constexpr auto Unmute = IOBitSet(14); + static constexpr auto NoiseFrequcenyShift = IOValueSet::from_to(10, 13); + static constexpr auto NoiseFrequcenyStep = IOValueSet::from_to(8, 9); + static constexpr auto ReverbMasterEnable = IOBitSet(7); + static constexpr auto IRQ9Enable = IOBitSet(6); + static constexpr auto TransferMode = IOValueSet::from_to(4, 5); + static constexpr auto ExternalAudioReverb = IOBitSet(3); + static constexpr auto CDAudioReverb = IOBitSet(2); + static constexpr auto ExternalAudioEnable = IOBitSet(1); + static constexpr auto CDAudioEnable = IOBitSet(0); + ); - struct PitchModFlags : public ComplexBitMap { - static constexpr BitRange EnableBits = BitRange::from_to(1, 23); - }; + __declare_io_type(PMON, uint16_t, + static constexpr auto EnableBits = IOValueSet::from_to(1, 23); + ); - struct NoiseGenerator : public ComplexBitMap { - static constexpr BitRange NoiseBits = BitRange::from_to(0, 23); - }; + __declare_io_type(NON, uint16_t, + static constexpr auto NoiseBits = IOValueSet::from_to(0, 23); + ); - struct EchoOn : public ComplexBitMap { - static constexpr BitRange EchoBits = BitRange::from_to(0, 23); - }; + __declare_io_type(EON, uint16_t, + static constexpr auto EchoBits = IOValueSet::from_to(0, 23); + ); static constexpr size_t VoiceCount = 24; @@ -120,35 +124,35 @@ namespace JabyEngine { }; struct MainVolume { - __declare_io_port_member(SweepVolume, Left, 0x1F801D80); - __declare_io_port_member(SweepVolume, Right, 0x1F801D82); + __declare_new_named_io_port(SweepVolume, Left, 0x1F801D80); + __declare_new_named_io_port(SweepVolume, Right, 0x1F801D82); }; struct CDVolume { - __declare_io_port_member_simple(SimpleVolume, Left, 0x1F801DB0); - __declare_io_port_member_simple(SimpleVolume, Right, 0x1F801DB2); + __declare_new_named_io_port(SimpleVolume, Left, 0x1F801DB0); + __declare_new_named_io_port(SimpleVolume, Right, 0x1F801DB2); }; struct ExternalAudioInputVolume { - __declare_io_port_member_simple(SimpleVolume, Left, 0x1F801DB4); - __declare_io_port_member_simple(SimpleVolume, Right, 0x1F801DB6); + __declare_new_named_io_port(SimpleVolume, Left, 0x1F801DB4); + __declare_new_named_io_port(SimpleVolume, Right, 0x1F801DB6); }; struct Reverb { struct Volume { - __declare_io_port_member_simple(SimpleVolume, Left, 0x1F801D84); - __declare_io_port_member_simple(SimpleVolume, Right, 0x1F801D86); + __declare_new_named_io_port(SimpleVolume, Left, 0x1F801D84); + __declare_new_named_io_port(SimpleVolume, Right, 0x1F801D86); }; - __declare_io_port_member_simple(uint16_t, WorkAreaAdr, 0x1F801DA2); + __declare_new_named_io_port(Adr, WorkAreaAdr, 0x1F801DA2); }; - __declare_io_port_global(ControlRegister, Control, 0x1F801DAA); - __declare_io_port_global_simple(uint16_t, DataTransferControl, 0x1F801DAC); - __declare_io_port_global(PitchModFlags, PMON, 0x1F801D90); - __declare_io_port_global(NoiseGenerator, NON, 0x1F801D94); - __declare_io_port_global(EchoOn, EON, 0x1F801D98); + __declare_new_io_port(ControlRegister, 0x1F801DAA); + __declare_new_io_port(DataTransferControl, 0x1F801DAC); + __declare_new_io_port(PMON, 0x1F801D90); + __declare_new_io_port(NON, 0x1F801D94); + __declare_new_io_port(EON, 0x1F801D98); - __declare_io_port_global_array(struct Voice, Voice, 0x1F801C00, VoiceCount); + __declare_new_io_port_array(Voice, 0x1F801C00, VoiceCount); } } #endif //!__JABYENGINE_SPU_IO_HPP__ \ No newline at end of file diff --git a/src/Library/src/BootLoader/spu_boot.cpp b/src/Library/src/BootLoader/spu_boot.cpp index 9521352b..b3f779b4 100644 --- a/src/Library/src/BootLoader/spu_boot.cpp +++ b/src/Library/src/BootLoader/spu_boot.cpp @@ -6,65 +6,66 @@ namespace JabyEngine { namespace boot { namespace SPU { using namespace JabyEngine; + using namespace SPU_IO; static void clear_main_volume() { - static constexpr auto StartVol = SPU_IO::SweepVolume::with(SPU_IO::SweepVolume::VolumeEnable, SPU_IO::SweepVolume::Volume.with(I16_MAX >> 2)); + static constexpr auto StartVol = SweepVolume_t::from(SweepVolume_t::VolumeEnable, SweepVolume_t::Volume.with(static_cast(I16_MAX >> 2))); - SPU_IO::MainVolume::Left.write({StartVol}); - SPU_IO::MainVolume::Right.write({StartVol}); + MainVolume::Left = *StartVol; + MainVolume::Right = *StartVol; } static void clear_cd_and_ext_audio_volume() { - SPU_IO::CDVolume::Left.write(0); - SPU_IO::CDVolume::Right.write(0); + CDVolume::Left = 0; + CDVolume::Right = 0; - SPU_IO::ExternalAudioInputVolume::Left.write(0); - SPU_IO::ExternalAudioInputVolume::Right.write(0); + ExternalAudioInputVolume::Left = 0; + ExternalAudioInputVolume::Right = 0; } static void clear_control_register() { - SPU_IO::Control.write(SPU_IO::ControlRegister()); + ControlRegister = 0; } static void clear_voice() { for(auto& voice : SPU_IO::Voice) { - voice.volumeLeft.write(SPU_IO::SweepVolume()); - voice.volumeRight.write(SPU_IO::SweepVolume()); - voice.sampleRate.write(SPU_IO::SampleRate()); - voice.ad.write(SPU_IO::AD()); - voice.sr.write(SPU_IO::SR()); - voice.currentVolume.write(SPU_IO::SimpleVolume(0)); + voice.volumeLeft = *SweepVolume_t(); + voice.volumeRight = *SweepVolume_t(); + voice.sampleRate = *SampleRate_t(); + voice.ad = *AD_t(); + voice.sr = *SR_t(); + voice.currentVolume = 0; - voice.adr.write(0x200); - voice.repeatAdr.write(0x200); + voice.adr = 0x200; + voice.repeatAdr = 0x200; } } static void clear_pmon() { - SPU_IO::PMON.write(SPU_IO::PitchModFlags()); + SPU_IO::PMON = *PMON_t(); } static void clear_noise_and_echo() { - SPU_IO::NON.write(SPU_IO::NoiseGenerator()); - SPU_IO::EON.write(SPU_IO::EchoOn()); + SPU_IO::NON = *NON_t(); + SPU_IO::EON = *EON_t(); } static void clear_reverb() { - SPU_IO::Reverb::Volume::Left.write(0); - SPU_IO::Reverb::Volume::Right.write(0); - SPU_IO::Reverb::WorkAreaAdr.write(0); + Reverb::Volume::Left = 0; + Reverb::Volume::Right = 0; + Reverb::WorkAreaAdr = 0; } static void setup_control_register() { - static constexpr auto SetupValue = SPU_IO::ControlRegister::with(SPU_IO::ControlRegister::Enable, SPU_IO::ControlRegister::Unmute, SPU_IO::ControlRegister::CDAudioEnable); + static constexpr auto SetupValue = ControlRegister_t::from(ControlRegister_t::Enable, ControlRegister_t::Unmute, ControlRegister_t::CDAudioEnable); - SPU_IO::Control.write({SetupValue}); + SPU_IO::ControlRegister = *SetupValue; } static void setup_data_transfer_control() { static constexpr uint16_t RequiredValue = (2 << 1); - SPU_IO::DataTransferControl.write(RequiredValue); + DataTransferControl = RequiredValue; } static void wait_voices() { @@ -72,7 +73,7 @@ namespace JabyEngine { try_again: for(const auto& voice : SPU_IO::Voice) { - if(voice.currentVolume.read() > Treshhold) { + if(voice.currentVolume > Treshhold) { goto try_again; } } From 69b886e67703d6ed858d07c3173c0bf0af76550d Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 20 Mar 2023 17:53:20 +0100 Subject: [PATCH 12/47] Port InterruptIOs --- include/PSX/System/IOPorts/interrupt_io.hpp | 50 ++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/PSX/System/IOPorts/interrupt_io.hpp b/include/PSX/System/IOPorts/interrupt_io.hpp index 4e2556b8..4586d619 100644 --- a/include/PSX/System/IOPorts/interrupt_io.hpp +++ b/include/PSX/System/IOPorts/interrupt_io.hpp @@ -4,42 +4,42 @@ namespace JabyEngine { struct Interrupt { - static constexpr auto VBlank = Bit(0); - static constexpr auto GPU = Bit(1); - static constexpr auto CDROM = Bit(2); - static constexpr auto DMA = Bit(3); - static constexpr auto Timer0 = Bit(4); - static constexpr auto Timer1 = Bit(5); - static constexpr auto Timer2 = Bit(6); - static constexpr auto Periphery = Bit(7); - static constexpr auto SIO = Bit(8); - static constexpr auto SPU = Bit(9); - static constexpr auto Controller = Bit(10); + static constexpr auto VBlank = IOBitSet(0); + static constexpr auto GPU = IOBitSet(1); + static constexpr auto CDROM = IOBitSet(2); + static constexpr auto DMA = IOBitSet(3); + static constexpr auto Timer0 = IOBitSet(4); + static constexpr auto Timer1 = IOBitSet(5); + static constexpr auto Timer2 = IOBitSet(6); + static constexpr auto Periphery = IOBitSet(7); + static constexpr auto SIO = IOBitSet(8); + static constexpr auto SPU = IOBitSet(9); + static constexpr auto Controller = IOBitSet(10); static constexpr auto LightPen = Controller; - typedef struct Status : public ComplexBitMap { - } Status_t; + __declare_io_type(Status, uint32_t, + ); - typedef struct Mask : public ComplexBitMap { - } Mask_t; + __declare_io_type(Mask, uint32_t, + ); - __declare_io_port_member(Status_t, Status, 0x1F801070); - __declare_io_port_member(Mask_t, Mask, 0x1F801074); + __declare_new_io_port(Status, 0x1F801070); + __declare_new_io_port(Mask, 0x1F801074); - static bool is_irq(Bit irq) { - return Status.read().is_bit_set(irq); + static constexpr bool is_irq(IOBitSet irq) { + return Status.is_set(irq); } - static void ack_irq(Bit irq) { - Status.write({Status.read().clear_bit(irq)}); + static constexpr void ack_irq(IOBitSet irq) { + Status.clear(irq); } - static void disable_irq(Bit irq) { - Mask.write({Mask.read().clear_bit(irq)}); + static constexpr void disable_irq(IOBitSet irq) { + Mask.clear(irq); } - static void enable_irq(Bit irq) { - Mask.write({Mask.read().set_bit(irq)}); + static void enable_irq(IOBitSet irq) { + Mask.set(irq); } }; } From 9243a3a17f5a2c9f72d5ddf1d9975a00887a20fb Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 20 Mar 2023 19:06:28 +0100 Subject: [PATCH 13/47] Port GPU IOs --- include/PSX/GPU/gpu.hpp | 4 +- include/PSX/System/IOPorts/gpu_io.hpp | 252 +++++++++++++---------- include/PSX/System/IOPorts/ioport.hpp | 8 +- src/Library/include/GPU/gpu_internal.hpp | 61 ++---- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/GPU/gpu.cpp | 10 +- 6 files changed, 173 insertions(+), 164 deletions(-) diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 2960d8e3..5952091a 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -22,11 +22,11 @@ namespace JabyEngine { #endif static void enable() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::On)); + GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On); } static void disable() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::SetDisplayState(GPU_IO::DisplayState::Off)); + GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off); } }; diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index b5f4bf0c..9e21b3a3 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -47,124 +47,162 @@ namespace JabyEngine { Off = 1 }; - struct Command { - struct GP0 : public ComplexBitMap { - - static constexpr GP0 QuickFill(GPU::Color24 color) { - return {(0x02 << 24) | color.raw()}; - } - - static constexpr GP0 CPU2VRAM_Blitting() { - return {(0b101u << 29)}; - } - - static constexpr GP0 DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { - constexpr auto Command = BitRange::from_to(24, 31); - constexpr auto Y = BitRange::from_to(10, 18); - constexpr auto X = BitRange::from_to(0, 9); - - return {GP0::with(Command.with(code), Y.with(y), X.with(x))}; - } - - static constexpr GP0 DrawAreaTopLeft(uint16_t x, uint16_t y) { - return DrawAreaTemplate(0xE3, x, y); - } - - static constexpr GP0 DrawAreaBottomRight(uint16_t x, uint16_t y) { - return DrawAreaTemplate(0xE4, x, y); - } - - static constexpr GP0 TopLeftPosition(uint16_t x, uint16_t y) { - return {static_cast((y << 16u) | x)}; - } - - static constexpr GP0 WidthHeight(uint16_t w, uint16_t h) { - return {static_cast((h << 16u) | w)}; - } + __declare_io_type(DisplayMode, uint32_t, + enum struct TVEncoding { + NTSC = 0, + PAL = 1, }; - struct GP1 : public ComplexBitMap { + static constexpr auto HorizontalResolution368 = IOBitSet(6); + static constexpr auto VerticalInterlace = IOBitSet(5); + static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(4, 4); + static constexpr auto VideoMode = IOValueSet::from_to(3, 3); + static constexpr auto VerticalResolution = IOValueSet::from_to(2, 2); + static constexpr auto HorizontalResolution = IOValueSet::from_to(0, 1); + + static constexpr Self PAL() { + return Self::from( + HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), + VerticalResolution.with(GPU_IO::VerticalResolution::$240), + VideoMode.with(TVEncoding::PAL), + DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) + ); + } + + static constexpr Self NTSC() { + return Self::from( + HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), + VerticalResolution.with(GPU_IO::VerticalResolution::$240), + VideoMode.with(TVEncoding::NTSC), + DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) + ); + } + ); + + __declare_io_type(GP0, uint32_t, + ); + + __declare_io_type(GP1, uint32_t, + ); + + + struct Command { + struct Helper { + static constexpr GP0_t DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { + constexpr auto Command = IOValueSet::from_to(24, 31); + constexpr auto Y = IOValueSet::from_to(10, 18); + constexpr auto X = IOValueSet::from_to(0, 9); + + return GP0_t::from(Command.with(code), Y.with(y), X.with(x)); + } + static constexpr uint32_t construct_cmd(uint8_t cmd, uint32_t value) { return ((cmd << 24) | value); } - - static constexpr GP1 Reset() { - return {0}; - } - - static constexpr GP1 ResetCMDBufer() { - return {construct_cmd(0x01, 0)}; - } - - static constexpr GP1 SetDisplayState(DisplayState state) { - return {construct_cmd(0x03, static_cast(state))}; - } - - static constexpr GP1 DMADirection(DMADirection dir) { - return {construct_cmd(0x04, static_cast(dir))}; - } - - static constexpr GP1 DisplayArea(uint16_t x, uint16_t y) { - constexpr auto X = BitRange::from_to(0, 9); - constexpr auto Y = BitRange::from_to(10, 18); - - return {construct_cmd(0x05, ComplexBitMap::with(X.with(x), Y.with(y)).raw)}; - } - - static constexpr GP1 HorizontalDisplayRange(uint32_t x1, uint32_t x2) { - constexpr auto X1 = BitRange::from_to(0, 11); - constexpr auto X2 = BitRange::from_to(12, 23); - - return {construct_cmd(0x06, ComplexBitMap::with(X1.with(x1), X2.with(x2)).raw)}; - } - - static constexpr GP1 VerticalDisplayRange(uint32_t y1, uint32_t y2) { - constexpr auto Y1 = BitRange::from_to(0, 9); - constexpr auto Y2 = BitRange::from_to(10, 19); - - return {construct_cmd(0x07, ComplexBitMap::with(Y1.with(y1), Y2.with(y2)).raw)}; - } - - static constexpr GP1 DisplayMode(uint32_t mode) { - return {construct_cmd(0x08, mode)}; - } }; + + static constexpr GP0_t QuickFill(GPU::Color24 color) { + return {(0x02 << 24) | color.raw()}; + } + + static constexpr GP0_t CPU2VRAM_Blitting() { + return {(0b101u << 29)}; + } + + static constexpr GP0_t DrawAreaTopLeft(uint16_t x, uint16_t y) { + return Helper::DrawAreaTemplate(0xE3, x, y); + } + + static constexpr GP0_t DrawAreaBottomRight(uint16_t x, uint16_t y) { + return Helper::DrawAreaTemplate(0xE4, x, y); + } + + static constexpr GP0_t TopLeftPosition(uint16_t x, uint16_t y) { + return {static_cast((y << 16u) | x)}; + } + + static constexpr GP0_t WidthHeight(uint16_t w, uint16_t h) { + return {static_cast((h << 16u) | w)}; + } + + static constexpr GP1_t Reset() { + return {0}; + } + + static constexpr GP1_t ResetCMDBufer() { + return {Helper::construct_cmd(0x01, 0)}; + } + + static constexpr GP1_t SetDisplayState(DisplayState state) { + return {Helper::construct_cmd(0x03, static_cast(state))}; + } + + static constexpr GP1_t DMADirection(DMADirection dir) { + return {Helper::construct_cmd(0x04, static_cast(dir))}; + } + + static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { + constexpr auto X = BitRange::from_to(0, 9); + constexpr auto Y = BitRange::from_to(10, 18); + + return {Helper::construct_cmd(0x05, ComplexBitMap::with(X.with(x), Y.with(y)).raw)}; + } + + static constexpr GP1_t HorizontalDisplayRange(uint32_t x1, uint32_t x2) { + constexpr auto X1 = BitRange::from_to(0, 11); + constexpr auto X2 = BitRange::from_to(12, 23); + + return {Helper::construct_cmd(0x06, ComplexBitMap::with(X1.with(x1), X2.with(x2)).raw)}; + } + + static constexpr GP1_t VerticalDisplayRange(uint32_t y1, uint32_t y2) { + constexpr auto Y1 = BitRange::from_to(0, 9); + constexpr auto Y2 = BitRange::from_to(10, 19); + + return {Helper::construct_cmd(0x07, ComplexBitMap::with(Y1.with(y1), Y2.with(y2)).raw)}; + } + + static constexpr GP1_t DisplayMode(DisplayMode_t mode) { + return {Helper::construct_cmd(0x08, *mode)}; + } }; - struct GPUStatusRegister : public ComplexBitMap { - static constexpr auto DrawingOddLinesInterlaced = Bit(31); - static constexpr auto DMADirectionValue = BitRange::from_to(29, 30); - static constexpr auto DMAReady = Bit(28); - static constexpr auto VRAMtoCPUtransferReay = Bit(27); - static constexpr auto GP0ReadyForCMD = Bit(26); - static constexpr auto FifoNotFull = Bit(25); // Only for Fifo - static constexpr auto InterruptRequest = Bit(24); - static constexpr auto DisplayDisabled = Bit(23); - static constexpr auto VerticalInterlaceOn = Bit(22); - static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21); - static constexpr auto VideoModePal = Bit(20); - static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19); - static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18); - static constexpr auto HorizontalResolution368 = Bit(16); - static constexpr auto TexturesDisabled = Bit(15); - static constexpr auto NotDrawingMaskedPixels = Bit(12); - static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11); - static constexpr auto DrawingToDisplayAreadAllowed = Bit(10); - static constexpr auto DitherEnabled = Bit(9); - static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8); - static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6); - static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256 - static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64 + __declare_io_type(GPUSTAT, uint32_t, + static constexpr auto DrawingOddLinesInterlaced = IOBitSet(31); + static constexpr auto DMADirectionValue = IOValueSet::from_to(29, 30); + static constexpr auto DMAReady = IOBitSet(28); + static constexpr auto VRAMtoCPUtransferReay = IOBitSet(27); + static constexpr auto GP0ReadyForCMD = IOBitSet(26); + static constexpr auto FifoNotFull = IOBitSet(25); // Only for Fifo + static constexpr auto InterruptRequest = IOBitSet(24); + static constexpr auto DisplayDisabled = IOBitSet(23); + static constexpr auto VerticalInterlaceOn = IOBitSet(22); + static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(21, 21); + static constexpr auto VideoModePal = IOBitSet(20); + static constexpr auto VerticalResolutionValue = IOValueSet::from_to(19, 19); + static constexpr auto HorizontalResolutionValue = IOValueSet::from_to(17, 18); + static constexpr auto HorizontalResolution368 = IOBitSet(16); + static constexpr auto TexturesDisabled = IOBitSet(15); + static constexpr auto NotDrawingMaskedPixels = IOBitSet(12); + static constexpr auto MaskBitSetDuringDrawEnabled = IOBitSet(11); + static constexpr auto DrawingToDisplayAreadAllowed = IOBitSet(10); + static constexpr auto DitherEnabled = IOBitSet(9); + static constexpr auto TexturePageColorValue = IOValueSet::from_to(7, 8); + static constexpr auto SemiTransparencyValue = IOValueSet::from_to(5, 6); + static constexpr auto TexturePageY = IOValueSet::from_to(4, 4); // N*256 + static constexpr auto TexturePageX = IOValueSet::from_to(0, 3); // N*64 - static constexpr auto VerticalResolution480 = Bit(19); - static constexpr auto TexturePageY256 = Bit(4); - }; + static constexpr auto VerticalResolution480 = IOBitSet(19); + static constexpr auto TexturePageY256 = IOBitSet(4); + ); - __declare_io_port_global(Command::GP0, GP0, 0x1F801810); - __declare_io_port_global(Command::GP1, GP1, 0x1F801814); + typedef volatile uint32_t GPUREAD_v; - __declare_io_port_global_const_simple(uint32_t, GPUREAD, 0x1F801810); - __declare_io_port_global_const(GPUStatusRegister, GPUSTAT, 0x1F801814); + __declare_new_io_port(GP0, 0x1F801810); + __declare_new_io_port(GP1, 0x1F801814); + + __declare_new_const_io_port(GPUREAD, 0x1F801810); + __declare_new_const_io_port(GPUSTAT, 0x1F801814); } } #endif //!__JABYENGINE_GPU_IO_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 8d24f618..c3132268 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -57,6 +57,9 @@ namespace JabyEngine { #define __declare_new_io_port(name, adr) \ __declare_new_named_io_port(name, name, adr) + + #define __declare_new_const_io_port(name, adr) \ + __declare_new_named_io_port(const name, name, adr) #define __declare_new_io_port_array(name, adr, size) \ static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) @@ -88,8 +91,9 @@ namespace JabyEngine { return *this; \ } \ \ - constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ - this->set(value.first, value.second); \ + template \ + constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ + this->set(value.first, static_cast(value.second)); \ return *this; \ } \ \ diff --git a/src/Library/include/GPU/gpu_internal.hpp b/src/Library/include/GPU/gpu_internal.hpp index 7d2b89e2..fd042bca 100644 --- a/src/Library/include/GPU/gpu_internal.hpp +++ b/src/Library/include/GPU/gpu_internal.hpp @@ -8,50 +8,18 @@ namespace JabyEngine { namespace GPU { namespace internal { struct Screen { - struct Mode { - enum struct TVEncoding { - NTSC = 0, - PAL = 1, - }; - - static constexpr auto HorizontalResolution368 = Bit(6); - static constexpr auto VerticalInterlace = Bit(5); - static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4); - static constexpr auto VideoMode = BitRange::from_to(3, 3); - static constexpr auto VerticalResolution = BitRange::from_to(2, 2); - static constexpr auto HorizontalResolution = BitRange::from_to(0, 1); - - static constexpr uint32_t PAL() { - return ComplexBitMap::with( - Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), - Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240), - Mode::VideoMode.with(TVEncoding::PAL), - Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) - ).raw; - } - - static constexpr uint32_t NTSC() { - return ComplexBitMap::with( - Mode::HorizontalResolution.with(GPU_IO::HorizontalResolution::$320), - Mode::VerticalResolution.with(GPU_IO::VerticalResolution::$240), - Mode::VideoMode.with(TVEncoding::NTSC), - Mode::DisplayAreaColorDepth.with(GPU_IO::DisplayAreaColorDepth::$15bit) - ).raw; - } - }; - static void configurate() { static constexpr uint16_t FirstVisiblePixelH = 0x260; #ifdef JABYENGINE_PAL static constexpr uint16_t FirstVisiblePixelV = 0xA3; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::PAL())); + GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL()); GPU::Screen::set_offset(0, 0); #else static constexpr uint16_t FirstVisiblePixelV = 0x88; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayMode(Mode::NTSC())); + GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC()); GPU::Screen::set_offset(0, 5); //< Random values #endif } @@ -60,22 +28,22 @@ namespace JabyEngine { }; static void set_draw_area(uint16_t x, uint16_t y) { - GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaTopLeft(x, y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::DrawAreaBottomRight((x + Display::Width), (y + Display::Height))); + GPU_IO::GP0 = *GPU_IO::Command::DrawAreaTopLeft(x, y); + GPU_IO::GP0 = *GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); } static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { - GPU_IO::GP0.write(GPU_IO::Command::GP0::QuickFill(color)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(pos.x, pos.y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height)); + GPU_IO::GP0 = *GPU_IO::Command::QuickFill(color); + GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(pos.x, pos.y); + GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); } static void reset_cmd_buffer() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::ResetCMDBufer()); + GPU_IO::GP1 = *GPU_IO::Command::ResetCMDBufer(); } static void wait_ready_for_CMD() { - while(!GPU_IO::GPUSTAT.read().is(GPU_IO::GPUStatusRegister::GP0ReadyForCMD)); + while(!GPU_IO::GPUSTAT.is_set(GPU_IO::GPUSTAT_t::GP0ReadyForCMD)); } namespace DMA { @@ -88,9 +56,8 @@ namespace JabyEngine { } namespace Receive { - static void prepare() - { - GPU_IO::GP1.write(GPU_IO::Command::GP1::DMADirection(GPU_IO::DMADirection::CPU2GPU)); + static void prepare() { + GPU_IO::GP1 = *GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU); reset_cmd_buffer(); } @@ -100,9 +67,9 @@ namespace JabyEngine { static void set_dst(const PositionU16& position, const SizeU16& size) { wait_ready_for_CMD(); - GPU_IO::GP0.write(GPU_IO::Command::GP0::CPU2VRAM_Blitting()); - GPU_IO::GP0.write(GPU_IO::Command::GP0::TopLeftPosition(position.x, position.y)); - GPU_IO::GP0.write(GPU_IO::Command::GP0::WidthHeight(size.width, size.height)); + GPU_IO::GP0 = *GPU_IO::Command::CPU2VRAM_Blitting(); + GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(position.x, position.y); + GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 9f4eca69..064961f8 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -49,7 +49,7 @@ namespace JabyEngine { } void setup() { - GPU_IO::GP1.write(GPU_IO::Command::GP1::Reset()); + GPU_IO::GP1 = *GPU_IO::Command::Reset(); internal::Screen::configurate(); internal::Screen::exchange_buffer_and_display(); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 31a1cc91..6474edf0 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -16,7 +16,7 @@ namespace JabyEngine { void Screen :: exchange_buffer_and_display() { GPU::internal::set_draw_area(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); PublicScreenClass::CurrentDisplayAreaID ^= 1; - GPU_IO::GP1.write(GPU_IO::Command::GP1::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID))); + GPU_IO::GP1 = *GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); } } @@ -25,13 +25,13 @@ namespace JabyEngine { x += 78; y += 43; - GPU_IO::GP1.write(GPU_IO::Command::GP1::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3)); - GPU_IO::GP1.write(GPU_IO::Command::GP1::VerticalDisplayRange(y, y + Display::Height)); + GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3); + GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height); } #else void Screen :: set_offset(uint16_t x, uint16_t y) { - GP1.write(Command::GP1::HorizontalDisplayRange(x, (x + Display::Width*8))); - GP1.write(Command::GP1::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2))); + GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8)); + GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)); } #endif //USE_NO$PSX } From 44685184f88c54c0b9709e91135b9a6797d7fad1 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 20 Mar 2023 21:04:01 +0100 Subject: [PATCH 14/47] Port DMA code --- include/PSX/System/IOPorts/dma_io.hpp | 151 ++++++++++++---------- include/PSX/System/IOPorts/ioport.hpp | 1 - src/Library/include/GPU/gpu_internal.hpp | 10 +- src/Library/src/BootLoader/start_boot.cpp | 4 +- 4 files changed, 92 insertions(+), 74 deletions(-) diff --git a/include/PSX/System/IOPorts/dma_io.hpp b/include/PSX/System/IOPorts/dma_io.hpp index 7a48a58f..8af6a4f8 100644 --- a/include/PSX/System/IOPorts/dma_io.hpp +++ b/include/PSX/System/IOPorts/dma_io.hpp @@ -4,130 +4,147 @@ namespace JabyEngine { namespace DMA_IO { - struct MADR : public ComplexBitMap { - static constexpr auto MemoryAdr = BitRange::from_to(0, 23); - }; + __declare_io_type(MADR, uint32_t, + static constexpr auto MemoryAdr = IOValueSet::from_to(0, 23); + ); - struct BCR : public ComplexBitMap { + __declare_io_type(BCR, uint32_t, struct __no_align SyncMode0 { - static constexpr auto NumberOfWords = BitRange::from_to(0, 15); - static constexpr auto CD_OneBlock = Bit(16); + static constexpr auto NumberOfWords = IOValueSet::from_to(0, 15); + static constexpr auto CD_OneBlock = IOBitSet(16); }; struct SyncMode1 : public ComplexBitMap { - static constexpr auto BlockSize = BitRange::from_to(0, 15); - static constexpr auto BlockAmount = BitRange::from_to(16, 31); + static constexpr auto BlockSize = IOValueSet::from_to(0, 15); + static constexpr auto BlockAmount = IOValueSet::from_to(16, 31); }; struct SyncMode2 { }; - }; + ); - struct CHCHR : public ComplexBitMap { - enum _SyncMode { + __declare_io_type(CHCHR, uint32_t, + enum SyncMode_t { Sync0 = 0, //Start immediately, Sync1 = 1, //Sync blocks to DMA requests Sync2 = 2, //Linked List }; - static constexpr auto ManualStart = Bit(28); + static constexpr auto ManualStart = IOBitSet(28); - static constexpr auto Start = Bit(24); + static constexpr auto Start = IOBitSet(24); static constexpr auto Busy = Start; - static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22); - static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18); + static constexpr auto ChoppingCPUWindowSize = IOValueSet::from_to(20, 22); + static constexpr auto ChoppingDMAWindowSize = IOValueSet::from_to(16, 18); - static constexpr auto SyncMode = BitRange<_SyncMode>::from_to(9, 10); + static constexpr auto SyncMode = IOValueSet::from_to(9, 10); static constexpr auto UseSyncMode0 = SyncMode.with(Sync0); static constexpr auto UseSyncMode1 = SyncMode.with(Sync1); static constexpr auto UseSyncMode2 = SyncMode.with(Sync2); - static constexpr auto UseChopping = Bit(8); + static constexpr auto UseChopping = IOBitSet(8); - static constexpr auto MemoryAdrDecreaseBy4 = Bit(1); + static constexpr auto MemoryAdrDecreaseBy4 = IOBitSet(1); static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; - static constexpr auto FromMainRAM = Bit(0); + static constexpr auto FromMainRAM = IOBitSet(0); static constexpr auto ToMainRAM = !FromMainRAM; - static constexpr CHCHR StartMDECin() { - return CHCHR{0x01000201}; + static constexpr Self StartMDECin() { + return Self{0x01000201}; } - static constexpr CHCHR StartMDECout() { - return CHCHR{0x01000200}; + static constexpr Self StartMDECout() { + return Self{0x01000200}; } - static constexpr CHCHR StartGPUReceive() { - return CHCHR{0x01000201}; + static constexpr Self StartGPUReceive() { + return Self{0x01000201}; } - static constexpr CHCHR StartCDROM() { - return CHCHR{0x11000000}; + static constexpr Self StartCDROM() { + return Self{0x11000000}; } - static constexpr CHCHR StartSPUReceive() { - return CHCHR{0x01000201}; + static constexpr Self StartSPUReceive() { + return Self{0x01000201}; } - static constexpr CHCHR StartOTC() { - return CHCHR{0x11000002}; + static constexpr Self StartOTC() { + return Self{0x11000002}; } - }; + ); struct __no_align Registers { - VolatileBitMapPOD adr; - VolatileBitMapPOD block_ctrl; - VolatileBitMapPOD channel_ctrl; + MADR_v adr; + BCR_v block_ctrl; + CHCHR_v channel_ctrl; + + void set_adr(uintptr_t adr) { + this->adr.set(MADR_t::MemoryAdr.with(adr)); + } + + void wait() { + while(this->channel_ctrl.is_set(CHCHR_t::Busy)); + } }; + // Those types do not need to be volatile because there members are + typedef Registers MDECin_v; + typedef Registers MDECout_v; + typedef Registers GPU_v; + typedef Registers CDROM_v; + typedef Registers SPU_v; + typedef Registers PIO_v; + typedef Registers OTC_v; + //0: Highest, 7: Lowest typedef uint32_t Priority; static constexpr Priority HighestPriority = 0; static constexpr Priority LowestPriority = 7; - struct DMAControlRegister : public ComplexBitMap { - static constexpr auto OTCEnable = Bit(27); - static constexpr auto OTCPriority = BitRange::from_to(24, 26); + __declare_io_type(DPCR, uint32_t, + static constexpr auto OTCEnable = IOBitSet(27); + static constexpr auto OTCPriority = IOValueSet::from_to(24, 26); - static constexpr auto PIOEnable = Bit(23); - static constexpr auto PIOPriority = BitRange::from_to(20, 22); + static constexpr auto PIOEnable = IOBitSet(23); + static constexpr auto PIOPriority = IOValueSet::from_to(20, 22); - static constexpr auto SPUEnable = Bit(19); - static constexpr auto SPUPriority = BitRange::from_to(16, 18); + static constexpr auto SPUEnable = IOBitSet(19); + static constexpr auto SPUPriority = IOValueSet::from_to(16, 18); - static constexpr auto CDROMEnable = Bit(15); - static constexpr auto CDROMPriority = BitRange::from_to(12, 14); + static constexpr auto CDROMEnable = IOBitSet(15); + static constexpr auto CDROMPriority = IOValueSet::from_to(12, 14); - static constexpr auto GPUEnable = Bit(11); - static constexpr auto GPUPriority = BitRange::from_to(8, 10); + static constexpr auto GPUEnable = IOBitSet(11); + static constexpr auto GPUPriority = IOValueSet::from_to(8, 10); - static constexpr auto MDECoutEnable = Bit(7); - static constexpr auto MDECoutPriority = BitRange::from_to(4, 6); + static constexpr auto MDECoutEnable = IOBitSet(7); + static constexpr auto MDECoutPriority = IOValueSet::from_to(4, 6); - static constexpr auto MDECinEnable = Bit(3); - static constexpr auto MDECinPriority = BitRange::from_to(0, 2); - }; + static constexpr auto MDECinEnable = IOBitSet(3); + static constexpr auto MDECinPriority = IOValueSet::from_to(0, 2); + ); - struct DMAInterruptRegister : public ComplexBitMap { - static constexpr auto MasterEnable = Bit(31); - static constexpr auto Flags = BitRange::from_to(24, 30); - static constexpr auto MasterEnableDPCR = Bit(23); - static constexpr auto EnableDPCR = BitRange::from_to(16, 22); - static constexpr auto ForceIRQ = Bit(15); - }; + __declare_io_type(DICR, uint32_t, + static constexpr auto MasterEnable = IOBitSet(31); + static constexpr auto Flags = IOValueSet::from_to(24, 30); + static constexpr auto MasterEnableDPCR = IOBitSet(23); + static constexpr auto EnableDPCR = IOValueSet::from_to(16, 22); + static constexpr auto ForceIRQ = IOBitSet(15); + ); - __declare_io_port_global_struct(Registers, MDECin, 0x1F801080); - __declare_io_port_global_struct(Registers, MDECout, 0x1F801090); - __declare_io_port_global_struct(Registers, GPU, 0x1F8010A0); - __declare_io_port_global_struct(Registers, CDROM, 0x1F8010B0); - __declare_io_port_global_struct(Registers, SPU, 0x1F8010C0); - __declare_io_port_global_struct(Registers, PIO, 0x1F8010D0); - __declare_io_port_global_struct(Registers, OTC, 0x1F8010E0); + __declare_new_io_port(MDECin, 0x1F801080); + __declare_new_io_port(MDECout, 0x1F801090); + __declare_new_io_port(GPU, 0x1F8010A0); + __declare_new_io_port(CDROM, 0x1F8010B0); + __declare_new_io_port(SPU, 0x1F8010C0); + __declare_new_io_port(PIO, 0x1F8010D0); + __declare_new_io_port(OTC, 0x1F8010E0); - __declare_io_port_global(DMAControlRegister, DPCR, 0x1F8010F0); - __declare_io_port_global(DMAInterruptRegister, DICR, 0x1F8010F4); + __declare_new_io_port(DPCR, 0x1F8010F0); + __declare_new_io_port(DICR, 0x1F8010F4); } } #endif //!__JABYENGINE_DMA_IO_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index c3132268..e0d03916 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -75,7 +75,6 @@ namespace JabyEngine { static constexpr name##_io_base from(const ARGS&...args) { \ return name##_io_base().set_va(args...); \ } \ - \ constexpr name##_io_base& set(IOBitSet bit) { \ this->raw_value = bit::set(this->raw_value, bit.pos); \ return *this; \ diff --git a/src/Library/include/GPU/gpu_internal.hpp b/src/Library/include/GPU/gpu_internal.hpp index fd042bca..0978f497 100644 --- a/src/Library/include/GPU/gpu_internal.hpp +++ b/src/Library/include/GPU/gpu_internal.hpp @@ -48,7 +48,7 @@ namespace JabyEngine { namespace DMA { static void wait() { - while(::JabyEngine::DMA_IO::GPU.channel_ctrl.read().is(::JabyEngine::DMA_IO::CHCHR::Busy)); + ::JabyEngine::DMA_IO::GPU.wait(); } static void end() { @@ -62,7 +62,7 @@ namespace JabyEngine { } static void set_src(uintptr_t adr) { - DMA_IO::GPU.adr.write(DMA_IO::MADR::MemoryAdr.with(static_cast(adr))); + DMA_IO::GPU.set_adr(adr); } static void set_dst(const PositionU16& position, const SizeU16& size) { @@ -73,10 +73,10 @@ namespace JabyEngine { } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { - typedef DMA_IO::BCR::SyncMode1 SyncMode1; + typedef DMA_IO::BCR_t::SyncMode1 SyncMode1; - DMA_IO::GPU.block_ctrl.write(DMA_IO::BCR{SyncMode1::with(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount))}); - DMA_IO::GPU.channel_ctrl.write(DMA_IO::CHCHR::StartGPUReceive()); + DMA_IO::GPU.block_ctrl = *DMA_IO::BCR_t::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount)); + DMA_IO::GPU.channel_ctrl = *DMA_IO::CHCHR_t::StartGPUReceive(); } } } diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 6d6e183e..625ed582 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -1,6 +1,7 @@ #include "BootLoader/boot_loader.hpp" #include +// 2x For setup timing #include #include @@ -8,7 +9,8 @@ namespace JabyEngine { namespace boot { namespace Start { static void enable_DMA() { - DMA_IO::DPCR.write(DMA_IO::DMAControlRegister{DMA_IO::DPCR.read() | DMA_IO::DMAControlRegister::SPUEnable | DMA_IO::DMAControlRegister::GPUEnable}); + const auto dpcr = DMA_IO::DPCR_t(*DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable); + DMA_IO::DPCR = *dpcr; } JabyEngine::NextRoutine setup() { From 8e883ad1d12236e26dc2408230cc024f6224077a Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 21 Mar 2023 20:39:51 +0100 Subject: [PATCH 15/47] Ported CDIOs --- include/PSX/System/IOPorts/cd_io.hpp | 180 ++++++++++++------------- include/PSX/System/IOPorts/ioport.hpp | 5 + src/Library/include/CD/cd_internal.hpp | 14 +- src/Library/src/BootLoader/cd_boot.cpp | 4 +- src/Library/src/CD/cd.cpp | 8 +- 5 files changed, 107 insertions(+), 104 deletions(-) diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 416fdbab..1f4d0198 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -31,56 +31,54 @@ namespace JabyEngine { static constexpr uint8_t Max = 0xFF; }; - typedef struct IndexStatus : public ComplexBitMap { - static constexpr auto PortIndex = BitRange::from_to(0, 1); - static constexpr auto HasXAFifoData = Bit(2); - static constexpr auto IsParameterFifoEmpty = Bit(3); - static constexpr auto HasParameterFifoSpace = Bit(4); - static constexpr auto HasResponseFifoData = Bit(5); - static constexpr auto HasDataFifoData = Bit(6); - static constexpr auto IsTransmissionBusy = Bit(7); - } IndexStatus_t; + __declare_io_type(IndexStatus, uint8_t, + static constexpr auto PortIndex = IOValueSet::from_to(0, 1); + static constexpr auto HasXAFifoData = IOBitSet(2); + static constexpr auto IsParameterFifoEmpty = IOBitSet(3); + static constexpr auto HasParameterFifoSpace = IOBitSet(4); + static constexpr auto HasResponseFifoData = IOBitSet(5); + static constexpr auto HasDataFifoData = IOBitSet(6); + static constexpr auto IsTransmissionBusy = IOBitSet(7); + ); - struct InterruptEnable : public ComplexBitMap { - static constexpr auto InterruptTypValue = BitRange::from_to(0, 2); - static constexpr auto InterruptExtended = BitRange::from_to(0, 4); - static constexpr auto UnknownIRQ = Bit(3); - static constexpr auto CommandStartIRQ = Bit(4); - }; - typedef InterruptEnable InterruptFlag; + __declare_io_type(InterruptEnable, uint8_t, + static constexpr auto InterruptTypValue = IOValueSet::from_to(0, 2); + static constexpr auto InterruptExtended = IOValueSet::from_to(0, 4); + static constexpr auto UnknownIRQ = IOBitSet(3); + static constexpr auto CommandStartIRQ = IOBitSet(4); + ); + typedef InterruptEnable_v InterruptFlag_v; - struct Request : public ComplexBitMap { - static constexpr auto WantCommandStartIRQ = Bit(5); - static constexpr auto WantData = Bit(7); - }; + __declare_io_type(Request, uint8_t, + static constexpr auto WantCommandStartIRQ = IOBitSet(5); + static constexpr auto WantData = IOBitSet(7); + ); - struct SoundMapCoding : public ComplexBitMap { - static constexpr auto Stereo = Bit(0); + __declare_io_type(SoundMapCoding, uint8_t, + static constexpr auto Stereo = IOBitSet(0); static constexpr auto Mono = !Stereo; - static constexpr auto SampleRate_18900hz = Bit(2); + static constexpr auto SampleRate_18900hz = IOBitSet(2); static constexpr auto SampleRate_37800hz = !SampleRate_18900hz; - static constexpr auto BitsPerSample8 = Bit(4); + static constexpr auto BitsPerSample8 = IOBitSet(4); static constexpr auto BitsPerSample4 = !BitsPerSample8; - static constexpr auto Emphasis = Bit(6); - }; + static constexpr auto Emphasis = IOBitSet(6); + ); - struct AudioVolumeApply : public ComplexBitMap { - static constexpr auto Mute = Bit(0); - static constexpr auto ApplyChanges = Bit(5); - }; + __declare_io_type(AudioVolumeApply, uint8_t, + static constexpr auto Mute = IOBitSet(0); + static constexpr auto ApplyChanges = IOBitSet(5); + ); - typedef VolatilePOD ResponseFifo_t; - typedef VolatilePOD CommandFifo_t; - typedef VolatilePOD DataFifo_t; - typedef VolatilePOD DataFifo16_t; - typedef VolatilePOD ParameterFifo_t; - typedef VolatilePOD SoundMapDataOut_t; - typedef VolatilePOD VolumeRegister_t; - typedef VolatileBitMapPOD InterruptEnableRegister_t; - typedef VolatileBitMapPOD InterruptFlagRegister_t; - typedef VolatileBitMapPOD RequestRegister_t; - typedef VolatileBitMapPOD SoundMapCodingInfo_t; - typedef VolatileBitMapPOD AudioVolumeApplyChange_t; + __declare_io_type(ResponseFifo, uint8_t,); + __declare_io_type(CommandFifo, uint8_t,); + __declare_io_type(DataFifo, uint8_t,); + __declare_io_type(DataFifo16, uint16_t,); + __declare_io_type(ParameterFifo, uint8_t,); + __declare_io_type(SoundMapDataOut, uint8_t,); + __declare_io_type(LeftCD2LeftSPU, CDDAVolume::Type,); + __declare_io_type(LeftCD2RightSPU, CDDAVolume::Type,); + __declare_io_type(RightCD2RightSPU,CDDAVolume::Type,); + __declare_io_type(RightCD2LeftSPU, CDDAVolume::Type,); struct Interrupt { enum Type : uint8_t { @@ -92,110 +90,110 @@ namespace JabyEngine { DiskError = 5 }; - static void enable(InterruptEnableRegister_t& port) { - port.write(InterruptEnable::InterruptTypValue.max()); + static void enable(InterruptEnable_v& port) { + port.set(InterruptEnable_t::InterruptTypValue.range_max()); } - static void enable_extended(InterruptEnableRegister_t& port) { - port.write({InterruptEnable::with(InterruptEnable::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)}); + static void enable_extended(InterruptEnable_v& port) { + port = *InterruptEnable_t::from(InterruptEnable_t::InterruptTypValue.range_max(), InterruptEnable_t::UnknownIRQ, InterruptEnable_t::CommandStartIRQ); } - static Type get_type(const InterruptFlagRegister_t& port) { - return static_cast(port.read().get_value(InterruptFlag::InterruptTypValue)); + static Type get_type(const InterruptFlag_v& port) { + return static_cast(port.get(InterruptFlag_v::InterruptTypValue)); } - static void ack(InterruptFlagRegister_t& port) { - port.write(InterruptFlag::InterruptTypValue.max()); + static void ack(InterruptFlag_v& port) { + port.set(InterruptFlag_v::InterruptTypValue.range_max()); } - static void ack_extended(InterruptFlagRegister_t& port) { - port.write({InterruptFlag::with(InterruptFlag::InterruptTypValue.max(), InterruptEnable::UnknownIRQ, InterruptEnable::CommandStartIRQ)}); + static void ack_extended(InterruptFlag_v& port) { + port = *InterruptFlag_v::from(InterruptFlag_v::InterruptTypValue.range_max(), InterruptEnable_v::UnknownIRQ, InterruptEnable_v::CommandStartIRQ); } }; struct Command { - struct Info { + struct Desc { uint8_t id; Interrupt::Type complete_irq; }; - static constexpr Info GetStat{0x01, Interrupt::Type::Acknowledge}; - static constexpr Info SetLoc{0x02, Interrupt::Type::Acknowledge}; - static constexpr Info ReadN{0x06, Interrupt::Type::DataReady}; - static constexpr Info Pause{0x09, Interrupt::Type::Complete}; - static constexpr Info Init{0x0A, Interrupt::Type::Complete}; - static constexpr Info SetMode{0x0E, Interrupt::Type::Acknowledge}; + static constexpr Desc GetStat{0x01, Interrupt::Type::Acknowledge}; + static constexpr Desc SetLoc{0x02, Interrupt::Type::Acknowledge}; + static constexpr Desc ReadN{0x06, Interrupt::Type::DataReady}; + static constexpr Desc Pause{0x09, Interrupt::Type::Complete}; + static constexpr Desc Init{0x0A, Interrupt::Type::Complete}; + static constexpr Desc SetMode{0x0E, Interrupt::Type::Acknowledge}; }; static constexpr auto IORegister1Adr = 0x1F801801; static constexpr auto IORegister2Adr = 0x1F801802; static constexpr auto IORegister3Adr = 0x1F801803; - __declare_io_port_global(IndexStatus_t, IndexStatus, 0x1F801800); + __declare_new_io_port(IndexStatus, 0x1F801800); #define __declare_index_io_port(type, name, adr) __cast_io_adr_with_type(inline, type, name, adr) #define __declare_index_io_port_const(type, name, adr) __cast_io_adr_with_type(const inline, type, name, adr) struct PortIndex0 { - __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); - __declare_index_io_port( CommandFifo_t, CommandFifo, IORegister1Adr); + __declare_new_const_io_port(ResponseFifo, IORegister1Adr); + __declare_new_io_port(CommandFifo, IORegister1Adr); - __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); - __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); - __declare_index_io_port( ParameterFifo_t, ParameterFifo, IORegister2Adr); + __declare_new_const_io_port(DataFifo, IORegister2Adr); + __declare_new_const_io_port(DataFifo16, IORegister2Adr); + __declare_new_io_port(ParameterFifo, IORegister2Adr); - __declare_index_io_port_const(InterruptEnableRegister_t, InterruptEnableRegister, IORegister3Adr); - __declare_index_io_port( RequestRegister_t, RequestRegister, IORegister3Adr); + __declare_new_const_io_port(InterruptEnable, IORegister3Adr); + __declare_new_io_port(Request, IORegister3Adr); static void change_to() { - IndexStatus.write({static_cast(Index::Index0)}); + IndexStatus = Index::Index0; } }; struct PortIndex1 { - __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); - __declare_index_io_port( SoundMapDataOut_t, SoundMapDataOut, IORegister1Adr); + __declare_new_const_io_port(ResponseFifo, IORegister1Adr); + __declare_new_io_port(SoundMapDataOut, IORegister1Adr); - __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); - __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); - __declare_index_io_port( InterruptEnableRegister_t, InterruptEnableRegister, IORegister2Adr); + __declare_new_const_io_port(DataFifo, IORegister2Adr); + __declare_new_const_io_port(DataFifo16, IORegister2Adr); + __declare_new_io_port(InterruptEnable, IORegister2Adr); - __declare_index_io_port(InterruptFlagRegister_t, InterruptFlagRegister, IORegister3Adr); + __declare_new_io_port(InterruptFlag, IORegister3Adr); static void change_to() { - IndexStatus.write({static_cast(Index::Index1)}); + IndexStatus = Index::Index1; } }; struct PortIndex2 { - __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); - __declare_index_io_port( SoundMapCodingInfo_t, SoundMapCodingInfo, IORegister1Adr); + __declare_new_const_io_port(ResponseFifo, IORegister1Adr); + __declare_new_io_port(SoundMapCoding, IORegister1Adr); - __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); - __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); - __declare_index_io_port( VolumeRegister_t, LeftCD2LeftSPU, IORegister2Adr); + __declare_new_const_io_port(DataFifo, IORegister2Adr); + __declare_new_const_io_port(DataFifo16, IORegister2Adr); + __declare_new_io_port(LeftCD2LeftSPU, IORegister2Adr); - __declare_index_io_port_const(InterruptEnableRegister_t, InterruptEnableRegister, IORegister3Adr); - __declare_index_io_port( VolumeRegister_t, LeftCD2RightSPU, IORegister3Adr); + __declare_new_const_io_port(InterruptEnable, IORegister3Adr); + __declare_new_io_port(LeftCD2RightSPU, IORegister3Adr); static void change_to() { - IndexStatus.write({static_cast(Index::Index2)}); + IndexStatus = Index::Index2; } }; struct PortIndex3 { - __declare_index_io_port_const(ResponseFifo_t, ResponseFifo, IORegister1Adr); - __declare_index_io_port( VolumeRegister_t, RightCD2RightSPU, IORegister1Adr); + __declare_new_const_io_port(ResponseFifo, IORegister1Adr); + __declare_new_io_port(RightCD2RightSPU, IORegister1Adr); - __declare_index_io_port_const(DataFifo_t, DataFifo, IORegister2Adr); - __declare_index_io_port_const(DataFifo16_t, DataFifo16, IORegister2Adr); - __declare_index_io_port( VolumeRegister_t, RightCD2LeftSPU, IORegister1Adr); + __declare_new_const_io_port(DataFifo, IORegister2Adr); + __declare_new_const_io_port(DataFifo16, IORegister2Adr); + __declare_new_io_port(RightCD2LeftSPU, IORegister1Adr); - __declare_index_io_port_const(InterruptFlagRegister_t, InterruptFlagRegister, IORegister3Adr); - __declare_index_io_port( AudioVolumeApplyChange_t, AudioVolumeApplyChange, IORegister3Adr); + __declare_new_const_io_port(InterruptFlag, IORegister3Adr); + __declare_new_io_port(AudioVolumeApply, IORegister3Adr); static void change_to() { - IndexStatus.write({static_cast(Index::Index3)}); + IndexStatus = Index::Index3; } }; diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index e0d03916..657c6d29 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -40,6 +40,11 @@ namespace JabyEngine { constexpr IOValueSetPair with(T value) const { return {*this, value}; } + + template + constexpr IOValueSetPair range_max() const { + return IOValueSet::with((1 << this->length) - 1); + } }; template diff --git a/src/Library/include/CD/cd_internal.hpp b/src/Library/include/CD/cd_internal.hpp index 0eed478a..3e05fb69 100644 --- a/src/Library/include/CD/cd_internal.hpp +++ b/src/Library/include/CD/cd_internal.hpp @@ -22,26 +22,26 @@ namespace JabyEngine { } template - static void send(CD_IO::CommandFifo_t& cmd_fifo, CD_IO::ParameterFifo_t& parameter_fifo, CD_IO::Command::Info cmd, ARGS...args) { - while(CD_IO::IndexStatus.read().is_bit_set(CD_IO::IndexStatus::IsTransmissionBusy)); + static void send(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { + while(CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::IsTransmissionBusy)); - (parameter_fifo.write(static_cast(args)), ...); - cmd_fifo.write(cmd.id); + ((parameter_fifo = args),...); + cmd_fifo = cmd.id; } template - static void send(CD_IO::Command::Info cmd, ARGS...args) { + static void send(CD_IO::Command::Desc cmd, ARGS...args) { send(T::CommandFifo, T::ParameterFifo, cmd, args...); } template - static void send_wait(CD_IO::CommandFifo_t& cmd_fifo, CD_IO::ParameterFifo_t& parameter_fifo, CD_IO::Command::Info cmd, ARGS...args) { + static void send_wait(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { send(cmd_fifo, parameter_fifo, cmd, args...); wait_until(cmd.complete_irq); } template - static void send_wait(CD_IO::Command::Info cmd, ARGS...args) { + static void send_wait(CD_IO::Command::Desc cmd, ARGS...args) { send_wait(T::CommandFifo, T::ParameterFifo, cmd, args...); } }; diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index c7507534..e52d6ded 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -22,8 +22,8 @@ namespace JabyEngine { __syscall_SysEnqIntRP(CdromIoIrq, &::JabyEngine::CD::internal::callback); CD_IO::PortIndex1::change_to(); - CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlagRegister); - CD_IO::Interrupt::enable(CD_IO::PortIndex1::InterruptEnableRegister); + CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); + CD_IO::Interrupt::enable(CD_IO::PortIndex1::InterruptEnable); Interrupt::ack_irq(Interrupt::CDROM); Interrupt::enable_irq(Interrupt::CDROM); diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 24769bb1..e015bda8 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -31,12 +31,12 @@ namespace JabyEngine { }; if(Interrupt::is_irq(Interrupt::CDROM)) { - const uint8_t old_idx = (CD_IO::IndexStatus.read() & 0x3); + const uint8_t old_idx = (*CD_IO::IndexStatus & 0x3); CD_IO::PortIndex1::change_to(); - const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlagRegister); + const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); last_interrupt = cur_irq; - CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlagRegister); + CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlag); if(cur_irq == CD_IO::Interrupt::DataReady) { //Obtain sector content here @@ -67,7 +67,7 @@ namespace JabyEngine { current_state = State::Error; } - CD_IO::IndexStatus.write({old_idx}); + CD_IO::IndexStatus = old_idx; return InterruptVerifierResult::ExecuteHandler; } From 550d6574782a0eb880d77cf6abaf3fa2133937d4 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 21 Mar 2023 21:51:56 +0100 Subject: [PATCH 16/47] Improve readability of code slightly --- include/PSX/GPU/gpu.hpp | 4 +- include/PSX/System/IOPorts/cd_io.hpp | 4 +- include/PSX/System/IOPorts/gpu_io.hpp | 2 +- include/PSX/System/IOPorts/ioport.hpp | 164 ++++++++++++---------- include/PSX/System/IOPorts/timer_io.hpp | 2 +- src/Library/include/GPU/gpu_internal.hpp | 28 ++-- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/BootLoader/spu_boot.cpp | 22 +-- src/Library/src/BootLoader/start_boot.cpp | 4 +- src/Library/src/CD/cd.cpp | 2 +- src/Library/src/GPU/gpu.cpp | 10 +- 11 files changed, 127 insertions(+), 117 deletions(-) diff --git a/include/PSX/GPU/gpu.hpp b/include/PSX/GPU/gpu.hpp index 5952091a..6f026a8f 100644 --- a/include/PSX/GPU/gpu.hpp +++ b/include/PSX/GPU/gpu.hpp @@ -22,11 +22,11 @@ namespace JabyEngine { #endif static void enable() { - GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On); + GPU_IO::GP1 = GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::On); } static void disable() { - GPU_IO::GP1 = *GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off); + GPU_IO::GP1 = GPU_IO::Command::SetDisplayState(GPU_IO::DisplayState::Off); } }; diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 1f4d0198..9e3ba268 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -95,7 +95,7 @@ namespace JabyEngine { } static void enable_extended(InterruptEnable_v& port) { - port = *InterruptEnable_t::from(InterruptEnable_t::InterruptTypValue.range_max(), InterruptEnable_t::UnknownIRQ, InterruptEnable_t::CommandStartIRQ); + port = InterruptEnable_t::from(InterruptEnable_t::InterruptTypValue.range_max(), InterruptEnable_t::UnknownIRQ, InterruptEnable_t::CommandStartIRQ); } static Type get_type(const InterruptFlag_v& port) { @@ -107,7 +107,7 @@ namespace JabyEngine { } static void ack_extended(InterruptFlag_v& port) { - port = *InterruptFlag_v::from(InterruptFlag_v::InterruptTypValue.range_max(), InterruptEnable_v::UnknownIRQ, InterruptEnable_v::CommandStartIRQ); + port = InterruptFlag_v::from(InterruptFlag_v::InterruptTypValue.range_max(), InterruptEnable_v::UnknownIRQ, InterruptEnable_v::CommandStartIRQ); } }; diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index 9e21b3a3..b4ede548 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -163,7 +163,7 @@ namespace JabyEngine { } static constexpr GP1_t DisplayMode(DisplayMode_t mode) { - return {Helper::construct_cmd(0x08, *mode)}; + return {Helper::construct_cmd(0x08, mode)}; } }; diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 657c6d29..6719a2c2 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -47,15 +47,21 @@ namespace JabyEngine { } }; - template - struct NormalValue { - typedef T Value; - }; + namespace IOPort { + struct IOValueType { + template + struct Normal { + typedef T Value; + typedef T UnderlyingValue; + }; - template - struct VolatileValue { - typedef volatile T Value; - }; + template + struct Volatile { + typedef volatile T Value; + typedef T UnderlyingValue; + }; + }; + } #define __declare_new_named_io_port(type, name, adr) \ static inline auto& name = *reinterpret_cast(adr) @@ -69,73 +75,77 @@ namespace JabyEngine { #define __declare_new_io_port_array(name, adr, size) \ static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) - #define __declare_io_type(name, type, ...) \ - template typename T> \ - struct name##_io_base { \ - T::Value raw_value = 0; \ - typedef name##_io_base Self; \ - \ - __VA_ARGS__ \ - template \ - static constexpr name##_io_base from(const ARGS&...args) { \ - return name##_io_base().set_va(args...); \ - } \ - constexpr name##_io_base& set(IOBitSet bit) { \ - this->raw_value = bit::set(this->raw_value, bit.pos); \ - return *this; \ - } \ - \ - constexpr name##_io_base& set(IOBitUnset bit) { \ - this->raw_value = bit::clear(this->raw_value, bit.pos); \ - return *this; \ - } \ - \ - constexpr name##_io_base& set(IOValueSet bits, type value) { \ - this->raw_value = bit::value::set_normalized(this->raw_value, value, bits.pos, bits.length); \ - return *this; \ - } \ - \ - template \ - constexpr name##_io_base& set(const IOValueSet::IOValueSetPair& value) { \ - this->set(value.first, static_cast(value.second)); \ - return *this; \ - } \ - \ - template \ - constexpr name##_io_base& set_va(const S& head) { \ - return this->set(head); \ - } \ - template \ - constexpr name##_io_base& set_va(const S& head, const ARGS&...tail) { \ - return this->set(head).set_va(tail...); \ - } \ - constexpr type get(IOValueSet bits) const { \ - return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ - } \ - \ - \ - constexpr name##_io_base& clear(IOBitSet bit) { \ - this->raw_value = bit::clear(this->raw_value, bit.pos); \ - return *this; \ - } \ - \ - \ - constexpr bool is_set(IOBitSet bit) const { \ - return bit::is_set(this->raw_value, bit.pos); \ - } \ - \ - \ - constexpr void operator=(type value) { \ - this->raw_value = value; \ - } \ - \ - constexpr type operator*() const { \ - return this->raw_value; \ - } \ - }; \ - \ - typedef name##_io_base name##_v; \ - typedef name##_io_base name##_t \ + #define __declare_io_type(name, type, ...) \ + /*We need this type to be a POD sadly*/ \ + template typename T> \ + struct name##_io_base { \ + typedef T::UnderlyingValue UnderlyingValue; \ + typedef name##_io_base Self; \ + \ + T::Value raw_value = 0; \ + \ + __VA_ARGS__ \ + \ + template \ + static constexpr Self from(const ARGS&...args) { \ + return Self().set_va(args...); \ + } \ + \ + constexpr Self& set(IOBitSet bit) { \ + this->raw_value = bit::set(this->raw_value, bit.pos); \ + return *this; \ + } \ + \ + constexpr Self& set(IOBitUnset bit) { \ + this->raw_value = bit::clear(this->raw_value, bit.pos); \ + return *this; \ + } \ + \ + constexpr Self& set(IOValueSet bits, UnderlyingValue value) { \ + this->raw_value = bit::value::set_normalized(this->raw_value, value, bits.pos, bits.length); \ + return *this; \ + } \ + \ + template \ + constexpr Self& set(const IOValueSet::IOValueSetPair& value) { \ + this->set(value.first, static_cast(value.second)); \ + return *this; \ + } \ + \ + template \ + constexpr Self& set_va(const S& head) { \ + return this->set(head); \ + } \ + \ + template \ + constexpr Self& set_va(const S& head, const ARGS&...tail) { \ + return this->set(head).set_va(tail...); \ + } \ + \ + constexpr UnderlyingValue get(IOValueSet bits) const { \ + return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ + } \ + \ + constexpr Self& clear(IOBitSet bit) { \ + this->raw_value = bit::clear(this->raw_value, bit.pos); \ + return *this; \ + } \ + \ + constexpr bool is_set(IOBitSet bit) const { \ + return bit::is_set(this->raw_value, bit.pos); \ + } \ + \ + constexpr void operator=(UnderlyingValue value) { \ + this->raw_value = value; \ + } \ + \ + constexpr operator UnderlyingValue() const { \ + return this->raw_value; \ + } \ + }; \ + \ + typedef name##_io_base name##_v; \ + typedef name##_io_base name##_t template struct VolatilePOD { @@ -196,8 +206,8 @@ namespace JabyEngine { } constexpr operator uint32_t() const { - const uint32_t high = *this->high; - const uint32_t low = *this->low; + const uint32_t high = this->high; + const uint32_t low = this->low; return ((high << 16) | low); } diff --git a/include/PSX/System/IOPorts/timer_io.hpp b/include/PSX/System/IOPorts/timer_io.hpp index 8343f70b..3962f3be 100644 --- a/include/PSX/System/IOPorts/timer_io.hpp +++ b/include/PSX/System/IOPorts/timer_io.hpp @@ -47,7 +47,7 @@ namespace JabyEngine { } constexpr void set_mode(CounterMode_t mode) { - this->mode = *mode; + this->mode = mode; } }; diff --git a/src/Library/include/GPU/gpu_internal.hpp b/src/Library/include/GPU/gpu_internal.hpp index 0978f497..9903400b 100644 --- a/src/Library/include/GPU/gpu_internal.hpp +++ b/src/Library/include/GPU/gpu_internal.hpp @@ -14,12 +14,12 @@ namespace JabyEngine { #ifdef JABYENGINE_PAL static constexpr uint16_t FirstVisiblePixelV = 0xA3; - GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL()); + GPU_IO::GP1 = GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::PAL()); GPU::Screen::set_offset(0, 0); #else static constexpr uint16_t FirstVisiblePixelV = 0x88; - GPU_IO::GP1 = *GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC()); + GPU_IO::GP1 = GPU_IO::Command::DisplayMode(GPU_IO::DisplayMode_t::NTSC()); GPU::Screen::set_offset(0, 5); //< Random values #endif } @@ -28,18 +28,18 @@ namespace JabyEngine { }; static void set_draw_area(uint16_t x, uint16_t y) { - GPU_IO::GP0 = *GPU_IO::Command::DrawAreaTopLeft(x, y); - GPU_IO::GP0 = *GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); + GPU_IO::GP0 = GPU_IO::Command::DrawAreaTopLeft(x, y); + GPU_IO::GP0 = GPU_IO::Command::DrawAreaBottomRight((x + Display::Width), (y + Display::Height)); } static void quick_fill_fast(const Color24& color, const PositionU16& pos, const SizeU16& size) { - GPU_IO::GP0 = *GPU_IO::Command::QuickFill(color); - GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(pos.x, pos.y); - GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); + GPU_IO::GP0 = GPU_IO::Command::QuickFill(color); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(pos.x, pos.y); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(size.width, size.height); } static void reset_cmd_buffer() { - GPU_IO::GP1 = *GPU_IO::Command::ResetCMDBufer(); + GPU_IO::GP1 = GPU_IO::Command::ResetCMDBufer(); } static void wait_ready_for_CMD() { @@ -57,7 +57,7 @@ namespace JabyEngine { namespace Receive { static void prepare() { - GPU_IO::GP1 = *GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU); + GPU_IO::GP1 = GPU_IO::Command::DMADirection(GPU_IO::DMADirection::CPU2GPU); reset_cmd_buffer(); } @@ -67,16 +67,16 @@ namespace JabyEngine { static void set_dst(const PositionU16& position, const SizeU16& size) { wait_ready_for_CMD(); - GPU_IO::GP0 = *GPU_IO::Command::CPU2VRAM_Blitting(); - GPU_IO::GP0 = *GPU_IO::Command::TopLeftPosition(position.x, position.y); - GPU_IO::GP0 = *GPU_IO::Command::WidthHeight(size.width, size.height); + GPU_IO::GP0 = GPU_IO::Command::CPU2VRAM_Blitting(); + GPU_IO::GP0 = GPU_IO::Command::TopLeftPosition(position.x, position.y); + GPU_IO::GP0 = GPU_IO::Command::WidthHeight(size.width, size.height); } static void start(uint16_t blockCount, uint16_t wordsPerBlock = 0x10) { typedef DMA_IO::BCR_t::SyncMode1 SyncMode1; - DMA_IO::GPU.block_ctrl = *DMA_IO::BCR_t::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount)); - DMA_IO::GPU.channel_ctrl = *DMA_IO::CHCHR_t::StartGPUReceive(); + DMA_IO::GPU.block_ctrl = DMA_IO::BCR_t::from(SyncMode1::BlockSize.with(wordsPerBlock), SyncMode1::BlockAmount.with(blockCount)); + DMA_IO::GPU.channel_ctrl = DMA_IO::CHCHR_t::StartGPUReceive(); } } } diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index 064961f8..c682a2b6 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -49,7 +49,7 @@ namespace JabyEngine { } void setup() { - GPU_IO::GP1 = *GPU_IO::Command::Reset(); + GPU_IO::GP1 = GPU_IO::Command::Reset(); internal::Screen::configurate(); internal::Screen::exchange_buffer_and_display(); diff --git a/src/Library/src/BootLoader/spu_boot.cpp b/src/Library/src/BootLoader/spu_boot.cpp index b3f779b4..bff3a1d8 100644 --- a/src/Library/src/BootLoader/spu_boot.cpp +++ b/src/Library/src/BootLoader/spu_boot.cpp @@ -11,8 +11,8 @@ namespace JabyEngine { static void clear_main_volume() { static constexpr auto StartVol = SweepVolume_t::from(SweepVolume_t::VolumeEnable, SweepVolume_t::Volume.with(static_cast(I16_MAX >> 2))); - MainVolume::Left = *StartVol; - MainVolume::Right = *StartVol; + MainVolume::Left = StartVol; + MainVolume::Right = StartVol; } static void clear_cd_and_ext_audio_volume() { @@ -29,11 +29,11 @@ namespace JabyEngine { static void clear_voice() { for(auto& voice : SPU_IO::Voice) { - voice.volumeLeft = *SweepVolume_t(); - voice.volumeRight = *SweepVolume_t(); - voice.sampleRate = *SampleRate_t(); - voice.ad = *AD_t(); - voice.sr = *SR_t(); + voice.volumeLeft = SweepVolume_t(); + voice.volumeRight = SweepVolume_t(); + voice.sampleRate = SampleRate_t(); + voice.ad = AD_t(); + voice.sr = SR_t(); voice.currentVolume = 0; voice.adr = 0x200; @@ -42,12 +42,12 @@ namespace JabyEngine { } static void clear_pmon() { - SPU_IO::PMON = *PMON_t(); + SPU_IO::PMON = PMON_t(); } static void clear_noise_and_echo() { - SPU_IO::NON = *NON_t(); - SPU_IO::EON = *EON_t(); + SPU_IO::NON = NON_t(); + SPU_IO::EON = EON_t(); } static void clear_reverb() { @@ -59,7 +59,7 @@ namespace JabyEngine { static void setup_control_register() { static constexpr auto SetupValue = ControlRegister_t::from(ControlRegister_t::Enable, ControlRegister_t::Unmute, ControlRegister_t::CDAudioEnable); - SPU_IO::ControlRegister = *SetupValue; + SPU_IO::ControlRegister = SetupValue; } static void setup_data_transfer_control() { diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 625ed582..1745006c 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -9,8 +9,8 @@ namespace JabyEngine { namespace boot { namespace Start { static void enable_DMA() { - const auto dpcr = DMA_IO::DPCR_t(*DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable); - DMA_IO::DPCR = *dpcr; + const auto dpcr = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable); + DMA_IO::DPCR = dpcr; } JabyEngine::NextRoutine setup() { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index e015bda8..d6497a07 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -31,7 +31,7 @@ namespace JabyEngine { }; if(Interrupt::is_irq(Interrupt::CDROM)) { - const uint8_t old_idx = (*CD_IO::IndexStatus & 0x3); + const uint8_t old_idx = (CD_IO::IndexStatus & 0x3); CD_IO::PortIndex1::change_to(); const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index 6474edf0..de902fd1 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -16,7 +16,7 @@ namespace JabyEngine { void Screen :: exchange_buffer_and_display() { GPU::internal::set_draw_area(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); PublicScreenClass::CurrentDisplayAreaID ^= 1; - GPU_IO::GP1 = *GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); + GPU_IO::GP1 = GPU_IO::Command::DisplayArea(0, (Display::Height*PublicScreenClass::CurrentDisplayAreaID)); } } @@ -25,13 +25,13 @@ namespace JabyEngine { x += 78; y += 43; - GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3); - GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height); + GPU_IO::GP1 = GPU_IO::Command::HorizontalDisplayRange((x << 3), (x + Display::Width) << 3); + GPU_IO::GP1 = GPU_IO::Command::VerticalDisplayRange(y, y + Display::Height); } #else void Screen :: set_offset(uint16_t x, uint16_t y) { - GPU_IO::GP1 = *GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8)); - GPU_IO::GP1 = *GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)); + GPU_IO::GP1 = GPU_IO::Command::HorizontalDisplayRange(x, (x + Display::Width*8)); + GPU_IO::GP1 = GPU_IO::Command::VerticalDisplayRange(y - (ScanlinesV/2), y + (ScanlinesV/2)); } #endif //USE_NO$PSX } From 94c078dc9f6f10eff1223b6b58c037b2aba79ab8 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 22 Mar 2023 20:46:08 +0100 Subject: [PATCH 17/47] Remove the ComplexBitMap --- include/PSX/Auxiliary/bits.hpp | 119 ++++++++++-- include/PSX/Auxiliary/complex_bitmap.hpp | 202 -------------------- include/PSX/File/file_types.hpp | 22 ++- include/PSX/GPU/gpu_types.hpp | 16 +- include/PSX/System/IOPorts/cd_io.hpp | 38 ++-- include/PSX/System/IOPorts/dma_io.hpp | 68 +++---- include/PSX/System/IOPorts/gpu_io.hpp | 88 ++++----- include/PSX/System/IOPorts/interrupt_io.hpp | 30 +-- include/PSX/System/IOPorts/ioport.hpp | 101 ++-------- include/PSX/System/IOPorts/spu_io.hpp | 64 +++---- include/PSX/System/IOPorts/timer_io.hpp | 26 +-- src/Library/src/CD/cd.cpp | 20 +- src/Library/src/startup.cpp | 2 +- 13 files changed, 307 insertions(+), 489 deletions(-) diff --git a/include/PSX/Auxiliary/bits.hpp b/include/PSX/Auxiliary/bits.hpp index 8ef3a671..8857b64a 100644 --- a/include/PSX/Auxiliary/bits.hpp +++ b/include/PSX/Auxiliary/bits.hpp @@ -1,17 +1,88 @@ #ifndef __JABYENGINE_BITS_HPP__ #define __JABYENGINE_BITS_HPP__ #include "../jabyengine_defines.h" +#include "types.hpp" namespace JabyEngine { namespace bit { + namespace value { + template + static constexpr T set_normalized(T raw_value, T value, size_t start_bit, size_t length); + } + } + + struct ClearBit { + uint16_t pos; + + constexpr ClearBit(uint16_t bit_pos) : pos(bit_pos) { + } + }; + + struct Bit { + uint16_t pos; + + constexpr Bit(uint16_t bit_pos) : pos(bit_pos) { + } + + constexpr ClearBit operator!() const { + return ClearBit(this->pos); + } + }; + + struct BitRange { + template + using RangeValuePair = pair; + + uint16_t pos; + uint16_t length; + + constexpr BitRange(uint16_t pos, uint16_t length) : pos(pos), length(length) { + } + + static constexpr BitRange from_to(uint16_t first_bit, uint16_t last_bit) { + return BitRange(first_bit, (last_bit - first_bit) + 1); + } + + template + constexpr RangeValuePair with(T value) const { + return {*this, value}; + } + + template + constexpr T as_value(T value) const { + return bit::value::set_normalized(static_cast(0), value, this->pos, this->length); + } + + template + constexpr RangeValuePair range_max() const { + return BitRange::with((1 << this->length) - 1); + } + }; + + namespace bit { + template + static constexpr T clear(T raw_value, size_t bit) { + return (raw_value & ~(1 << bit)); + } + + template + static constexpr T clear(T raw_value, Bit bit) { + return clear(raw_value, bit.pos); + } + template static constexpr T set(T raw_value, size_t bit) { return (raw_value | (1 << bit)); } template - static constexpr T clear(T raw_value, size_t bit) { - return (raw_value & ~(1 << bit)); + static constexpr T set(T raw_value, Bit bit) { + return set(raw_value, bit.pos); + } + + template + static constexpr T set(T raw_value, ClearBit bit) { + return clear(raw_value, bit.pos); } template @@ -19,30 +90,52 @@ namespace JabyEngine { return static_cast(raw_value & (1 << bit)); } - namespace value { - template - static constexpr T crop_value(T raw_value, size_t length) { - return (raw_value & ((1 << length) - 1)); - } + template + static constexpr bool is_set(T raw_value, Bit bit) { + return is_set(raw_value, bit.pos); + } - template - static constexpr T range_mask(size_t start_bit, size_t length) { - return (((1 << length) - 1) << start_bit); + namespace value { + namespace helper { + template + static constexpr T crop_value(T raw_value, size_t length) { + return (raw_value & ((1 << length) - 1)); + } + + template + static constexpr T range_mask(size_t start_bit, size_t length) { + return (((1 << length) - 1) << start_bit); + } } template static constexpr T clear_normalized(T raw_value, size_t start_bit, size_t length) { - return (raw_value & ~range_mask(start_bit, length)); + return (raw_value & ~helper::range_mask(start_bit, length)); } template static constexpr T set_normalized(T raw_value, T value, size_t start_bit, size_t length) { - return (clear_normalized(raw_value, start_bit, length) | (crop_value(value, length) << start_bit)); + return (clear_normalized(raw_value, start_bit, length) | (helper::crop_value(value, length) << start_bit)); + } + + template + static constexpr T set_normalized(T raw_value, BitRange bits, T value) { + return set_normalized(raw_value, value, bits.pos, bits.length); + } + + template + static constexpr T set_normalized(T raw_value, const BitRange::RangeValuePair &value_pair) { + return set_normalized(raw_value, value_pair.first, static_cast(value_pair.second)); } template static constexpr T get_normalized(T raw_value, size_t start_bit, size_t length) { - return crop_value((raw_value & range_mask(start_bit, length)) >> start_bit, length); + return helper::crop_value((raw_value & helper::range_mask(start_bit, length)) >> start_bit, length); + } + + template + static constexpr T get_normalized(T raw_value, BitRange range) { + return get_normalized(raw_value, range.pos, range.length); } } diff --git a/include/PSX/Auxiliary/complex_bitmap.hpp b/include/PSX/Auxiliary/complex_bitmap.hpp index b1a6bb64..4709a4b7 100644 --- a/include/PSX/Auxiliary/complex_bitmap.hpp +++ b/include/PSX/Auxiliary/complex_bitmap.hpp @@ -3,208 +3,6 @@ #include "bits.hpp" namespace JabyEngine { - struct ClearBitValue { - size_t bit; - - constexpr ClearBitValue(size_t bit) : bit(bit) { - } - }; - - template - struct Bit { - typedef T ValueType; - - size_t value; - - constexpr Bit(size_t value) : value(value) { - } - - constexpr operator size_t() const { - return this->value; - } - - constexpr ClearBitValue operator!() const { - return ClearBitValue(this->value); - } - }; - - template - struct BitRangeValue { - T value; - size_t begin; - size_t length; - - constexpr BitRangeValue() = default; - constexpr BitRangeValue(T value, size_t begin, size_t length) : value(value), begin(begin), length(length) { - } - }; - - template - struct BitRange { - typedef T ValueType; - - size_t begin; - size_t length; - - static constexpr BitRange from_to(size_t start, size_t end) { - return {start, (end - start + 1)}; - } - - constexpr BitRangeValue with(T value) const { - return BitRangeValue(value, this->begin, this->length); - } - - constexpr BitRangeValue max() const { - return BitRange::with((1 << this->length) - 1); - } - }; - - template - static constexpr __always_inline BitRangeValue operator<<(const BitRange& range, T value) { - return BitRangeValue{value, range.begin, range.length}; - } - - template - class ComplexBitMap { - public: - typedef T UnderlyingType; - T raw; - - private: - template - constexpr __always_inline ComplexBitMap& set_va(const S& value) { - return this->set(value); - } - - template - constexpr __always_inline ComplexBitMap& set_va(const S& value, const ARGS&...args) { - return this->set_va(value).set_va(args...); - } - - public: - template - static constexpr __always_inline ComplexBitMap with(ARGS...args) { - return ComplexBitMap().set_va(args...); - } - - //Accesssing bits - template - constexpr ComplexBitMap& set_bit(S bit) { - this->raw = bit::set(this->raw, static_cast(bit)); - return *this; - } - - template - constexpr void set_bit(S bit) volatile { - this->raw = bit::set(this->raw, static_cast(bit)); - } - - template - constexpr ComplexBitMap& clear_bit(S bit) { - this->raw = bit::clear(this->raw, static_cast(bit)); - return *this; - } - - template - constexpr void clear_bit(S bit) volatile { - this->raw = bit::clear(this->raw, static_cast(bit)); - } - - template - constexpr bool is_bit_set(S bit) { - return bit::is_set(this->raw, static_cast(bit)); - } - - template - constexpr bool is_bit_set(S bit) const volatile { - return bit::is_set(this->raw, static_cast(bit)); - } - - //Accessing values - template - constexpr ComplexBitMap& set_value(S value, const BitRange& range) { - this->raw = bit::value::set_normalized(this->raw, static_cast(value), range.begin, range.length); - return *this; - } - - template - constexpr void set_value(S value, const BitRange& range) volatile { - this->raw = bit::value::set_normalized(this->raw, static_cast(value), range.begin, range.length); - } - - template - constexpr ComplexBitMap& clear_value(const BitRange& range) { - this->raw = bit::value::clear_normalized(this->raw, range.begin, range.length); - return *this; - } - - template - constexpr void clear_value(const BitRange& range) volatile { - this->raw = bit::value::clear_normalized(this->raw, range.begin, range.length); - } - - template - constexpr S get_value(const BitRange& range) const { - return static_cast(bit::value::get_normalized(this->raw, range.begin, range.length)); - } - - template - constexpr S get_value(const BitRange& range) const volatile { - return static_cast(bit::value::get_normalized(this->raw, range.begin, range.length)); - } - - //For easier checking - constexpr bool is(Bit bit) const { - return ComplexBitMap::is_bit_set(bit); - } - - constexpr bool is(Bit bit) const volatile { - return ComplexBitMap::is_bit_set(bit); - } - - // For easier constructing - template - constexpr __always_inline ComplexBitMap& set(const BitRange& range, T value) { - this->set_value(value, range); - return *this; - } - - template - constexpr __always_inline ComplexBitMap& set(const BitRangeValue& value) { - this->set_value(value.value, {value.begin, value.length}); - return *this; - } - - template - constexpr __always_inline ComplexBitMap& set(const Bit& bit) { - this->set_bit(bit.value); - return *this; - } - - constexpr __always_inline ComplexBitMap& set(const ClearBitValue& value) { - this->clear_bit(value.bit); - return *this; - } - - constexpr __always_inline ComplexBitMap& operator|(const BitRangeValue& value) { - this->set_value(value.value, value.range); - return *this; - } - - constexpr __always_inline ComplexBitMap& operator|(const Bit& bit) { - this->set_bit(bit.value); - return *this; - } - - constexpr __always_inline ComplexBitMap& operator|(const ClearBitValue& value) { - this->clear_bit(value.bit); - return *this; - } - - constexpr __always_inline operator T() const { - return this->raw; - } - }; } #endif //!__JABYENGINE_COMPLEX_BITMAP_HPP__ \ No newline at end of file diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index 6f353d7c..77e420e6 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -4,33 +4,35 @@ #include "../jabyengine_defines.h" namespace JabyEngine { - struct __no_align SimpleTIM : private ComplexBitMap { - static constexpr auto TextureX = BitRange(0, 8); - static constexpr auto TextureY = BitRange(9, 16); - static constexpr auto ClutX = BitRange(17, 22); - static constexpr auto ClutY = BitRange(23, 31); + struct __no_align SimpleTIM { + static constexpr auto TextureX = BitRange::from_to(0, 8); + static constexpr auto TextureY = BitRange::from_to(9, 16); + static constexpr auto ClutX = BitRange::from_to(17, 22); + static constexpr auto ClutY = BitRange::from_to(23, 31); + + uint32_t raw; constexpr SimpleTIM() { this->raw = 0; } - constexpr SimpleTIM(uint16_t texX, uint16_t texY, uint16_t clutX, uint16_t clutY) : ComplexBitMap(ComplexBitMap::with(TextureX.with(texX >> 1), TextureY.with(texY >> 1), ClutX.with(clutX >> 4), ClutY.with(clutY))) { + constexpr SimpleTIM(uint16_t texX, uint16_t texY, uint16_t clutX, uint16_t clutY) : raw(TextureX.as_value(texX >> 1) | TextureY.as_value(texY >> 1) | ClutX.as_value(clutX >> 4) | ClutY.as_value(clutY)) { } constexpr uint16_t getTextureX() const { - return (ComplexBitMap::get_value(SimpleTIM::TextureX) << 1); + return bit::value::get_normalized(this->raw, TextureX) << 1; } constexpr uint16_t getTextureY() const { - return (ComplexBitMap::get_value(SimpleTIM::TextureY) << 1); + return bit::value::get_normalized(this->raw, TextureY) << 1; } constexpr uint16_t getClutX() const { - return (ComplexBitMap::get_value(SimpleTIM::ClutX) << 4); + return bit::value::get_normalized(this->raw, SimpleTIM::ClutX) << 4; } constexpr uint16_t getClutY() const { - return ComplexBitMap::get_value(SimpleTIM::ClutY); + return bit::value::get_normalized(this->raw, ClutY); } }; diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 814f7370..79bce891 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -41,12 +41,12 @@ namespace JabyEngine { class Color { private: - static constexpr auto RedRange = BitRange::from_to(0, 4); - static constexpr auto GreenRange = BitRange::from_to(5, 9); - static constexpr auto BlueRange = BitRange::from_to(10, 14); - static constexpr auto SemiTransperancyBit = Bit(15); + static constexpr auto RedRange = BitRange::from_to(0, 4); + static constexpr auto GreenRange = BitRange::from_to(5, 9); + static constexpr auto BlueRange = BitRange::from_to(10, 14); + static constexpr auto SemiTransperancyBit = Bit(15); - ComplexBitMap value = {0}; + uint16_t value = 0; public: static constexpr Color from_rgb(uint8_t r, uint8_t g, uint8_t b) { @@ -58,17 +58,17 @@ namespace JabyEngine { } constexpr Color& set_red(uint8_t red) { - this->value.set_value(static_cast(red), RedRange); + this->value = bit::value::set_normalized(this->value, RedRange.with(red)); return *this; } constexpr Color& set_green(uint8_t green) { - this->value.set_value(static_cast(green), GreenRange); + this->value = bit::value::set_normalized(this->value, GreenRange.with(green)); return *this; } constexpr Color& set_blue(uint8_t blue) { - this->value.set_value(static_cast(blue), BlueRange); + this->value = bit::value::set_normalized(this->value, BlueRange.with(blue)); return *this; } }; diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index 9e3ba268..e6d2c36c 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -32,41 +32,41 @@ namespace JabyEngine { }; __declare_io_type(IndexStatus, uint8_t, - static constexpr auto PortIndex = IOValueSet::from_to(0, 1); - static constexpr auto HasXAFifoData = IOBitSet(2); - static constexpr auto IsParameterFifoEmpty = IOBitSet(3); - static constexpr auto HasParameterFifoSpace = IOBitSet(4); - static constexpr auto HasResponseFifoData = IOBitSet(5); - static constexpr auto HasDataFifoData = IOBitSet(6); - static constexpr auto IsTransmissionBusy = IOBitSet(7); + static constexpr auto PortIndex = BitRange::from_to(0, 1); + static constexpr auto HasXAFifoData = Bit(2); + static constexpr auto IsParameterFifoEmpty = Bit(3); + static constexpr auto HasParameterFifoSpace = Bit(4); + static constexpr auto HasResponseFifoData = Bit(5); + static constexpr auto HasDataFifoData = Bit(6); + static constexpr auto IsTransmissionBusy = Bit(7); ); __declare_io_type(InterruptEnable, uint8_t, - static constexpr auto InterruptTypValue = IOValueSet::from_to(0, 2); - static constexpr auto InterruptExtended = IOValueSet::from_to(0, 4); - static constexpr auto UnknownIRQ = IOBitSet(3); - static constexpr auto CommandStartIRQ = IOBitSet(4); + static constexpr auto InterruptTypValue = BitRange::from_to(0, 2); + static constexpr auto InterruptExtended = BitRange::from_to(0, 4); + static constexpr auto UnknownIRQ = Bit(3); + static constexpr auto CommandStartIRQ = Bit(4); ); typedef InterruptEnable_v InterruptFlag_v; __declare_io_type(Request, uint8_t, - static constexpr auto WantCommandStartIRQ = IOBitSet(5); - static constexpr auto WantData = IOBitSet(7); + static constexpr auto WantCommandStartIRQ = Bit(5); + static constexpr auto WantData = Bit(7); ); __declare_io_type(SoundMapCoding, uint8_t, - static constexpr auto Stereo = IOBitSet(0); + static constexpr auto Stereo = Bit(0); static constexpr auto Mono = !Stereo; - static constexpr auto SampleRate_18900hz = IOBitSet(2); + static constexpr auto SampleRate_18900hz = Bit(2); static constexpr auto SampleRate_37800hz = !SampleRate_18900hz; - static constexpr auto BitsPerSample8 = IOBitSet(4); + static constexpr auto BitsPerSample8 = Bit(4); static constexpr auto BitsPerSample4 = !BitsPerSample8; - static constexpr auto Emphasis = IOBitSet(6); + static constexpr auto Emphasis = Bit(6); ); __declare_io_type(AudioVolumeApply, uint8_t, - static constexpr auto Mute = IOBitSet(0); - static constexpr auto ApplyChanges = IOBitSet(5); + static constexpr auto Mute = Bit(0); + static constexpr auto ApplyChanges = Bit(5); ); __declare_io_type(ResponseFifo, uint8_t,); diff --git a/include/PSX/System/IOPorts/dma_io.hpp b/include/PSX/System/IOPorts/dma_io.hpp index 8af6a4f8..c17b54b9 100644 --- a/include/PSX/System/IOPorts/dma_io.hpp +++ b/include/PSX/System/IOPorts/dma_io.hpp @@ -5,18 +5,18 @@ namespace JabyEngine { namespace DMA_IO { __declare_io_type(MADR, uint32_t, - static constexpr auto MemoryAdr = IOValueSet::from_to(0, 23); + static constexpr auto MemoryAdr = BitRange::from_to(0, 23); ); __declare_io_type(BCR, uint32_t, - struct __no_align SyncMode0 { - static constexpr auto NumberOfWords = IOValueSet::from_to(0, 15); - static constexpr auto CD_OneBlock = IOBitSet(16); + struct SyncMode0 { + static constexpr auto NumberOfWords = BitRange::from_to(0, 15); + static constexpr auto CD_OneBlock = Bit(16); }; - struct SyncMode1 : public ComplexBitMap { - static constexpr auto BlockSize = IOValueSet::from_to(0, 15); - static constexpr auto BlockAmount = IOValueSet::from_to(16, 31); + struct SyncMode1 { + static constexpr auto BlockSize = BitRange::from_to(0, 15); + static constexpr auto BlockAmount = BitRange::from_to(16, 31); }; struct SyncMode2 { @@ -30,25 +30,25 @@ namespace JabyEngine { Sync2 = 2, //Linked List }; - static constexpr auto ManualStart = IOBitSet(28); + static constexpr auto ManualStart = Bit(28); - static constexpr auto Start = IOBitSet(24); + static constexpr auto Start = Bit(24); static constexpr auto Busy = Start; - static constexpr auto ChoppingCPUWindowSize = IOValueSet::from_to(20, 22); - static constexpr auto ChoppingDMAWindowSize = IOValueSet::from_to(16, 18); + static constexpr auto ChoppingCPUWindowSize = BitRange::from_to(20, 22); + static constexpr auto ChoppingDMAWindowSize = BitRange::from_to(16, 18); - static constexpr auto SyncMode = IOValueSet::from_to(9, 10); + static constexpr auto SyncMode = BitRange::from_to(9, 10); static constexpr auto UseSyncMode0 = SyncMode.with(Sync0); static constexpr auto UseSyncMode1 = SyncMode.with(Sync1); static constexpr auto UseSyncMode2 = SyncMode.with(Sync2); - static constexpr auto UseChopping = IOBitSet(8); + static constexpr auto UseChopping = Bit(8); - static constexpr auto MemoryAdrDecreaseBy4 = IOBitSet(1); + static constexpr auto MemoryAdrDecreaseBy4 = Bit(1); static constexpr auto MemoryAdrIncreaseBy4 = !MemoryAdrDecreaseBy4; - static constexpr auto FromMainRAM = IOBitSet(0); + static constexpr auto FromMainRAM = Bit(0); static constexpr auto ToMainRAM = !FromMainRAM; static constexpr Self StartMDECin() { @@ -105,34 +105,34 @@ namespace JabyEngine { static constexpr Priority LowestPriority = 7; __declare_io_type(DPCR, uint32_t, - static constexpr auto OTCEnable = IOBitSet(27); - static constexpr auto OTCPriority = IOValueSet::from_to(24, 26); + static constexpr auto OTCEnable = Bit(27); + static constexpr auto OTCPriority = BitRange::from_to(24, 26); - static constexpr auto PIOEnable = IOBitSet(23); - static constexpr auto PIOPriority = IOValueSet::from_to(20, 22); + static constexpr auto PIOEnable = Bit(23); + static constexpr auto PIOPriority = BitRange::from_to(20, 22); - static constexpr auto SPUEnable = IOBitSet(19); - static constexpr auto SPUPriority = IOValueSet::from_to(16, 18); + static constexpr auto SPUEnable = Bit(19); + static constexpr auto SPUPriority = BitRange::from_to(16, 18); - static constexpr auto CDROMEnable = IOBitSet(15); - static constexpr auto CDROMPriority = IOValueSet::from_to(12, 14); + static constexpr auto CDROMEnable = Bit(15); + static constexpr auto CDROMPriority = BitRange::from_to(12, 14); - static constexpr auto GPUEnable = IOBitSet(11); - static constexpr auto GPUPriority = IOValueSet::from_to(8, 10); + static constexpr auto GPUEnable = Bit(11); + static constexpr auto GPUPriority = BitRange::from_to(8, 10); - static constexpr auto MDECoutEnable = IOBitSet(7); - static constexpr auto MDECoutPriority = IOValueSet::from_to(4, 6); + static constexpr auto MDECoutEnable = Bit(7); + static constexpr auto MDECoutPriority = BitRange::from_to(4, 6); - static constexpr auto MDECinEnable = IOBitSet(3); - static constexpr auto MDECinPriority = IOValueSet::from_to(0, 2); + static constexpr auto MDECinEnable = Bit(3); + static constexpr auto MDECinPriority = BitRange::from_to(0, 2); ); __declare_io_type(DICR, uint32_t, - static constexpr auto MasterEnable = IOBitSet(31); - static constexpr auto Flags = IOValueSet::from_to(24, 30); - static constexpr auto MasterEnableDPCR = IOBitSet(23); - static constexpr auto EnableDPCR = IOValueSet::from_to(16, 22); - static constexpr auto ForceIRQ = IOBitSet(15); + static constexpr auto MasterEnable = Bit(31); + static constexpr auto Flags = BitRange::from_to(24, 30); + static constexpr auto MasterEnableDPCR = Bit(23); + static constexpr auto EnableDPCR = BitRange::from_to(16, 22); + static constexpr auto ForceIRQ = Bit(15); ); __declare_new_io_port(MDECin, 0x1F801080); diff --git a/include/PSX/System/IOPorts/gpu_io.hpp b/include/PSX/System/IOPorts/gpu_io.hpp index b4ede548..43d93dfb 100644 --- a/include/PSX/System/IOPorts/gpu_io.hpp +++ b/include/PSX/System/IOPorts/gpu_io.hpp @@ -53,12 +53,12 @@ namespace JabyEngine { PAL = 1, }; - static constexpr auto HorizontalResolution368 = IOBitSet(6); - static constexpr auto VerticalInterlace = IOBitSet(5); - static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(4, 4); - static constexpr auto VideoMode = IOValueSet::from_to(3, 3); - static constexpr auto VerticalResolution = IOValueSet::from_to(2, 2); - static constexpr auto HorizontalResolution = IOValueSet::from_to(0, 1); + static constexpr auto HorizontalResolution368 = Bit(6); + static constexpr auto VerticalInterlace = Bit(5); + static constexpr auto DisplayAreaColorDepth = BitRange::from_to(4, 4); + static constexpr auto VideoMode = BitRange::from_to(3, 3); + static constexpr auto VerticalResolution = BitRange::from_to(2, 2); + static constexpr auto HorizontalResolution = BitRange::from_to(0, 1); static constexpr Self PAL() { return Self::from( @@ -86,12 +86,12 @@ namespace JabyEngine { ); - struct Command { + struct Command { struct Helper { static constexpr GP0_t DrawAreaTemplate(uint8_t code, uint16_t x, uint16_t y) { - constexpr auto Command = IOValueSet::from_to(24, 31); - constexpr auto Y = IOValueSet::from_to(10, 18); - constexpr auto X = IOValueSet::from_to(0, 9); + constexpr auto Command = BitRange::from_to(24, 31); + constexpr auto Y = BitRange::from_to(10, 18); + constexpr auto X = BitRange::from_to(0, 9); return GP0_t::from(Command.with(code), Y.with(y), X.with(x)); } @@ -142,24 +142,24 @@ namespace JabyEngine { } static constexpr GP1_t DisplayArea(uint16_t x, uint16_t y) { - constexpr auto X = BitRange::from_to(0, 9); - constexpr auto Y = BitRange::from_to(10, 18); + constexpr auto X = BitRange::from_to(0, 9); + constexpr auto Y = BitRange::from_to(10, 18); - return {Helper::construct_cmd(0x05, ComplexBitMap::with(X.with(x), Y.with(y)).raw)}; + return {Helper::construct_cmd(0x05, X.as_value(x) | Y.as_value(y))}; } static constexpr GP1_t HorizontalDisplayRange(uint32_t x1, uint32_t x2) { - constexpr auto X1 = BitRange::from_to(0, 11); - constexpr auto X2 = BitRange::from_to(12, 23); + constexpr auto X1 = BitRange::from_to(0, 11); + constexpr auto X2 = BitRange::from_to(12, 23); - return {Helper::construct_cmd(0x06, ComplexBitMap::with(X1.with(x1), X2.with(x2)).raw)}; + return {Helper::construct_cmd(0x06, X1.as_value(x1) | X2.as_value(x2))}; } static constexpr GP1_t VerticalDisplayRange(uint32_t y1, uint32_t y2) { - constexpr auto Y1 = BitRange::from_to(0, 9); - constexpr auto Y2 = BitRange::from_to(10, 19); + constexpr auto Y1 = BitRange::from_to(0, 9); + constexpr auto Y2 = BitRange::from_to(10, 19); - return {Helper::construct_cmd(0x07, ComplexBitMap::with(Y1.with(y1), Y2.with(y2)).raw)}; + return {Helper::construct_cmd(0x07, Y1.as_value(y1) | Y2.as_value(y2))}; } static constexpr GP1_t DisplayMode(DisplayMode_t mode) { @@ -168,32 +168,32 @@ namespace JabyEngine { }; __declare_io_type(GPUSTAT, uint32_t, - static constexpr auto DrawingOddLinesInterlaced = IOBitSet(31); - static constexpr auto DMADirectionValue = IOValueSet::from_to(29, 30); - static constexpr auto DMAReady = IOBitSet(28); - static constexpr auto VRAMtoCPUtransferReay = IOBitSet(27); - static constexpr auto GP0ReadyForCMD = IOBitSet(26); - static constexpr auto FifoNotFull = IOBitSet(25); // Only for Fifo - static constexpr auto InterruptRequest = IOBitSet(24); - static constexpr auto DisplayDisabled = IOBitSet(23); - static constexpr auto VerticalInterlaceOn = IOBitSet(22); - static constexpr auto DisplayAreaColorDepth = IOValueSet::from_to(21, 21); - static constexpr auto VideoModePal = IOBitSet(20); - static constexpr auto VerticalResolutionValue = IOValueSet::from_to(19, 19); - static constexpr auto HorizontalResolutionValue = IOValueSet::from_to(17, 18); - static constexpr auto HorizontalResolution368 = IOBitSet(16); - static constexpr auto TexturesDisabled = IOBitSet(15); - static constexpr auto NotDrawingMaskedPixels = IOBitSet(12); - static constexpr auto MaskBitSetDuringDrawEnabled = IOBitSet(11); - static constexpr auto DrawingToDisplayAreadAllowed = IOBitSet(10); - static constexpr auto DitherEnabled = IOBitSet(9); - static constexpr auto TexturePageColorValue = IOValueSet::from_to(7, 8); - static constexpr auto SemiTransparencyValue = IOValueSet::from_to(5, 6); - static constexpr auto TexturePageY = IOValueSet::from_to(4, 4); // N*256 - static constexpr auto TexturePageX = IOValueSet::from_to(0, 3); // N*64 + static constexpr auto DrawingOddLinesInterlaced = Bit(31); + static constexpr auto DMADirectionValue = BitRange::from_to(29, 30); + static constexpr auto DMAReady = Bit(28); + static constexpr auto VRAMtoCPUtransferReay = Bit(27); + static constexpr auto GP0ReadyForCMD = Bit(26); + static constexpr auto FifoNotFull = Bit(25); // Only for Fifo + static constexpr auto InterruptRequest = Bit(24); + static constexpr auto DisplayDisabled = Bit(23); + static constexpr auto VerticalInterlaceOn = Bit(22); + static constexpr auto DisplayAreaColorDepth = BitRange::from_to(21, 21); + static constexpr auto VideoModePal = Bit(20); + static constexpr auto VerticalResolutionValue = BitRange::from_to(19, 19); + static constexpr auto HorizontalResolutionValue = BitRange::from_to(17, 18); + static constexpr auto HorizontalResolution368 = Bit(16); + static constexpr auto TexturesDisabled = Bit(15); + static constexpr auto NotDrawingMaskedPixels = Bit(12); + static constexpr auto MaskBitSetDuringDrawEnabled = Bit(11); + static constexpr auto DrawingToDisplayAreadAllowed = Bit(10); + static constexpr auto DitherEnabled = Bit(9); + static constexpr auto TexturePageColorValue = BitRange::from_to(7, 8); + static constexpr auto SemiTransparencyValue = BitRange::from_to(5, 6); + static constexpr auto TexturePageY = BitRange::from_to(4, 4); // N*256 + static constexpr auto TexturePageX = BitRange::from_to(0, 3); // N*64 - static constexpr auto VerticalResolution480 = IOBitSet(19); - static constexpr auto TexturePageY256 = IOBitSet(4); + static constexpr auto VerticalResolution480 = Bit(19); + static constexpr auto TexturePageY256 = Bit(4); ); typedef volatile uint32_t GPUREAD_v; diff --git a/include/PSX/System/IOPorts/interrupt_io.hpp b/include/PSX/System/IOPorts/interrupt_io.hpp index 4586d619..83683d39 100644 --- a/include/PSX/System/IOPorts/interrupt_io.hpp +++ b/include/PSX/System/IOPorts/interrupt_io.hpp @@ -4,17 +4,17 @@ namespace JabyEngine { struct Interrupt { - static constexpr auto VBlank = IOBitSet(0); - static constexpr auto GPU = IOBitSet(1); - static constexpr auto CDROM = IOBitSet(2); - static constexpr auto DMA = IOBitSet(3); - static constexpr auto Timer0 = IOBitSet(4); - static constexpr auto Timer1 = IOBitSet(5); - static constexpr auto Timer2 = IOBitSet(6); - static constexpr auto Periphery = IOBitSet(7); - static constexpr auto SIO = IOBitSet(8); - static constexpr auto SPU = IOBitSet(9); - static constexpr auto Controller = IOBitSet(10); + static constexpr auto VBlank = Bit(0); + static constexpr auto GPU = Bit(1); + static constexpr auto CDROM = Bit(2); + static constexpr auto DMA = Bit(3); + static constexpr auto Timer0 = Bit(4); + static constexpr auto Timer1 = Bit(5); + static constexpr auto Timer2 = Bit(6); + static constexpr auto Periphery = Bit(7); + static constexpr auto SIO = Bit(8); + static constexpr auto SPU = Bit(9); + static constexpr auto Controller = Bit(10); static constexpr auto LightPen = Controller; __declare_io_type(Status, uint32_t, @@ -26,19 +26,19 @@ namespace JabyEngine { __declare_new_io_port(Status, 0x1F801070); __declare_new_io_port(Mask, 0x1F801074); - static constexpr bool is_irq(IOBitSet irq) { + static constexpr bool is_irq(Bit irq) { return Status.is_set(irq); } - static constexpr void ack_irq(IOBitSet irq) { + static constexpr void ack_irq(Bit irq) { Status.clear(irq); } - static constexpr void disable_irq(IOBitSet irq) { + static constexpr void disable_irq(Bit irq) { Mask.clear(irq); } - static void enable_irq(IOBitSet irq) { + static void enable_irq(Bit irq) { Mask.set(irq); } }; diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 6719a2c2..7daf0627 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -4,49 +4,6 @@ #include "../../Auxiliary/types.hpp" namespace JabyEngine { - struct IOBitUnset { - uint16_t pos; - - constexpr IOBitUnset(uint16_t bit_pos) : pos(bit_pos) { - } - }; - - struct IOBitSet { - uint16_t pos; - - constexpr IOBitSet(uint16_t bit_pos) : pos(bit_pos) { - } - - constexpr IOBitUnset operator!() const { - return IOBitUnset(this->pos); - } - }; - - struct IOValueSet { - template - using IOValueSetPair = pair; - - uint16_t pos; - uint16_t length; - - constexpr IOValueSet(uint16_t pos, uint16_t length) : pos(pos), length(length) { - } - - static constexpr IOValueSet from_to(uint16_t first_bit, uint16_t last_bit) { - return IOValueSet(first_bit, (last_bit - first_bit) + 1); - } - - template - constexpr IOValueSetPair with(T value) const { - return {*this, value}; - } - - template - constexpr IOValueSetPair range_max() const { - return IOValueSet::with((1 << this->length) - 1); - } - }; - namespace IOPort { struct IOValueType { template @@ -91,24 +48,24 @@ namespace JabyEngine { return Self().set_va(args...); \ } \ \ - constexpr Self& set(IOBitSet bit) { \ - this->raw_value = bit::set(this->raw_value, bit.pos); \ + constexpr Self& set(Bit bit) { \ + this->raw_value = bit::set(this->raw_value, bit); \ return *this; \ } \ \ - constexpr Self& set(IOBitUnset bit) { \ - this->raw_value = bit::clear(this->raw_value, bit.pos); \ + constexpr Self& set(ClearBit bit) { \ + this->raw_value = bit::set(this->raw_value, bit); \ return *this; \ } \ \ - constexpr Self& set(IOValueSet bits, UnderlyingValue value) { \ - this->raw_value = bit::value::set_normalized(this->raw_value, value, bits.pos, bits.length); \ + constexpr Self& set(BitRange bits, UnderlyingValue value) { \ + this->raw_value = bit::value::set_normalized(this->raw_value, bits, value); \ return *this; \ } \ \ template \ - constexpr Self& set(const IOValueSet::IOValueSetPair& value) { \ - this->set(value.first, static_cast(value.second)); \ + constexpr Self& set(const BitRange::RangeValuePair& value) { \ + this->raw_value = bit::value::set_normalized(this->raw_value, value); \ return *this; \ } \ \ @@ -122,17 +79,17 @@ namespace JabyEngine { return this->set(head).set_va(tail...); \ } \ \ - constexpr UnderlyingValue get(IOValueSet bits) const { \ + constexpr UnderlyingValue get(BitRange bits) const { \ return bit::value::get_normalized(this->raw_value, bits.pos, bits.length); \ } \ \ - constexpr Self& clear(IOBitSet bit) { \ - this->raw_value = bit::clear(this->raw_value, bit.pos); \ + constexpr Self& clear(Bit bit) { \ + this->raw_value = bit::clear(this->raw_value, bit); \ return *this; \ } \ \ - constexpr bool is_set(IOBitSet bit) const { \ - return bit::is_set(this->raw_value, bit.pos); \ + constexpr bool is_set(Bit bit) const { \ + return bit::is_set(this->raw_value, bit); \ } \ \ constexpr void operator=(UnderlyingValue value) { \ @@ -160,38 +117,6 @@ namespace JabyEngine { } }; - // For use with ComplexBitMaps or what else satisfies this API - template - struct VolatileBitMapPOD { - typedef typename T::UnderlyingType Raw; - - VolatilePOD pod; - - constexpr Raw read_raw() const { - return this->pod.read(); - } - - constexpr T read() const { - return T{this->pod.read()}; - } - - constexpr Raw read(const BitRange& range) const { - return VolatileBitMapPOD::read().get_value(range); - } - - constexpr void write_raw(Raw value) { - this->pod.write(value); - } - - constexpr void write(const T& value) { - this->pod.write(static_cast(value)); - } - - constexpr void write(const BitRangeValue& value) { - VolatileBitMapPOD::write(T{T::with(value)}); - } - }; - struct __no_align ubus32_t { __declare_io_type(uint16_t, uint16_t,); uint16_t_v low; diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index b5451779..e5450ccb 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -42,33 +42,33 @@ namespace JabyEngine { __declare_io_type(SweepVolume, int16_t, // For Volume Mode - static constexpr auto SweepEnable = IOBitSet(15); + static constexpr auto SweepEnable = Bit(15); static constexpr auto VolumeEnable = !SweepEnable; - static constexpr auto Volume = IOValueSet::from_to(0, 14); + static constexpr auto Volume = BitRange::from_to(0, 14); // For Sweep Mode - static constexpr auto SweepMode = IOBitSet(14); - static constexpr auto SweepDirection = IOBitSet(13); - static constexpr auto SweepPhase = IOBitSet(12); - static constexpr auto SweepShift = IOValueSet::from_to(2, 6); - static constexpr auto SweepStep = IOValueSet::from_to(0, 1); + static constexpr auto SweepMode = Bit(14); + static constexpr auto SweepDirection = Bit(13); + static constexpr auto SweepPhase = Bit(12); + static constexpr auto SweepShift = BitRange::from_to(2, 6); + static constexpr auto SweepStep = BitRange::from_to(0, 1); ); __declare_io_type(SR, uint16_t, - static constexpr auto SustainMode = IOBitSet(31 - 16); - static constexpr auto SustainDirection = IOBitSet(30 - 16); - static constexpr auto SustainShift = IOValueSet::from_to((24 - 16), (28 - 16)); - static constexpr auto SustainStep = IOValueSet::from_to((22 - 16), (23 - 16)); - static constexpr auto ReleaseMode = IOBitSet(21 - 16); - static constexpr auto ReleaseShift = IOValueSet::from_to((16 - 16), (20 - 16)); + static constexpr auto SustainMode = Bit(31 - 16); + static constexpr auto SustainDirection = Bit(30 - 16); + static constexpr auto SustainShift = BitRange::from_to((24 - 16), (28 - 16)); + static constexpr auto SustainStep = BitRange::from_to((22 - 16), (23 - 16)); + static constexpr auto ReleaseMode = Bit(21 - 16); + static constexpr auto ReleaseShift = BitRange::from_to((16 - 16), (20 - 16)); ); __declare_io_type(AD, uint16_t, - static constexpr auto AttackMode = IOBitSet(15); - static constexpr auto AttackShift = IOValueSet::from_to(10, 14); - static constexpr auto AttackStep = IOValueSet::from_to(8, 9); - static constexpr auto DecayShift = IOValueSet::from_to(4, 7); - static constexpr auto SustainLevel = IOValueSet::from_to(0, 3); + static constexpr auto AttackMode = Bit(15); + static constexpr auto AttackShift = BitRange::from_to(10, 14); + static constexpr auto AttackStep = BitRange::from_to(8, 9); + static constexpr auto DecayShift = BitRange::from_to(4, 7); + static constexpr auto SustainLevel = BitRange::from_to(0, 3); ); struct __no_align Voice_v { @@ -90,29 +90,29 @@ namespace JabyEngine { DMARead = 3 }; - static constexpr auto Enable = IOBitSet(15); - static constexpr auto Unmute = IOBitSet(14); - static constexpr auto NoiseFrequcenyShift = IOValueSet::from_to(10, 13); - static constexpr auto NoiseFrequcenyStep = IOValueSet::from_to(8, 9); - static constexpr auto ReverbMasterEnable = IOBitSet(7); - static constexpr auto IRQ9Enable = IOBitSet(6); - static constexpr auto TransferMode = IOValueSet::from_to(4, 5); - static constexpr auto ExternalAudioReverb = IOBitSet(3); - static constexpr auto CDAudioReverb = IOBitSet(2); - static constexpr auto ExternalAudioEnable = IOBitSet(1); - static constexpr auto CDAudioEnable = IOBitSet(0); + static constexpr auto Enable = Bit(15); + static constexpr auto Unmute = Bit(14); + static constexpr auto NoiseFrequcenyShift = BitRange::from_to(10, 13); + static constexpr auto NoiseFrequcenyStep = BitRange::from_to(8, 9); + static constexpr auto ReverbMasterEnable = Bit(7); + static constexpr auto IRQ9Enable = Bit(6); + static constexpr auto TransferMode = BitRange::from_to(4, 5); + static constexpr auto ExternalAudioReverb = Bit(3); + static constexpr auto CDAudioReverb = Bit(2); + static constexpr auto ExternalAudioEnable = Bit(1); + static constexpr auto CDAudioEnable = Bit(0); ); __declare_io_type(PMON, uint16_t, - static constexpr auto EnableBits = IOValueSet::from_to(1, 23); + static constexpr auto EnableBits = BitRange::from_to(1, 23); ); __declare_io_type(NON, uint16_t, - static constexpr auto NoiseBits = IOValueSet::from_to(0, 23); + static constexpr auto NoiseBits = BitRange::from_to(0, 23); ); __declare_io_type(EON, uint16_t, - static constexpr auto EchoBits = IOValueSet::from_to(0, 23); + static constexpr auto EchoBits = BitRange::from_to(0, 23); ); static constexpr size_t VoiceCount = 24; diff --git a/include/PSX/System/IOPorts/timer_io.hpp b/include/PSX/System/IOPorts/timer_io.hpp index 3962f3be..eadd5d44 100644 --- a/include/PSX/System/IOPorts/timer_io.hpp +++ b/include/PSX/System/IOPorts/timer_io.hpp @@ -5,28 +5,28 @@ namespace JabyEngine { namespace Timer_IO { __declare_io_type(CounterMode, uint32_t, - static constexpr auto SyncEnable = IOBitSet(0); + static constexpr auto SyncEnable = Bit(0); static constexpr auto FreeRun = !SyncEnable; - static constexpr auto SyncMode = IOValueSet::from_to(1, 2); - static constexpr auto ResetAfterTarget = IOBitSet(3); - static constexpr auto IRQAtTarget = IOBitSet(4); - static constexpr auto IRQAtMax = IOBitSet(5); - static constexpr auto IRQEveryTime = IOBitSet(6); + static constexpr auto SyncMode = BitRange::from_to(1, 2); + static constexpr auto ResetAfterTarget = Bit(3); + static constexpr auto IRQAtTarget = Bit(4); + static constexpr auto IRQAtMax = Bit(5); + static constexpr auto IRQEveryTime = Bit(6); static constexpr auto IRQOneShot = !IRQEveryTime; - static constexpr auto IRQToggle = IOBitSet(7); + static constexpr auto IRQToggle = Bit(7); static constexpr auto IRQPulse = !IRQToggle; - static constexpr auto ClockSource = IOValueSet::from_to(8, 9); - static constexpr auto HasIRQRequest = IOBitSet(10); - static constexpr auto IsTargetReached = IOBitSet(11); - static constexpr auto IsMaxReached = IOBitSet(12); + static constexpr auto ClockSource = BitRange::from_to(8, 9); + static constexpr auto HasIRQRequest = Bit(10); + static constexpr auto IsTargetReached = Bit(11); + static constexpr auto IsMaxReached = Bit(12); ); __declare_io_type(CounterTarget, uint32_t, - static constexpr auto CounterTargetValue = IOValueSet::from_to(0, 15); + static constexpr auto CounterTargetValue = BitRange::from_to(0, 15); ); __declare_io_type(CounterValue, uint32_t, - static constexpr auto Value = IOValueSet::from_to(0, 15); + static constexpr auto Value = BitRange::from_to(0, 15); ); struct __no_align Counter { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index d6497a07..6edba049 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -7,19 +7,19 @@ namespace JabyEngine { namespace CD { namespace internal { - struct Mode : public ComplexBitMap { - static constexpr auto DoubleSpeed = Bit(7); + __declare_io_type(Mode, uint8_t, + static constexpr auto DoubleSpeed = Bit(7); static constexpr auto SingleSpeed = !DoubleSpeed; - static constexpr auto XADPCM = Bit(6); - static constexpr auto WholeSector = Bit(5); + static constexpr auto XADPCM = Bit(6); + static constexpr auto WholeSector = Bit(5); static constexpr auto DataSector = !WholeSector; - static constexpr auto UseXAFilter = Bit(3); - static constexpr auto AudioPlayIRQ = Bit(2); - static constexpr auto AutoPauseTrack = Bit(1); - static constexpr auto CDDA = Bit(0); - }; + static constexpr auto UseXAFilter = Bit(3); + static constexpr auto AudioPlayIRQ = Bit(2); + static constexpr auto AutoPauseTrack = Bit(1); + static constexpr auto CDDA = Bit(0); + ); - static constexpr auto DataSectorMode = Mode::with(Mode::DoubleSpeed, Mode::DataSector); + static constexpr auto DataSectorMode = Mode_t::from(Mode_t::DoubleSpeed, Mode_t::DataSector); static SectorBufferAllocator sector_allocator; static uint16_t sectors_left; diff --git a/src/Library/src/startup.cpp b/src/Library/src/startup.cpp index cb3e9fae..b99bcf79 100644 --- a/src/Library/src/startup.cpp +++ b/src/Library/src/startup.cpp @@ -10,7 +10,7 @@ namespace JabyEngine { void start() { NextRoutine next_routine = JabyEngine::NextRoutine::from(boot::Start::setup); - printf("Starting Planschbecken 0x%p\n", next_routine.value); + printf("Starting Planschbecken Version 0 0x%p\n", next_routine.value); while(true) { if(next_routine.is_null()) { break; From 0ad664d94c21fc530f53abe08e4b250f95568f20 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 22 Mar 2023 20:54:40 +0100 Subject: [PATCH 18/47] Remove ComplexBitMap header --- include/PSX/Auxiliary/complex_bitmap.hpp | 8 -------- include/PSX/File/file_types.hpp | 1 - include/PSX/GPU/gpu_types.hpp | 1 - include/PSX/System/IOPorts/ioport.hpp | 2 +- 4 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 include/PSX/Auxiliary/complex_bitmap.hpp diff --git a/include/PSX/Auxiliary/complex_bitmap.hpp b/include/PSX/Auxiliary/complex_bitmap.hpp deleted file mode 100644 index 4709a4b7..00000000 --- a/include/PSX/Auxiliary/complex_bitmap.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JABYENGINE_COMPLEX_BITMAP_HPP__ -#define __JABYENGINE_COMPLEX_BITMAP_HPP__ -#include "bits.hpp" - -namespace JabyEngine { -} - -#endif //!__JABYENGINE_COMPLEX_BITMAP_HPP__ \ No newline at end of file diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index 77e420e6..21f428b6 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -1,6 +1,5 @@ #ifndef __JABYENGINE_FILE_TYPES_HPP__ #define __JABYENGINE_FILE_TYPES_HPP__ -#include "../Auxiliary/complex_bitmap.hpp" #include "../jabyengine_defines.h" namespace JabyEngine { diff --git a/include/PSX/GPU/gpu_types.hpp b/include/PSX/GPU/gpu_types.hpp index 79bce891..48bfc0ca 100644 --- a/include/PSX/GPU/gpu_types.hpp +++ b/include/PSX/GPU/gpu_types.hpp @@ -1,7 +1,6 @@ #ifndef __JABYENGINE_GPU_TYPES_HPP__ #define __JABYENGINE_GPU_TYPES_HPP__ #include "../jabyengine_defines.h" -#include "../Auxiliary/complex_bitmap.hpp" namespace JabyEngine { namespace GPU { diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 7daf0627..3e7935c4 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -1,7 +1,7 @@ #ifndef __JABYENGINE_IOPORT_HPP__ #define __JABYENGINE_IOPORT_HPP__ -#include "../../Auxiliary/complex_bitmap.hpp" #include "../../Auxiliary/types.hpp" +#include "../../Auxiliary/bits.hpp" namespace JabyEngine { namespace IOPort { From 159fbc5d9c99be7a46897069302363a73262be7a Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 22 Mar 2023 21:23:52 +0100 Subject: [PATCH 19/47] More cleanup --- include/PSX/System/IOPorts/interrupt_io.hpp | 6 +-- include/PSX/System/IOPorts/ioport.hpp | 45 +++++---------------- include/PSX/System/IOPorts/spu_io.hpp | 8 ++-- 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/include/PSX/System/IOPorts/interrupt_io.hpp b/include/PSX/System/IOPorts/interrupt_io.hpp index 83683d39..cb2aeb3f 100644 --- a/include/PSX/System/IOPorts/interrupt_io.hpp +++ b/include/PSX/System/IOPorts/interrupt_io.hpp @@ -26,15 +26,15 @@ namespace JabyEngine { __declare_new_io_port(Status, 0x1F801070); __declare_new_io_port(Mask, 0x1F801074); - static constexpr bool is_irq(Bit irq) { + static bool is_irq(Bit irq) { return Status.is_set(irq); } - static constexpr void ack_irq(Bit irq) { + static void ack_irq(Bit irq) { Status.clear(irq); } - static constexpr void disable_irq(Bit irq) { + static void disable_irq(Bit irq) { Mask.clear(irq); } diff --git a/include/PSX/System/IOPorts/ioport.hpp b/include/PSX/System/IOPorts/ioport.hpp index 3e7935c4..7120225f 100644 --- a/include/PSX/System/IOPorts/ioport.hpp +++ b/include/PSX/System/IOPorts/ioport.hpp @@ -20,8 +20,17 @@ namespace JabyEngine { }; } + namespace IOAdress { + constexpr uintptr_t patch_adr(uintptr_t adr) { + constexpr uintptr_t Mask = 0xF0000000; + constexpr uintptr_t Base = 0x10000000; // We might want to change this later to 0xB0000000 for caching and stuff (More research needed) + + return (Base + (adr & ~Mask)); + } + } + #define __declare_new_named_io_port(type, name, adr) \ - static inline auto& name = *reinterpret_cast(adr) + static inline auto& name = *reinterpret_cast(IOAdress::patch_adr(adr)) #define __declare_new_io_port(name, adr) \ __declare_new_named_io_port(name, name, adr) @@ -32,8 +41,8 @@ namespace JabyEngine { #define __declare_new_io_port_array(name, adr, size) \ static inline auto& name = reinterpret_cast(*reinterpret_cast(adr)) + // We need this construct to ensure the types end up being a POD - Inheritance doesn't qualify for a POD #define __declare_io_type(name, type, ...) \ - /*We need this type to be a POD sadly*/ \ template typename T> \ struct name##_io_base { \ typedef T::UnderlyingValue UnderlyingValue; \ @@ -104,19 +113,6 @@ namespace JabyEngine { typedef name##_io_base name##_v; \ typedef name##_io_base name##_t - template - struct VolatilePOD { - volatile T raw; - - constexpr T read() const { - return this->raw; - } - - constexpr void write(T value) { - this->raw = value; - } - }; - struct __no_align ubus32_t { __declare_io_type(uint16_t, uint16_t,); uint16_t_v low; @@ -144,24 +140,5 @@ namespace JabyEngine { return *this; } }; - static constexpr uintptr_t IO_Base_Mask = 0xF0000000; - static constexpr uintptr_t IO_Base_Adr = 0x10000000; - - #define __io_port_adr(adr) (IO_Base_Adr + (adr & ~IO_Base_Mask)) - #define __cast_io_adr_with_type(cv, type, name, adr) static __always_inline cv auto& name = *reinterpret_cast(__io_port_adr(adr)) - - - #define __declare_io_port_global(type, name, adr) __cast_io_adr_with_type(, VolatileBitMapPOD, name, adr) - #define __declare_io_port_global_const(type, name, adr) __cast_io_adr_with_type(const, VolatileBitMapPOD, name, adr) - #define __declare_io_port_global_simple(type, name, adr) __cast_io_adr_with_type(, VolatilePOD, name, adr) - #define __declare_io_port_global_const_simple(type, name, adr) __cast_io_adr_with_type(const, VolatilePOD, name, adr) - - #define __declare_io_port_member(type, name, adr) __cast_io_adr_with_type(inline, VolatileBitMapPOD, name, adr) - #define __declare_io_port_member_const(type, name, adr) __cast_io_adr_with_type(const inline, VolatileBitMapPOD, name, adr) - #define __declare_io_port_member_simple(type, name, adr) __cast_io_adr_with_type(inline, VolatilePOD, name, adr) - #define __declare_io_port_member_const_simple(type, name, adr) __cast_io_adr_with_type(const inline, VolatilePOD, name, adr) - - #define __declare_io_port_global_array(type, name, adr, size) static __always_inline auto& name = reinterpret_cast(*reinterpret_cast(__io_port_adr(adr))) - #define __declare_io_port_global_struct(type, name, adr) static __always_inline auto& name = *reinterpret_cast(__io_port_adr(adr)) } #endif //!__JABYENGINE_IOPORT_HPP__ \ No newline at end of file diff --git a/include/PSX/System/IOPorts/spu_io.hpp b/include/PSX/System/IOPorts/spu_io.hpp index e5450ccb..a5edfea0 100644 --- a/include/PSX/System/IOPorts/spu_io.hpp +++ b/include/PSX/System/IOPorts/spu_io.hpp @@ -118,9 +118,11 @@ namespace JabyEngine { static constexpr size_t VoiceCount = 24; struct Key { - __cast_io_adr_with_type(inline, ubus32_t, On, 0x1F801D88); - __cast_io_adr_with_type(inline, ubus32_t, Off, 0x1F801D8C); - __cast_io_adr_with_type(inline, ubus32_t, Status, 0x1F801D9C); + typedef ubus32_t ubus32_v; + + __declare_new_named_io_port(ubus32, On, 0x1F801D88); + __declare_new_named_io_port(ubus32, Off, 0x1F801D8C); + __declare_new_named_io_port(ubus32, Status, 0x1F801D9C); }; struct MainVolume { From a35243053033f706e58b63495869bcff757aac19 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 22 Mar 2023 21:28:38 +0100 Subject: [PATCH 20/47] Try improving workspace structure --- src/Library/Library.code-workspace | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Library/Library.code-workspace b/src/Library/Library.code-workspace index 31e78c26..d95b7e0b 100644 --- a/src/Library/Library.code-workspace +++ b/src/Library/Library.code-workspace @@ -1,13 +1,21 @@ { "folders": [ { - "name": "JabyEngine", - "path": ".", + "name": "Internal Include", + "path": "include" + }, + { + "name": "Internal Source", + "path": "src" }, { "name": "Include", "path": "..\\..\\include" }, + { + "name": "JabyEngine", + "path": ".", + }, { "name": "Root", "path": "..\\.." From e7b9e23132b9874f6e58dce914607fcf682376d8 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 25 Mar 2023 21:02:51 +0100 Subject: [PATCH 21/47] Revert restructure of project settings --- src/Library/Library.code-workspace | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Library/Library.code-workspace b/src/Library/Library.code-workspace index d95b7e0b..31e78c26 100644 --- a/src/Library/Library.code-workspace +++ b/src/Library/Library.code-workspace @@ -1,21 +1,13 @@ { "folders": [ { - "name": "Internal Include", - "path": "include" - }, - { - "name": "Internal Source", - "path": "src" + "name": "JabyEngine", + "path": ".", }, { "name": "Include", "path": "..\\..\\include" }, - { - "name": "JabyEngine", - "path": ".", - }, { "name": "Root", "path": "..\\.." From 1aec7b541eb2ffffe9c019038a8490c3d398b07c Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 26 Mar 2023 14:19:48 +0200 Subject: [PATCH 22/47] Rename include folder to internal-include for easier destinguishing with the JabyEngine include folder --- .../{include => internal-include}/BootLoader/boot_loader.hpp | 0 src/Library/{include => internal-include}/CD/cd_internal.hpp | 0 src/Library/{include => internal-include}/CD/cd_types.hpp | 0 .../{include => internal-include}/GPU/gpu_internal.hpp | 0 src/Library/src/BootLoader/boot_file/main_boot.cpp | 2 +- src/Library/src/BootLoader/boot_file/overlay_boot.cpp | 2 +- src/Library/src/BootLoader/cd_boot.cpp | 4 ++-- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/BootLoader/start_boot.cpp | 2 +- src/Library/src/CD/cd.cpp | 2 +- src/Library/src/File/Processor/cd_file_processor.cpp | 2 +- src/Library/src/File/Processor/tim_processor.cpp | 2 +- src/Library/src/GPU/gpu.cpp | 2 +- src/Library/src/startup.cpp | 4 ++-- 14 files changed, 12 insertions(+), 12 deletions(-) rename src/Library/{include => internal-include}/BootLoader/boot_loader.hpp (100%) rename src/Library/{include => internal-include}/CD/cd_internal.hpp (100%) rename src/Library/{include => internal-include}/CD/cd_types.hpp (100%) rename src/Library/{include => internal-include}/GPU/gpu_internal.hpp (100%) diff --git a/src/Library/include/BootLoader/boot_loader.hpp b/src/Library/internal-include/BootLoader/boot_loader.hpp similarity index 100% rename from src/Library/include/BootLoader/boot_loader.hpp rename to src/Library/internal-include/BootLoader/boot_loader.hpp diff --git a/src/Library/include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp similarity index 100% rename from src/Library/include/CD/cd_internal.hpp rename to src/Library/internal-include/CD/cd_internal.hpp diff --git a/src/Library/include/CD/cd_types.hpp b/src/Library/internal-include/CD/cd_types.hpp similarity index 100% rename from src/Library/include/CD/cd_types.hpp rename to src/Library/internal-include/CD/cd_types.hpp diff --git a/src/Library/include/GPU/gpu_internal.hpp b/src/Library/internal-include/GPU/gpu_internal.hpp similarity index 100% rename from src/Library/include/GPU/gpu_internal.hpp rename to src/Library/internal-include/GPU/gpu_internal.hpp diff --git a/src/Library/src/BootLoader/boot_file/main_boot.cpp b/src/Library/src/BootLoader/boot_file/main_boot.cpp index afd053a1..711ead13 100644 --- a/src/Library/src/BootLoader/boot_file/main_boot.cpp +++ b/src/Library/src/BootLoader/boot_file/main_boot.cpp @@ -1,4 +1,4 @@ -#include "../../../include/BootLoader/boot_loader.hpp" +#include "../../../internal-include/BootLoader/boot_loader.hpp" #include #include diff --git a/src/Library/src/BootLoader/boot_file/overlay_boot.cpp b/src/Library/src/BootLoader/boot_file/overlay_boot.cpp index 0bd5e969..decd2942 100644 --- a/src/Library/src/BootLoader/boot_file/overlay_boot.cpp +++ b/src/Library/src/BootLoader/boot_file/overlay_boot.cpp @@ -1,4 +1,4 @@ -#include "../../../include/BootLoader/boot_loader.hpp" +#include "../../../internal-include/BootLoader/boot_loader.hpp" #include namespace JabyEngine { diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index e52d6ded..37016a89 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -1,5 +1,5 @@ -#include "../../include/BootLoader/boot_loader.hpp" -#include "../../include/CD/cd_internal.hpp" +#include "../../internal-include/BootLoader/boot_loader.hpp" +#include "../../internal-include/CD/cd_internal.hpp" #include #include #include diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index c682a2b6..fa0d97bd 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -1,4 +1,4 @@ -#include "../../include/GPU/gpu_internal.hpp" +#include "../../internal-include/GPU/gpu_internal.hpp" #include #include #include diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 1745006c..94cc51ee 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -1,4 +1,4 @@ -#include "BootLoader/boot_loader.hpp" +#include "../../internal-include/BootLoader/boot_loader.hpp" #include // 2x For setup timing diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 6edba049..f64c7edf 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -1,4 +1,4 @@ -#include "../../include/CD/cd_internal.hpp" +#include "../../internal-include/CD/cd_internal.hpp" #include #include diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 41c79ecd..58a9dd52 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -1,5 +1,5 @@ +#include "../../../internal-include/CD/cd_internal.hpp" #include -#include #include namespace JabyEngine { diff --git a/src/Library/src/File/Processor/tim_processor.cpp b/src/Library/src/File/Processor/tim_processor.cpp index 636a00eb..c9a3eca8 100644 --- a/src/Library/src/File/Processor/tim_processor.cpp +++ b/src/Library/src/File/Processor/tim_processor.cpp @@ -1,4 +1,4 @@ -#include "../../../include/GPU/gpu_internal.hpp" +#include "../../../internal-include/GPU/gpu_internal.hpp" #include "simplehelper.hpp" #include #include diff --git a/src/Library/src/GPU/gpu.cpp b/src/Library/src/GPU/gpu.cpp index de902fd1..b4004e80 100644 --- a/src/Library/src/GPU/gpu.cpp +++ b/src/Library/src/GPU/gpu.cpp @@ -1,4 +1,4 @@ -#include "../include/GPU/gpu_internal.hpp" +#include "../../internal-include/GPU/gpu_internal.hpp" namespace JabyEngine { namespace GPU { diff --git a/src/Library/src/startup.cpp b/src/Library/src/startup.cpp index b99bcf79..78c2ede0 100644 --- a/src/Library/src/startup.cpp +++ b/src/Library/src/startup.cpp @@ -1,4 +1,4 @@ -#include "../include/BootLoader/boot_loader.hpp" +#include "../internal-include/BootLoader/boot_loader.hpp" #include namespace JabyEngine { @@ -10,7 +10,7 @@ namespace JabyEngine { void start() { NextRoutine next_routine = JabyEngine::NextRoutine::from(boot::Start::setup); - printf("Starting Planschbecken Version 0 0x%p\n", next_routine.value); + printf("Starting Planschbecken 0x%p\n", next_routine.value); while(true) { if(next_routine.is_null()) { break; From 50eaedde6a09bdf041b92572f32cd78347cb68af Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 26 Mar 2023 16:42:45 +0200 Subject: [PATCH 23/47] Code ready to obtain data; Doesn't work in No and causes strange errors in DS --- include/PSX/System/IOPorts/cd_io.hpp | 8 ++++ include/PSX/System/IOPorts/dma_io.hpp | 5 +++ src/Library/src/BootLoader/cd_boot.cpp | 3 +- src/Library/src/BootLoader/start_boot.cpp | 6 +-- src/Library/src/CD/cd.cpp | 40 +++++++++++++++---- .../src/File/Processor/cd_file_processor.cpp | 1 + 6 files changed, 51 insertions(+), 12 deletions(-) diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index e6d2c36c..bab6d9ba 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -52,6 +52,14 @@ namespace JabyEngine { __declare_io_type(Request, uint8_t, static constexpr auto WantCommandStartIRQ = Bit(5); static constexpr auto WantData = Bit(7); + + void want_data() { + this->raw_value = Self::set(Self::WantData); + } + + void reset() { + this->raw_value = 0; + } ); __declare_io_type(SoundMapCoding, uint8_t, diff --git a/include/PSX/System/IOPorts/dma_io.hpp b/include/PSX/System/IOPorts/dma_io.hpp index c17b54b9..7f7a1e69 100644 --- a/include/PSX/System/IOPorts/dma_io.hpp +++ b/include/PSX/System/IOPorts/dma_io.hpp @@ -12,6 +12,11 @@ namespace JabyEngine { struct SyncMode0 { static constexpr auto NumberOfWords = BitRange::from_to(0, 15); static constexpr auto CD_OneBlock = Bit(16); + + static constexpr Self for_cd() { + // v Should be replaced with a named constant + return Self::from(SyncMode0::CD_OneBlock, SyncMode0::NumberOfWords.with(512)); + } }; struct SyncMode1 { diff --git a/src/Library/src/BootLoader/cd_boot.cpp b/src/Library/src/BootLoader/cd_boot.cpp index 37016a89..24da5b48 100644 --- a/src/Library/src/BootLoader/cd_boot.cpp +++ b/src/Library/src/BootLoader/cd_boot.cpp @@ -25,11 +25,10 @@ namespace JabyEngine { CD_IO::Interrupt::ack_extended(CD_IO::PortIndex1::InterruptFlag); CD_IO::Interrupt::enable(CD_IO::PortIndex1::InterruptEnable); - Interrupt::ack_irq(Interrupt::CDROM); Interrupt::enable_irq(Interrupt::CDROM); + Interrupt::ack_irq(Interrupt::CDROM); __syscall_ExitCriticalSection(); - CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::PortIndex0::CommandFifo, CD_IO::PortIndex0::ParameterFifo, CD_IO::Command::GetStat); diff --git a/src/Library/src/BootLoader/start_boot.cpp b/src/Library/src/BootLoader/start_boot.cpp index 94cc51ee..ee4bf32d 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -7,10 +7,10 @@ namespace JabyEngine { namespace boot { - namespace Start { + namespace Start { + //This should become part of the bootloader later static void enable_DMA() { - const auto dpcr = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable); - DMA_IO::DPCR = dpcr; + DMA_IO::DPCR = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable).set(DMA_IO::DPCR_t::CDROMEnable); } JabyEngine::NextRoutine setup() { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index f64c7edf..ba1ca60c 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -1,4 +1,5 @@ #include "../../internal-include/CD/cd_internal.hpp" +#include #include #include @@ -24,6 +25,36 @@ namespace JabyEngine { static SectorBufferAllocator sector_allocator; static uint16_t sectors_left; + static void read_sector_dma(CD_IO::DataSector& sector) { + static const auto WaitSectorReady = []() { + while(!CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::HasDataFifoData)); + }; + + static const auto ReadSector = [](uint32_t* dst) { + DMA_IO::CDROM.set_adr(reinterpret_cast(dst)); + DMA_IO::CDROM.block_ctrl = DMA_IO::BCR_t::SyncMode0::for_cd(); + DMA_IO::CDROM.channel_ctrl = DMA_IO::CHCHR_t::StartCDROM(); + + DMA_IO::CDROM.wait(); + + CD_IO::PortIndex0::Request.reset(); + }; + + WaitSectorReady(); + ReadSector(sector.data); + } + + static void read_sector_to(CD_IO::DataSector& sector) { + CD_IO::PortIndex0::change_to(); + CD_IO::PortIndex0::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 InterruptVerifierResult interrupt_verifier() { static const auto pause = []() { CD_IO::PortIndex0::change_to(); @@ -43,12 +74,7 @@ namespace JabyEngine { auto* sector = sector_allocator.allocate_sector(); if(sector) { //Now obtain sector - static const char SimpleStr[] = "CD-Drive: This is a test string"; - - char* test_str = reinterpret_cast(sector->data); - for(size_t n = 0; n < sizeof(SimpleStr); n++) { - test_str[n] = SimpleStr[n]; - } + //read_sector_to(*sector); sectors_left--; if(sectors_left == 0) { @@ -102,7 +128,7 @@ namespace JabyEngine { current_state = State::Reading; - printf("Now reading: %i\n", file_info.lba); + printf("Now reading: %i(%i:%i:%i)\n", file_info.lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 58a9dd52..7ba57171 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -54,6 +54,7 @@ namespace JabyEngine { case CD::internal::State::Error: // Error for real! + test_print(); return Progress::Error; } From 206c95f295d08d4850bfdea2b52b2ff6c4727b29 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 27 Mar 2023 20:43:18 +0200 Subject: [PATCH 24/47] Successfully read in file --- include/PSX/Auxiliary/bits.hpp | 7 +++++++ include/PSX/System/IOPorts/cd_io.hpp | 2 +- src/Library/src/CD/cd.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/PSX/Auxiliary/bits.hpp b/include/PSX/Auxiliary/bits.hpp index 8857b64a..2e2cce79 100644 --- a/include/PSX/Auxiliary/bits.hpp +++ b/include/PSX/Auxiliary/bits.hpp @@ -5,6 +5,8 @@ namespace JabyEngine { namespace bit { + template + static constexpr T set(T raw_value, size_t bit); namespace value { template static constexpr T set_normalized(T raw_value, T value, size_t start_bit, size_t length); @@ -27,6 +29,11 @@ namespace JabyEngine { constexpr ClearBit operator!() const { return ClearBit(this->pos); } + + template + constexpr explicit operator T() const { + return bit::set(0, this->pos); + } }; struct BitRange { diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index bab6d9ba..ed8a044e 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -54,7 +54,7 @@ namespace JabyEngine { static constexpr auto WantData = Bit(7); void want_data() { - this->raw_value = Self::set(Self::WantData); + this->raw_value = static_cast(Self::WantData); } void reset() { diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index ba1ca60c..ae09f6ff 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -74,7 +74,7 @@ namespace JabyEngine { auto* sector = sector_allocator.allocate_sector(); if(sector) { //Now obtain sector - //read_sector_to(*sector); + read_sector_to(*sector); sectors_left--; if(sectors_left == 0) { From 2882ddfc3413a1ba750f92638094e4b884f3a0c1 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 27 Mar 2023 22:20:42 +0200 Subject: [PATCH 25/47] Support CopyTo now --- .../PSX/File/Processor/cd_file_processor.hpp | 24 +++++- src/Library/internal-include/CD/cd_types.hpp | 4 + src/Library/src/CD/cd.cpp | 5 +- .../src/File/Processor/cd_file_processor.cpp | 85 ++++++++++++++----- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index bd05a252..f6ca1c67 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -15,6 +15,13 @@ namespace JabyEngine { struct JobArray { const CDFile* files = nullptr; size_t size = 0; + + bool next() { + this->files += 1; + this->size -= 1; + + return this->size > 0; + } }; private: @@ -22,16 +29,27 @@ namespace JabyEngine { CircularBuffer circular_buffer; LZ4Decompressor lz4_decomp; JobArray jobs; - uint8_t* work_area = nullptr; const AutoLBAEntry* lba = nullptr; + uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to + uint32_t* dst_area = nullptr; //< Current target for copying the data - void start_cur_job(); + void start_cur_job(); + void reading_state(const CDFile& file); + void done_state(const CDFile& file); public: CDFileProcessor() = default; - void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area = reinterpret_cast(&__heap_base)); + void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area = &__heap_base); Progress process(); + bool next() { + if(this->jobs.next()) { + CDFileProcessor::start_cur_job(); + return true; + } + + return false; + } }; } diff --git a/src/Library/internal-include/CD/cd_types.hpp b/src/Library/internal-include/CD/cd_types.hpp index 01c7214d..cfb75e54 100644 --- a/src/Library/internal-include/CD/cd_types.hpp +++ b/src/Library/internal-include/CD/cd_types.hpp @@ -44,6 +44,10 @@ namespace JabyEngine { return SectorBufferAllocator(obj, function); } + static constexpr SectorBufferAllocator invalid() { + return SectorBufferAllocator(nullptr, nullptr); + } + inline CD_IO::DataSector* allocate_sector() const { return this->allocate(this->ctx); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index ae09f6ff..7b5a30d6 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -62,7 +62,7 @@ namespace JabyEngine { }; if(Interrupt::is_irq(Interrupt::CDROM)) { - const uint8_t old_idx = (CD_IO::IndexStatus & 0x3); + const uint8_t old_status = CD_IO::IndexStatus; CD_IO::PortIndex1::change_to(); const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); @@ -93,7 +93,8 @@ namespace JabyEngine { current_state = State::Error; } - CD_IO::IndexStatus = old_idx; + // No masking required because we can only write bit 0 - 2 + CD_IO::IndexStatus = old_status; return InterruptVerifierResult::ExecuteHandler; } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 7ba57171..0b323114 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -6,40 +6,83 @@ namespace JabyEngine { void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; + const auto configurate_for = [this](const CDFile& file) -> SectorBufferAllocator { + static const auto circular_buffer_callback = [](void* ctx) -> CD_IO::DataSector* { + CDFileProcessor &self = *reinterpret_cast(ctx); + return self.circular_buffer.allocate(); + }; + static const auto direct_copy_callback = [](void* ctx) -> CD_IO::DataSector* { + auto** data_sector = reinterpret_cast(ctx); + auto* cur_sector = *data_sector; + + data_sector += sizeof(CD_IO::DataSector); + return cur_sector; + }; + + switch(file.type) { + case CDFileType::SimpleTIM: + printf("CDFileProcessor: SimpleTIM not supported yet\n"); + return SectorBufferAllocator::invalid(); + + case CDFileType::CopyTo: + this->dst_area = file.payload.copy_to.dst; + return SectorBufferAllocator::create(&this->dst_area, direct_copy_callback); + + default: + return SectorBufferAllocator::invalid(); + } + }; const auto& cur_job = *this->jobs.files; const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; + const auto cfg = configurate_for(cur_job); - CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* { - CDFileProcessor &self = *reinterpret_cast(ctx); - - return self.circular_buffer.allocate(); - })); + CD::internal::read_file(FileInfo::from(cur_lba), cfg); printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); } - void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) { - this->lba = const_cast(lba); - this->work_area = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), 5)); - this->jobs = jobs; + void CDFileProcessor :: reading_state(const CDFile& file) { + switch(file.type) { + case CDFileType::SimpleTIM: + printf("CDFileProcessor: SimpleTIM not supported yet\n"); + break; + case CDFileType::CopyTo: + default: + break; + } + } + + void CDFileProcessor :: done_state(const CDFile& file) { + switch(file.type) { + case CDFileType::SimpleTIM: + printf("CDFileProcessor: SimpleTIM not supported yet\n"); + break; + + case CDFileType::CopyTo: + default: + break; + } + } + + void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) { + this->lba = const_cast(lba); + this->jobs = jobs; + + // Setsup the circular buffer and determines where to place the temp area in + const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), 5)); CDFileProcessor::start_cur_job(); } Progress CDFileProcessor :: process() { - const auto test_print = [this](){ - if(this->circular_buffer.has_data()) { - printf("Got-Data: %s\n", this->circular_buffer.get_next()); - this->circular_buffer.pop(); - } - }; + const auto& cur_job = *this->jobs.files; switch(CD::internal::read_current_state()) { case CD::internal::State::Done: - // Need to start next job? - // Does the user trigger this? - test_print(); + // We are done now! + // The user decides if he wants the next value + CDFileProcessor::done_state(cur_job); return Progress::Done; case CD::internal::State::BufferFull: @@ -49,15 +92,13 @@ namespace JabyEngine { case CD::internal::State::Reading: // Do we have data? Use it! - test_print(); + CDFileProcessor::reading_state(cur_job); return Progress::InProgress; case CD::internal::State::Error: + default: // Error for real! - test_print(); return Progress::Error; } - - return Progress::Error; } } \ No newline at end of file From d789bdd84535bbc367d36dfab9a67ac8aae806f2 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 29 Mar 2023 21:46:32 +0200 Subject: [PATCH 26/47] Separate make files for easier use --- lib/ExportPath.mk | 2 ++ lib/Makefile | 4 ++-- src/Library/Makefile | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 lib/ExportPath.mk diff --git a/lib/ExportPath.mk b/lib/ExportPath.mk new file mode 100644 index 00000000..fcc3b8d3 --- /dev/null +++ b/lib/ExportPath.mk @@ -0,0 +1,2 @@ +#Add the JabyEngine tools to path +export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH) \ No newline at end of file diff --git a/lib/Makefile b/lib/Makefile index 188bde77..5b262c51 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,5 +1,5 @@ -#Add the JabyEngine tools to path -export PATH := $(JABY_ENGINE_DIR)/bin/:$(PATH) +SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +include $(SELF_DIR)ExportPath.mk #Build architecture/variant string, possible values: x86, armv7le, etc... PLATFORM ?= PSX diff --git a/src/Library/Makefile b/src/Library/Makefile index ba511a31..688e59aa 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -42,6 +42,7 @@ $(LIB_DIR)/$(notdir $(OVERLAY_BOOT_OBJ)): $(OVERLAY_BOOT_OBJ) cp $(OVERLAY_BOOT_OBJ) $(LIB_DIR)/$(notdir $(OVERLAY_BOOT_OBJ)) # 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 $@ From 7550795af4086037ac435eece0653c629d744e46 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 29 Mar 2023 21:59:50 +0200 Subject: [PATCH 27/47] Support buffer full handling --- .../internal-include/CD/cd_internal.hpp | 1 + src/Library/src/CD/cd.cpp | 52 ++++++++++++------- .../src/File/Processor/cd_file_processor.cpp | 4 +- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 3e05fb69..5a370b4b 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -47,6 +47,7 @@ namespace JabyEngine { }; void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); + bool continue_reading(); } } } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 7b5a30d6..a812c3f4 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -25,6 +25,11 @@ namespace JabyEngine { static SectorBufferAllocator sector_allocator; static uint16_t sectors_left; + static void pause_cd() { + CD_IO::PortIndex0::change_to(); + Command::send(CD_IO::Command::Pause); + } + static void read_sector_dma(CD_IO::DataSector& sector) { static const auto WaitSectorReady = []() { while(!CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::HasDataFifoData)); @@ -55,12 +60,24 @@ namespace JabyEngine { // Doesn't seem to important when we can use DMA } - static InterruptVerifierResult interrupt_verifier() { - static const auto pause = []() { - CD_IO::PortIndex0::change_to(); - Command::send(CD_IO::Command::Pause); - }; + static bool try_read_sector() { + // Obtain sector content here + auto* sector = sector_allocator.allocate_sector(); + if(sector) { + //Now obtain sector + read_sector_to(*sector); + sectors_left--; + if(sectors_left == 0) { + current_state = State::Done; + pause_cd(); + } + return true; + } + return false; + } + + static InterruptVerifierResult interrupt_verifier() { if(Interrupt::is_irq(Interrupt::CDROM)) { const uint8_t old_status = CD_IO::IndexStatus; @@ -71,21 +88,9 @@ namespace JabyEngine { 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); - - sectors_left--; - if(sectors_left == 0) { - current_state = State::Done; - pause(); - } - } - - else { + if(!try_read_sector()) { current_state = State::BufferFull; - pause(); + pause_cd(); } } @@ -131,6 +136,15 @@ namespace JabyEngine { printf("Now reading: %i(%i:%i:%i)\n", file_info.lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } + + bool continue_reading() { + if(current_state != State::BufferFull) { + return true; + } + + CD_IO::PortIndex1::change_to(); + return try_read_sector(); + } } } } \ No newline at end of file diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 0b323114..01a198df 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -87,8 +87,8 @@ namespace JabyEngine { case CD::internal::State::BufferFull: // We have to process data and unpause the CD drive - // Error case for now - return Progress::Error; + CDFileProcessor::reading_state(cur_job); + return CD::internal::continue_reading() ? CDFileProcessor::process() : Progress::Error; case CD::internal::State::Reading: // Do we have data? Use it! From e9cc5f299a232fae56002c87af9f1bc27fcd7c94 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 1 Apr 2023 11:20:56 +0200 Subject: [PATCH 28/47] Integrate CircularBuffer as essential part of loading files from CD and dedicate file processing to the FileProcessor --- include/PSX/Auxiliary/lz4_decompressor.hpp | 22 +++++- .../PSX/File/Processor/cd_file_processor.hpp | 10 +-- include/PSX/File/Processor/file_processor.hpp | 2 + include/PSX/File/file_types.hpp | 4 + .../src/Auxiliary/lz4_decompressor.cpp | 9 ++- .../src/File/Processor/cd_file_processor.cpp | 75 +++++++++---------- .../src/File/Processor/nothing_processor.cpp | 16 ++++ 7 files changed, 85 insertions(+), 53 deletions(-) create mode 100644 src/Library/src/File/Processor/nothing_processor.cpp diff --git a/include/PSX/Auxiliary/lz4_decompressor.hpp b/include/PSX/Auxiliary/lz4_decompressor.hpp index e8343cc9..0ebd7b90 100644 --- a/include/PSX/Auxiliary/lz4_decompressor.hpp +++ b/include/PSX/Auxiliary/lz4_decompressor.hpp @@ -11,6 +11,10 @@ namespace JabyEngine { Progress progress; size_t bytes_ready; + constexpr operator bool() const { + return this->progress != Progress::Error; + } + static constexpr Result new_error() { return {Progress::Error, 0}; } @@ -27,6 +31,7 @@ namespace JabyEngine { private: struct State { enum struct Step { + Disabled, ReadToken, ObtainLiteralLength, CopyLiterals, @@ -35,12 +40,23 @@ namespace JabyEngine { CopyMatch, }; - Step step = Step::ReadToken; + Step step = Step::Disabled; size_t literal_length = 0; size_t match_length = 0; - uint16_t match_offset = 0xFFFF; + uint16_t match_offset = 0; State() = default; + + void enable() { + this->step = Step::ReadToken; + this->literal_length = 0; + this->match_length = 0; + this->match_offset = 0xFFFF; + } + + void disable() { + this->step = Step::Disabled; + } }; private: @@ -56,7 +72,7 @@ namespace JabyEngine { } void setup(uint8_t* dst_adr); - void reset(); + void disable(); Result process(ArrayRange data, bool is_last); }; diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index f6ca1c67..58b08920 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -25,17 +25,15 @@ namespace JabyEngine { }; private: - FileProcessor::State file_pro_state; + FileProcessor::State file_state; CircularBuffer circular_buffer; LZ4Decompressor lz4_decomp; JobArray jobs; const AutoLBAEntry* lba = nullptr; - uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to - uint32_t* dst_area = nullptr; //< Current target for copying the data + uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to for the file processor - void start_cur_job(); - void reading_state(const CDFile& file); - void done_state(const CDFile& file); + void start_cur_job(); + bool process_data(); public: CDFileProcessor() = default; diff --git a/include/PSX/File/Processor/file_processor.hpp b/include/PSX/File/Processor/file_processor.hpp index bdfba65f..fe3e3e9d 100644 --- a/include/PSX/File/Processor/file_processor.hpp +++ b/include/PSX/File/Processor/file_processor.hpp @@ -51,6 +51,8 @@ namespace JabyEngine { } }; + // The nothing state + State create(const uint32_t* data_adr, const Nothing& nothing); State create(const uint32_t* data_adr, const SimpleTIM& file); } } diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index 21f428b6..fe55228b 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -1,8 +1,12 @@ #ifndef __JABYENGINE_FILE_TYPES_HPP__ #define __JABYENGINE_FILE_TYPES_HPP__ +#include "../Auxiliary/bits.hpp" #include "../jabyengine_defines.h" namespace JabyEngine { + struct __no_align Nothing { + }; + struct __no_align SimpleTIM { static constexpr auto TextureX = BitRange::from_to(0, 8); static constexpr auto TextureY = BitRange::from_to(9, 16); diff --git a/src/Library/src/Auxiliary/lz4_decompressor.cpp b/src/Library/src/Auxiliary/lz4_decompressor.cpp index 3422a6ab..203693a9 100644 --- a/src/Library/src/Auxiliary/lz4_decompressor.cpp +++ b/src/Library/src/Auxiliary/lz4_decompressor.cpp @@ -24,11 +24,11 @@ namespace JabyEngine { void LZ4Decompressor :: setup(uint8_t* dst_adr) { this->dst_adr = dst_adr; - LZ4Decompressor::reset(); + this->state.enable(); } - void LZ4Decompressor :: reset() { - this->state = State(); + void LZ4Decompressor :: disable() { + this->state.disable(); } LZ4Decompressor::Result LZ4Decompressor :: process(ArrayRange data, bool is_last) { @@ -36,6 +36,9 @@ namespace JabyEngine { while(data) { switch(this->state.step) { + case State::Step::Disabled: + return Result::new_done(data.size); + case State::Step::ReadToken: { const auto token = data.pop(); diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 01a198df..3bd92faa 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,6 +3,8 @@ #include namespace JabyEngine { + static constexpr auto NormalCircularBufferSize = 5; + void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; @@ -11,13 +13,6 @@ namespace JabyEngine { CDFileProcessor &self = *reinterpret_cast(ctx); return self.circular_buffer.allocate(); }; - static const auto direct_copy_callback = [](void* ctx) -> CD_IO::DataSector* { - auto** data_sector = reinterpret_cast(ctx); - auto* cur_sector = *data_sector; - - data_sector += sizeof(CD_IO::DataSector); - return cur_sector; - }; switch(file.type) { case CDFileType::SimpleTIM: @@ -25,8 +20,11 @@ namespace JabyEngine { return SectorBufferAllocator::invalid(); case CDFileType::CopyTo: - this->dst_area = file.payload.copy_to.dst; - return SectorBufferAllocator::create(&this->dst_area, direct_copy_callback); + this->circular_buffer.setup(reinterpret_cast(file.payload.copy_to.dst), 512); + this->lz4_decomp.disable(); + + this->file_state = FileProcessor::create(this->tmp_area, Nothing()); + return SectorBufferAllocator::create(this, circular_buffer_callback); default: return SectorBufferAllocator::invalid(); @@ -42,28 +40,26 @@ namespace JabyEngine { printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); } - void CDFileProcessor :: reading_state(const CDFile& file) { - switch(file.type) { - case CDFileType::SimpleTIM: - printf("CDFileProcessor: SimpleTIM not supported yet\n"); - break; + bool CDFileProcessor :: process_data() { + while(this->circular_buffer.has_data()) { + ArrayRange cur_sector(reinterpret_cast(this->circular_buffer.get_next()->data), CD_IO::DataSector::SizeBytes); + + // v We can not know if there will be more data or not - but it also doesn't matter much for us + const auto result = this->lz4_decomp.process(cur_sector, false); + this->circular_buffer.pop(); - case CDFileType::CopyTo: - default: - break; - } - } - - void CDFileProcessor :: done_state(const CDFile& file) { - switch(file.type) { - case CDFileType::SimpleTIM: - printf("CDFileProcessor: SimpleTIM not supported yet\n"); - break; - - case CDFileType::CopyTo: - default: - break; + if(result) { + // Process the data in the tmp_area + if(this->file_state.process(result.bytes_ready/sizeof(uint32_t)) == Progress::Error) { + return false; + } + } + + else { + return false; + } } + return true; } void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) { @@ -71,33 +67,30 @@ namespace JabyEngine { this->jobs = jobs; // Setsup the circular buffer and determines where to place the temp area in - const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), 5)); + const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), NormalCircularBufferSize)); CDFileProcessor::start_cur_job(); } Progress CDFileProcessor :: process() { - const auto& cur_job = *this->jobs.files; - + CDFileProcessor::process_data(); switch(CD::internal::read_current_state()) { case CD::internal::State::Done: - // We are done now! - // The user decides if he wants the next value - CDFileProcessor::done_state(cur_job); + /* + We are done now! + The user decides if he wants the next value + */ return Progress::Done; case CD::internal::State::BufferFull: - // We have to process data and unpause the CD drive - CDFileProcessor::reading_state(cur_job); - return CD::internal::continue_reading() ? CDFileProcessor::process() : Progress::Error; + /* We processd data and unpause the CD drive */ + return CD::internal::continue_reading() ? Progress::InProgress : Progress::Error; case CD::internal::State::Reading: - // Do we have data? Use it! - CDFileProcessor::reading_state(cur_job); return Progress::InProgress; case CD::internal::State::Error: default: - // Error for real! + /* Error for real */ return Progress::Error; } } diff --git a/src/Library/src/File/Processor/nothing_processor.cpp b/src/Library/src/File/Processor/nothing_processor.cpp new file mode 100644 index 00000000..b76e5e2c --- /dev/null +++ b/src/Library/src/File/Processor/nothing_processor.cpp @@ -0,0 +1,16 @@ +#include "simplehelper.hpp" + +namespace JabyEngine { + namespace FileProcessor { + struct NothingState { + }; + + static Progress parse_nothing(State::Configuration& config, NothingState& state) { + return Progress::Done; + } + + State create(const uint32_t* data_adr, const Nothing& nothing) { + return State::from(NothingState(), data_adr, parse_nothing); + } + } +} \ No newline at end of file From 173c31dedea365f33a54e69f0eba62b50078600f Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 1 Apr 2023 11:57:48 +0200 Subject: [PATCH 29/47] Load TIM files (broken currently) --- .../PSX/File/Processor/cd_file_processor.hpp | 11 ++++- .../src/File/Processor/cd_file_processor.cpp | 44 +++++++++++-------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index 58b08920..552541b4 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -30,7 +30,7 @@ namespace JabyEngine { LZ4Decompressor lz4_decomp; JobArray jobs; const AutoLBAEntry* lba = nullptr; - uint32_t*const tmp_area = nullptr; //< The start of the area to copy data to for the file processor + uint32_t* tmp_area = nullptr; void start_cur_job(); bool process_data(); @@ -38,8 +38,15 @@ namespace JabyEngine { public: CDFileProcessor() = default; - void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area = &__heap_base); + void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area = &__heap_base); + + template + void setup(const volatile AutoLBAEntry* lba, const CDFile (&file_array)[N], uint32_t* tmp_area = &__heap_base) { + CDFileProcessor::setup(lba, JobArray{file_array, N}, tmp_area); + } + Progress process(); + bool next() { if(this->jobs.next()) { CDFileProcessor::start_cur_job(); diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 3bd92faa..3fe5550a 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -8,34 +8,41 @@ namespace JabyEngine { void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; - const auto configurate_for = [this](const CDFile& file) -> SectorBufferAllocator { - static const auto circular_buffer_callback = [](void* ctx) -> CD_IO::DataSector* { - CDFileProcessor &self = *reinterpret_cast(ctx); - return self.circular_buffer.allocate(); + const auto configurate_for = [this](const CDFile& file) { + const auto disable_lz4 = [this](uint32_t* work_area, size_t size) -> uint32_t* { + uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + + this->lz4_decomp.disable(); + return reinterpret_cast(dst_adr); + }; + + const auto enable_lz4 = [this](uint32_t* work_area, size_t size) -> uint32_t* { + uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + + this->lz4_decomp.setup(dst_adr); + return reinterpret_cast(dst_adr); }; switch(file.type) { case CDFileType::SimpleTIM: - printf("CDFileProcessor: SimpleTIM not supported yet\n"); - return SectorBufferAllocator::invalid(); + this->file_state = FileProcessor::create(enable_lz4(this->tmp_area, NormalCircularBufferSize), file.payload.simple_tim); + break; case CDFileType::CopyTo: - this->circular_buffer.setup(reinterpret_cast(file.payload.copy_to.dst), 512); - this->lz4_decomp.disable(); - - this->file_state = FileProcessor::create(this->tmp_area, Nothing()); - return SectorBufferAllocator::create(this, circular_buffer_callback); - - default: - return SectorBufferAllocator::invalid(); + this->file_state = FileProcessor::create(disable_lz4(file.payload.copy_to.dst, 512), Nothing()); + break; } }; const auto& cur_job = *this->jobs.files; const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; - const auto cfg = configurate_for(cur_job); - - CD::internal::read_file(FileInfo::from(cur_lba), cfg); + + configurate_for(cur_job); + CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, + [](void* ctx) -> CD_IO::DataSector* { + CDFileProcessor &self = *reinterpret_cast(ctx); + return self.circular_buffer.allocate(); + })); printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); } @@ -66,8 +73,7 @@ namespace JabyEngine { this->lba = const_cast(lba); this->jobs = jobs; - // Setsup the circular buffer and determines where to place the temp area in - const_cast(this->tmp_area) = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(tmp_area), NormalCircularBufferSize)); + this->tmp_area = tmp_area; CDFileProcessor::start_cur_job(); } From 0f78e62ab0a1421f9133ecbd37f1bbadda0b804c Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 1 Apr 2023 14:56:08 +0200 Subject: [PATCH 30/47] Fix LZ4 incorrect size bug --- src/Library/src/Auxiliary/lz4_decompressor.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Library/src/Auxiliary/lz4_decompressor.cpp b/src/Library/src/Auxiliary/lz4_decompressor.cpp index 203693a9..1c1ff4bf 100644 --- a/src/Library/src/Auxiliary/lz4_decompressor.cpp +++ b/src/Library/src/Auxiliary/lz4_decompressor.cpp @@ -70,9 +70,10 @@ namespace JabyEngine { memcpy(this->dst_adr, data, bytes_copy); this->state.literal_length -= bytes_copy; + bytes_ready += bytes_copy; + if(this->state.literal_length == 0) { - this->state.step = State::Step::ObtainMatchOffset; - bytes_ready += bytes_copy; + this->state.step = State::Step::ObtainMatchOffset; } } break; From 6333581c4ce697339f7119c0b13c386e3d751b03 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 1 Apr 2023 14:57:03 +0200 Subject: [PATCH 31/47] Load image w/o CircularBuffer --- include/PSX/File/Processor/file_processor.hpp | 18 ++++++++-------- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/CD/cd.cpp | 21 +++++++++++++++---- .../src/File/Processor/cd_file_processor.cpp | 6 +++--- .../src/File/Processor/nothing_processor.cpp | 2 +- .../src/File/Processor/simplehelper.hpp | 6 ++---- .../src/File/Processor/tim_processor.cpp | 19 +++++++++-------- 7 files changed, 43 insertions(+), 31 deletions(-) diff --git a/include/PSX/File/Processor/file_processor.hpp b/include/PSX/File/Processor/file_processor.hpp index fe3e3e9d..5930071a 100644 --- a/include/PSX/File/Processor/file_processor.hpp +++ b/include/PSX/File/Processor/file_processor.hpp @@ -20,17 +20,17 @@ namespace JabyEngine { struct Configuration { ProcessRoutine process_routine = nullptr; - const uint32_t* data_adr = nullptr; - size_t data_word_size = 0ull; + const uint8_t* data_adr = nullptr; + size_t data_bytes = 0ull; template - static __always_inline Configuration from(GenericProcessRoutine process_routine, const uint32_t* data_adr) { + static __always_inline Configuration from(GenericProcessRoutine process_routine, const uint8_t* data_adr) { return {reinterpret_cast(process_routine), data_adr}; } - constexpr void processed(size_t words) { - this->data_adr += words; - this->data_word_size -= words; + constexpr void processed(size_t bytes) { + this->data_adr += bytes; + this->data_bytes -= bytes; } }; @@ -39,14 +39,14 @@ namespace JabyEngine { Reserved reserved; template - static __always_inline State from(const T& reserved, const uint32_t* data_adr, GenericProcessRoutine process_routine) { + static __always_inline State from(const T& reserved, const uint8_t* data_adr, GenericProcessRoutine process_routine) { return {Configuration::from(process_routine, data_adr), *reinterpret_cast(&reserved)}; static_assert(sizeof(T) <= sizeof(Reserved)); } public: - Progress process(size_t word_size) { - this->config.data_word_size += word_size; + Progress process(size_t bytes_ready) { + this->config.data_bytes += bytes_ready; return (*this->config.process_routine)(this->config, this->reserved); } }; diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index fa0d97bd..d311e54d 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -43,7 +43,7 @@ namespace JabyEngine { // Upload SplashScreen picture auto state = FileProcessor::create(&__boot_loader_end, SimpleTIM(32, 0, 0, 0)); - while(state.process((bytes_ready/sizeof(uint32_t))) == Progress::InProgress); + while(state.process(bytes_ready) == Progress::InProgress); Display::enable(); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index a812c3f4..c407727e 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -30,6 +30,12 @@ namespace JabyEngine { Command::send(CD_IO::Command::Pause); } + // Requires Index0 + static void start_reading_cd() { + Command::send(CD_IO::Command::ReadN); + current_state = State::Reading; + } + static void read_sector_dma(CD_IO::DataSector& sector) { static const auto WaitSectorReady = []() { while(!CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::HasDataFifoData)); @@ -130,9 +136,7 @@ namespace JabyEngine { const auto loc = CDTimeStamp::from(file_info); Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); - Command::send(CD_IO::Command::ReadN); - - current_state = State::Reading; + start_reading_cd(); printf("Now reading: %i(%i:%i:%i)\n", file_info.lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } @@ -142,8 +146,17 @@ namespace JabyEngine { return true; } + printf(">>> Trying to read buffer from continue_reading\n"); CD_IO::PortIndex1::change_to(); - return try_read_sector(); + if(!try_read_sector()) { + return false; + } + + if(current_state != State::Done) { + CD_IO::PortIndex0::change_to(); + start_reading_cd(); + } + return true; } } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 3fe5550a..684c8858 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,7 +3,7 @@ #include namespace JabyEngine { - static constexpr auto NormalCircularBufferSize = 5; + static constexpr auto NormalCircularBufferSize = 64; void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; @@ -57,7 +57,7 @@ namespace JabyEngine { if(result) { // Process the data in the tmp_area - if(this->file_state.process(result.bytes_ready/sizeof(uint32_t)) == Progress::Error) { + if(this->file_state.process(result.bytes_ready) == Progress::Error) { return false; } } @@ -84,7 +84,7 @@ namespace JabyEngine { /* We are done now! The user decides if he wants the next value - */ + */ return Progress::Done; case CD::internal::State::BufferFull: diff --git a/src/Library/src/File/Processor/nothing_processor.cpp b/src/Library/src/File/Processor/nothing_processor.cpp index b76e5e2c..3bedba7b 100644 --- a/src/Library/src/File/Processor/nothing_processor.cpp +++ b/src/Library/src/File/Processor/nothing_processor.cpp @@ -10,7 +10,7 @@ namespace JabyEngine { } State create(const uint32_t* data_adr, const Nothing& nothing) { - return State::from(NothingState(), data_adr, parse_nothing); + return State::from(NothingState(), reinterpret_cast(data_adr), parse_nothing); } } } \ No newline at end of file diff --git a/src/Library/src/File/Processor/simplehelper.hpp b/src/Library/src/File/Processor/simplehelper.hpp index 0c179381..bdcfcae5 100644 --- a/src/Library/src/File/Processor/simplehelper.hpp +++ b/src/Library/src/File/Processor/simplehelper.hpp @@ -10,12 +10,10 @@ namespace JabyEngine { namespace Helper { template static void simple_read(T& dst, State::Configuration& config) { - static constexpr size_t UINT32_SIZE = (sizeof(T)/sizeof(uint32_t)); + static constexpr size_t T_SIZE = sizeof(T); dst = *reinterpret_cast(config.data_adr); - config.processed(UINT32_SIZE); - - static_assert((UINT32_SIZE*sizeof(uint32_t)) == sizeof(T)); + config.processed(T_SIZE); } template diff --git a/src/Library/src/File/Processor/tim_processor.cpp b/src/Library/src/File/Processor/tim_processor.cpp index c9a3eca8..f0528270 100644 --- a/src/Library/src/File/Processor/tim_processor.cpp +++ b/src/Library/src/File/Processor/tim_processor.cpp @@ -50,9 +50,10 @@ namespace JabyEngine { } static Progress parse_data(State::Configuration& config, SimpleTIMState& state) { - const auto words_to_use = (config.data_word_size > state.words_left) ? state.words_left : config.data_word_size; - bool is_last = (words_to_use == state.words_left); - auto block_count = (words_to_use >> 4); + const auto config_data_words = (config.data_bytes/sizeof(uint32_t)); + const auto words_to_use = (config_data_words > state.words_left) ? state.words_left : config_data_words; + bool is_last = (words_to_use == state.words_left); + auto block_count = (words_to_use >> 4); while(block_count > 0) { const auto block_send = (block_count > UI16_MAX) ? UI16_MAX : block_count; @@ -75,7 +76,7 @@ namespace JabyEngine { GPU::internal::DMA::end(); state.words_left = 0; - config.processed(words_to_use); + config.processed(words_to_use*sizeof(uint32_t)); return Progress::Done; } @@ -84,13 +85,13 @@ namespace JabyEngine { const auto words_used = (words_to_use & ~0b1111); state.words_left -= words_used; - config.processed(words_used); + config.processed(words_used*sizeof(uint32_t)); return Progress::InProgress; } } static Progress switch_state_parse_data(State::Configuration& config, SimpleTIMState& state) { - set_gpu_receive_data(config.data_adr, state, state.size_info.getTextureWidth(), state.size_info.getTextureHeight()); + set_gpu_receive_data(reinterpret_cast(config.data_adr), state, state.size_info.getTextureWidth(), state.size_info.getTextureHeight()); return Helper::exchange_and_execute_process_function(parse_data, config, state); } @@ -105,13 +106,13 @@ namespace JabyEngine { } static Progress parse_header(State::Configuration& config, SimpleTIMState& state) { - if(config.data_word_size >= (sizeof(SimpleTIMSize)/sizeof(uint32_t))) { + if(config.data_bytes >= sizeof(SimpleTIMSize)) { Helper::simple_read(state.size_info, config); //Check if we have a clut to care about if(state.size_info.getClutWidth() > 0) { //CLUTs are 16bit full color anyway - set_gpu_receive_data(config.data_adr, state, state.size_info.getClutWidth(), state.size_info.getClutHeight()); + set_gpu_receive_data(reinterpret_cast(config.data_adr), state, state.size_info.getClutWidth(), state.size_info.getClutHeight()); return Helper::exchange_and_execute_process_function(parse_clut, config, state); } @@ -125,7 +126,7 @@ namespace JabyEngine { } State create(const uint32_t* data_adr, const SimpleTIM& file) { - return State::from(SimpleTIMState(file), data_adr, parse_header); + return State::from(SimpleTIMState(file), reinterpret_cast(data_adr), parse_header); } } } From 1edae637c730fdad671192702ee13912323c0411 Mon Sep 17 00:00:00 2001 From: jaby Date: Sat, 1 Apr 2023 15:23:32 +0200 Subject: [PATCH 32/47] Fix CD pause issue --- .../internal-include/CD/cd_internal.hpp | 2 +- src/Library/src/BootLoader/gpu_boot.cpp | 2 +- src/Library/src/CD/cd.cpp | 72 ++++++++----------- .../src/File/Processor/cd_file_processor.cpp | 5 +- 4 files changed, 34 insertions(+), 47 deletions(-) diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 5a370b4b..7c555d27 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -47,7 +47,7 @@ namespace JabyEngine { }; void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); - bool continue_reading(); + void continue_reading(); } } } diff --git a/src/Library/src/BootLoader/gpu_boot.cpp b/src/Library/src/BootLoader/gpu_boot.cpp index d311e54d..5f38475e 100644 --- a/src/Library/src/BootLoader/gpu_boot.cpp +++ b/src/Library/src/BootLoader/gpu_boot.cpp @@ -43,7 +43,7 @@ namespace JabyEngine { // Upload SplashScreen picture auto state = FileProcessor::create(&__boot_loader_end, SimpleTIM(32, 0, 0, 0)); - while(state.process(bytes_ready) == Progress::InProgress); + state.process(bytes_ready); Display::enable(); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index c407727e..963a98f3 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -23,7 +23,8 @@ namespace JabyEngine { static constexpr auto DataSectorMode = Mode_t::from(Mode_t::DoubleSpeed, Mode_t::DataSector); static SectorBufferAllocator sector_allocator; - static uint16_t sectors_left; + static uint16_t cur_lba; + static uint16_t dst_lba; static void pause_cd() { CD_IO::PortIndex0::change_to(); @@ -31,9 +32,14 @@ namespace JabyEngine { } // Requires Index0 - static void start_reading_cd() { + static void read_cd(uint16_t lba) { + const auto loc = CDTimeStamp::from(lba); + + Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); Command::send(CD_IO::Command::ReadN); current_state = State::Reading; + + printf("Now reading: %i(%i:%i:%i)\n", lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } static void read_sector_dma(CD_IO::DataSector& sector) { @@ -66,23 +72,6 @@ namespace JabyEngine { // Doesn't seem to important when we can use DMA } - static bool try_read_sector() { - // Obtain sector content here - auto* sector = sector_allocator.allocate_sector(); - if(sector) { - //Now obtain sector - read_sector_to(*sector); - - sectors_left--; - if(sectors_left == 0) { - current_state = State::Done; - pause_cd(); - } - return true; - } - return false; - } - static InterruptVerifierResult interrupt_verifier() { if(Interrupt::is_irq(Interrupt::CDROM)) { const uint8_t old_status = CD_IO::IndexStatus; @@ -93,8 +82,20 @@ namespace JabyEngine { CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlag); if(cur_irq == CD_IO::Interrupt::DataReady) { - //Obtain sector content here - if(!try_read_sector()) { + // 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(); } @@ -128,35 +129,20 @@ namespace JabyEngine { }; void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { + cur_lba = file_info.lba; + dst_lba = file_info.lba + file_info.sectors; sector_allocator = buffer_allocator; - sectors_left = file_info.sectors; CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); - const auto loc = CDTimeStamp::from(file_info); - Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); - start_reading_cd(); - - printf("Now reading: %i(%i:%i:%i)\n", file_info.lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); + read_cd(file_info.lba); } - bool continue_reading() { - if(current_state != State::BufferFull) { - return true; - } - - printf(">>> Trying to read buffer from continue_reading\n"); - CD_IO::PortIndex1::change_to(); - if(!try_read_sector()) { - return false; - } - - if(current_state != State::Done) { - CD_IO::PortIndex0::change_to(); - start_reading_cd(); - } - return true; + void continue_reading() { + if(current_state == State::BufferFull) { + read_cd(cur_lba); + } } } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 684c8858..ac4e0a31 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,7 +3,7 @@ #include namespace JabyEngine { - static constexpr auto NormalCircularBufferSize = 64; + static constexpr auto NormalCircularBufferSize = 5; void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; @@ -89,7 +89,8 @@ namespace JabyEngine { case CD::internal::State::BufferFull: /* We processd data and unpause the CD drive */ - return CD::internal::continue_reading() ? Progress::InProgress : Progress::Error; + CD::internal::continue_reading(); + return Progress::InProgress; case CD::internal::State::Reading: return Progress::InProgress; From 7a373a38ff68c2490c0e9c9fe1c83532c960e50b Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 3 Apr 2023 22:00:39 +0200 Subject: [PATCH 33/47] Fix CD cancelling commands; Cleanup CD code a bit --- include/PSX/System/IOPorts/cd_io.hpp | 12 ++++++ .../internal-include/CD/cd_internal.hpp | 24 +++++------ src/Library/src/CD/cd.cpp | 43 ++++++++----------- .../src/File/Processor/cd_file_processor.cpp | 5 ++- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/include/PSX/System/IOPorts/cd_io.hpp b/include/PSX/System/IOPorts/cd_io.hpp index ed8a044e..f981aaac 100644 --- a/include/PSX/System/IOPorts/cd_io.hpp +++ b/include/PSX/System/IOPorts/cd_io.hpp @@ -31,6 +31,18 @@ namespace JabyEngine { static constexpr uint8_t Max = 0xFF; }; + __declare_io_type(Mode, uint8_t, + static constexpr auto DoubleSpeed = Bit(7); + static constexpr auto SingleSpeed = !DoubleSpeed; + static constexpr auto XADPCM = Bit(6); + static constexpr auto WholeSector = Bit(5); + static constexpr auto DataSector = !WholeSector; + static constexpr auto UseXAFilter = Bit(3); + static constexpr auto AudioPlayIRQ = Bit(2); + static constexpr auto AutoPauseTrack = Bit(1); + static constexpr auto CDDA = Bit(0); + ); + __declare_io_type(IndexStatus, uint8_t, static constexpr auto PortIndex = BitRange::from_to(0, 1); static constexpr auto HasXAFifoData = Bit(2); diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index 7c555d27..aab215c5 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -5,20 +5,13 @@ namespace JabyEngine { namespace CD { namespace internal { + extern State current_state; extern CD_IO::Interrupt::Type last_interrupt; - extern State current_state; - - static CD_IO::Interrupt::Type read_last_interrupt() { - return const_cast(last_interrupt); - } - - static State read_current_state() { - return const_cast(current_state); - } + extern uint8_t cmd_interrupt_bit; struct Command { - static void wait_until(CD_IO::Interrupt::Type irq) { - while(read_last_interrupt() != irq); + static void wait_completed() { + while(const_cast(cmd_interrupt_bit) > 0); } template @@ -26,7 +19,8 @@ namespace JabyEngine { while(CD_IO::IndexStatus.is_set(CD_IO::IndexStatus_t::IsTransmissionBusy)); ((parameter_fifo = args),...); - cmd_fifo = cmd.id; + cmd_fifo = cmd.id; + cmd_interrupt_bit = bit::set(0, cmd.complete_irq); } template @@ -37,7 +31,7 @@ namespace JabyEngine { template static void send_wait(CD_IO::CommandFifo_v& cmd_fifo, CD_IO::ParameterFifo_v& parameter_fifo, CD_IO::Command::Desc cmd, ARGS...args) { send(cmd_fifo, parameter_fifo, cmd, args...); - wait_until(cmd.complete_irq); + wait_completed(); } template @@ -46,6 +40,10 @@ namespace JabyEngine { } }; + static State read_current_state() { + return const_cast(current_state); + } + void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); void continue_reading(); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 963a98f3..66590264 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -3,28 +3,26 @@ #include #include -#include - namespace JabyEngine { namespace CD { namespace internal { - __declare_io_type(Mode, uint8_t, - static constexpr auto DoubleSpeed = Bit(7); - static constexpr auto SingleSpeed = !DoubleSpeed; - static constexpr auto XADPCM = Bit(6); - static constexpr auto WholeSector = Bit(5); - static constexpr auto DataSector = !WholeSector; - static constexpr auto UseXAFilter = Bit(3); - static constexpr auto AudioPlayIRQ = Bit(2); - static constexpr auto AutoPauseTrack = Bit(1); - static constexpr auto CDDA = Bit(0); - ); - - static constexpr auto DataSectorMode = Mode_t::from(Mode_t::DoubleSpeed, Mode_t::DataSector); + static constexpr auto DataSectorMode = CD_IO::Mode_t::from(CD_IO::Mode_t::DoubleSpeed, CD_IO::Mode_t::DataSector); + static InterruptVerifierResult interrupt_verifier(); + static void interrupt_handler(uint32_t); + static SectorBufferAllocator sector_allocator; static uint16_t cur_lba; static uint16_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; + InterrupCallback callback = { + .next = nullptr, + .handler_function = reinterpret_cast(interrupt_handler), + .verifier_function = interrupt_verifier + }; static void pause_cd() { CD_IO::PortIndex0::change_to(); @@ -33,13 +31,11 @@ namespace JabyEngine { // Requires Index0 static void read_cd(uint16_t lba) { - const auto loc = CDTimeStamp::from(lba); + const auto loc = CDTimeStamp::from(lba); Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); Command::send(CD_IO::Command::ReadN); current_state = State::Reading; - - printf("Now reading: %i(%i:%i:%i)\n", lba, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); } static void read_sector_dma(CD_IO::DataSector& sector) { @@ -81,6 +77,7 @@ namespace JabyEngine { last_interrupt = cur_irq; CD_IO::Interrupt::ack(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(); @@ -120,19 +117,12 @@ namespace JabyEngine { __syscall_ReturnFromException(); } - CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; - State current_state = State::Free; - InterrupCallback callback = { - .next = nullptr, - .handler_function = reinterpret_cast(interrupt_handler), - .verifier_function = interrupt_verifier - }; - void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { cur_lba = file_info.lba; dst_lba = file_info.lba + file_info.sectors; sector_allocator = buffer_allocator; + Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); @@ -141,6 +131,7 @@ namespace JabyEngine { void continue_reading() { if(current_state == State::BufferFull) { + Command::wait_completed(); read_cd(cur_lba); } } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index ac4e0a31..c3ee2ab5 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -78,13 +78,16 @@ namespace JabyEngine { } Progress CDFileProcessor :: process() { + const auto cur_state = CD::internal::read_current_state(); + CDFileProcessor::process_data(); - switch(CD::internal::read_current_state()) { + switch(cur_state) { case CD::internal::State::Done: /* We are done now! The user decides if he wants the next value */ + //while(this->file_state.process(0) != Progress::Done); return Progress::Done; case CD::internal::State::BufferFull: From 1a0d17577932fb95c99b0e21e739e04933e1a7c5 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 10 Apr 2023 17:01:28 +0200 Subject: [PATCH 34/47] Remove Overlayhader and support loading overlays --- include/PSX/File/cd_file_types.hpp | 8 ++- include/PSX/File/file_types.hpp | 2 + include/PSX/Overlay/overlay.hpp | 8 ++- include/PSX/Overlay/overlay_declaration.hpp | 5 +- include/PSX/jabyengine_defines.h | 2 +- .../src/File/Processor/cd_file_processor.cpp | 19 +++++-- src/Tools/mkoverlay/src/creator/ldscript.rs | 16 ++++-- .../psxcdgen_ex/src/types/overlay/mod.rs | 52 +++---------------- 8 files changed, 47 insertions(+), 65 deletions(-) diff --git a/include/PSX/File/cd_file_types.hpp b/include/PSX/File/cd_file_types.hpp index 4e8d0eb6..b6ff973f 100644 --- a/include/PSX/File/cd_file_types.hpp +++ b/include/PSX/File/cd_file_types.hpp @@ -7,13 +7,15 @@ namespace JabyEngine { enum struct CDFileType : uint8_t { SimpleTIM = 0, CopyTo, + Overlay, }; struct __no_align CDFile { union __no_align Payload { - uint32_t empty; + uint32_t raw; SimpleTIM simple_tim; CopyTo copy_to; + Overlay overlay; }; uint8_t rel_lba_idx; @@ -31,6 +33,10 @@ namespace JabyEngine { static constexpr CDFile copy_to(uint8_t rel_lba_idx, uint32_t* dst) { return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::CopyTo, .payload = {.copy_to = CopyTo{dst}}}; } + + static constexpr CDFile overlay(uint8_t rel_lba_idx, uint32_t* overlay_dst) { + return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::Overlay, .payload = {.overlay = Overlay{overlay_dst}}}; + } }; } #endif //!__JABYENGINE_CD_FILE_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/File/file_types.hpp b/include/PSX/File/file_types.hpp index fe55228b..bba6c5f5 100644 --- a/include/PSX/File/file_types.hpp +++ b/include/PSX/File/file_types.hpp @@ -42,5 +42,7 @@ namespace JabyEngine { struct __no_align CopyTo { uint32_t* dst; }; + + typedef CopyTo Overlay; } #endif // !__JABYENGINE_FILE_TYPES_HPP__ \ No newline at end of file diff --git a/include/PSX/Overlay/overlay.hpp b/include/PSX/Overlay/overlay.hpp index cd7b8ae8..1040eed4 100644 --- a/include/PSX/Overlay/overlay.hpp +++ b/include/PSX/Overlay/overlay.hpp @@ -3,11 +3,9 @@ #include "../AutoLBA/auto_lba.hpp" namespace JabyEngine { - struct __attribute__((packed)) OverlayHeader { - void (*execute)(); - uint16_t lba_size; //< The size of the OverlayLBA section - }; - typedef AutoLBAEntry OverlayLBA; + + // Can be used to create dummy values to trick LZ4 into compressing an uncompressed overlay + #define __create_dummy_fill(length) static const uint8_t __section(".keep.dummy") __used DummyFilling[length] = {0x0} } #endif //!__JABYENGINE_OVERLAY__HPP__ \ No newline at end of file diff --git a/include/PSX/Overlay/overlay_declaration.hpp b/include/PSX/Overlay/overlay_declaration.hpp index 279c1dfc..85cf0449 100644 --- a/include/PSX/Overlay/overlay_declaration.hpp +++ b/include/PSX/Overlay/overlay_declaration.hpp @@ -4,10 +4,7 @@ // No include here because this header should be included in a namespace and we don't want multiple namespace definitions of OverlayHeader and OverlayLBA #include "../AutoLBA/auto_lba_declaration.hpp" -extern const JabyEngine::OverlayHeader overlay_header; #define __declare_overlay_header(function, enum_struct) \ -__declare_lba_header(enum_struct); \ -[[gnu::used]] \ -const JabyEngine::OverlayHeader __section(".header") overlay_header = {.execute = &function, .lba_size = static_cast(enum_struct::EndOfRequest)}; +__declare_lba_header(enum_struct) #endif //!__JABYENGINE_OVERLAY_DECLARATION__HPP__ \ No newline at end of file diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h index efdd97b3..a0957d14 100644 --- a/include/PSX/jabyengine_defines.h +++ b/include/PSX/jabyengine_defines.h @@ -3,7 +3,7 @@ #include "jabyengine_config.hpp" #include "../stddef.h" -#define __keep __attribute__((used)) +#define __used __attribute__((used)) #define __no_align __attribute__((packed)) #define __no_inline __attribute__((noinline)) #define __always_inline __attribute__((always_inline)) diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index c3ee2ab5..88b1d891 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,22 +3,27 @@ #include namespace JabyEngine { - static constexpr auto NormalCircularBufferSize = 5; + static constexpr auto NormalCircularBufferSize = 5; + static constexpr auto DisabledCircularBufferSize = 512; void CDFileProcessor :: start_cur_job() { using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; const auto configurate_for = [this](const CDFile& file) { - const auto disable_lz4 = [this](uint32_t* work_area, size_t size) -> uint32_t* { - uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { + uint8_t*const dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); this->lz4_decomp.disable(); - return reinterpret_cast(dst_adr); + return overwrite_dst ? overwrite_dst : reinterpret_cast(dst_adr); }; - const auto enable_lz4 = [this](uint32_t* work_area, size_t size) -> uint32_t* { + const auto enable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* override_dst = nullptr) -> uint32_t* { uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + if(override_dst) { + dst_adr = reinterpret_cast(override_dst); + } + this->lz4_decomp.setup(dst_adr); return reinterpret_cast(dst_adr); }; @@ -31,6 +36,10 @@ namespace JabyEngine { case CDFileType::CopyTo: this->file_state = FileProcessor::create(disable_lz4(file.payload.copy_to.dst, 512), Nothing()); break; + + case CDFileType::Overlay: + this->file_state = FileProcessor::create(enable_lz4(this->tmp_area, NormalCircularBufferSize, file.payload.overlay.dst), Nothing()); + break; } }; diff --git a/src/Tools/mkoverlay/src/creator/ldscript.rs b/src/Tools/mkoverlay/src/creator/ldscript.rs index e256c270..7e636375 100644 --- a/src/Tools/mkoverlay/src/creator/ldscript.rs +++ b/src/Tools/mkoverlay/src/creator/ldscript.rs @@ -58,13 +58,23 @@ fn write_section(output: &mut Output, sections: &Vec, add_end_na for section in sections { writeln!(output, "\t\t.{} {{", section.name)?; writeln!(output, "\t\t\t__{}_start = .;", section.name)?; - section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\tKEEP({}(.header))", patr))?; writeln!(output, "\t\t\t__{}_lbas = .;", section.name)?; section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\tKEEP({}(.header.lbas))", patr))?; writeln!(output, "\t\t\t__{}_ctor = .;", section.name)?; - for section_type in [".text.startup._GLOBAL__*", ".ctors", ".text.*", ".rodata*", ".sdata*", ".data*", ".sbss*", ".bss*"] { - section.file_pattern.iter().try_for_each(|patr| writeln!(output, "\t\t\t{}({})", patr, section_type))?; + for (section_type, keep) in [(".text.startup._GLOBAL__*", false), (".ctors", false), (".text.*", false), (".rodata*", false), (".sdata*", false), (".data*", false), (".sbss*", false), (".bss*", false), (".keep.dummy", true)] { + section.file_pattern.iter().try_for_each(|patr| { + let section_entry = format!("{}({})", patr, section_type); + + write!(output, "\t\t\t")?; + if keep { + writeln!(output, "KEEP({})", section_entry) + } + + else { + writeln!(output, "{}", section_entry) + } + })?; } if add_end_name { diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index de6aca16..512ace87 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -8,18 +8,6 @@ pub type LBANameVec = Vec; mod main; -#[repr(packed)] -struct OverlayHeader { - _start_adr: u32, - lba_count: u16, -} - -impl OverlayHeader { - pub fn read_lba_count(&self) -> usize { - u16::from_le(self.lba_count) as usize - } -} - #[repr(packed)] struct LBAEntry { lba: u16, @@ -51,7 +39,7 @@ impl LBAEntry { } pub fn load_from(file_name: &str, file_path: PathBuf, lba_source: PathBuf) -> Result { - let content = load_content(&file_path)?; + let content = read_file(&file_path)?; let lba_names = load_lba_names(lba_source)?; let content_size = format_if_error!(tool_helper::compress::psx_default::lz4(&content), "Compressing {} failed with \"{error_text}\"", file_path.to_string_lossy())?.len(); @@ -63,14 +51,10 @@ pub fn load_for_main(file_name: &str, content: Vec, lba_source: PathBuf) -> } pub fn update_content(content: &mut Vec, lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result, Error> { - let (lba_header, lba_count) = skip_to_lba_header(content); - let lba_header = unsafe{std::slice::from_raw_parts_mut(lba_header.as_mut_ptr() as *mut LBAEntry, lba_count)}; + let lba_header = skip_to_lba_header(content); + let lba_header = unsafe{std::slice::from_raw_parts_mut(lba_header.as_mut_ptr() as *mut LBAEntry, lba_names.len())}; for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes)| { - if idx >= lba_count { - return Err(Error::from_text(format!("Trying to write more LBAs then there is space!"))); - } - lba_header[idx].write_entry(lba, bytes) })?; @@ -105,34 +89,10 @@ fn for_each_lba_name Result<(), Error>>(lba_nam Ok(()) } -fn load_content(file_path: &PathBuf) -> Result, Error> { - let mut content = read_file(&file_path)?; +fn skip_to_lba_header(content: &mut Vec) -> &mut [u8] { + let overlay_header_size = 0; - if content.len() < std::mem::size_of::() { - return Err(Error::from_text(format!("Overlay {} has no header!", file_path.to_string_lossy()))); - } - - let (lba_header, lba_count) = skip_to_lba_header(&mut content); - if lba_header.is_empty() { - return Err(Error::from_text(format!("LBA header of overlay {} is smaller then {} elements", file_path.to_string_lossy(), lba_count))); - } - - let mut count = 0; - for byte in lba_header { - *byte = count as u8; - count += 1; - } - - Ok(content) -} - -fn skip_to_lba_header(content: &mut Vec) -> (&mut [u8], usize) { - let overlay_header_size = std::mem::size_of::(); - - let lba_count = unsafe{std::mem::transmute::<&u8, &OverlayHeader>(&content[0])}.read_lba_count(); - let lba_header_size = lba_count*std::mem::size_of::(); - - (&mut content[overlay_header_size..(overlay_header_size+lba_header_size)], lba_count) + &mut content[overlay_header_size..] } fn load_lba_names(lba_source: PathBuf) -> Result { From 320fa8934cda7d5a561a0c82e817faf1ec766336 Mon Sep 17 00:00:00 2001 From: jaby Date: Wed, 12 Apr 2023 21:59:36 +0200 Subject: [PATCH 35/47] Prepare new LBA representation --- include/PSX/AutoLBA/auto_lba.hpp | 34 ++++++++++++-- .../internal-include/CD/cd_internal.hpp | 2 +- src/Library/internal-include/CD/cd_types.hpp | 19 ++------ src/Library/src/CD/cd.cpp | 14 +++--- .../src/File/Processor/cd_file_processor.cpp | 5 +- src/Tools/psxcdgen_ex/src/types/bits.rs | 42 +++++++++++++++++ src/Tools/psxcdgen_ex/src/types/mod.rs | 1 + .../psxcdgen_ex/src/types/overlay/mod.rs | 47 +++++++++++-------- 8 files changed, 114 insertions(+), 50 deletions(-) create mode 100644 src/Tools/psxcdgen_ex/src/types/bits.rs diff --git a/include/PSX/AutoLBA/auto_lba.hpp b/include/PSX/AutoLBA/auto_lba.hpp index d211535d..e1dc7358 100644 --- a/include/PSX/AutoLBA/auto_lba.hpp +++ b/include/PSX/AutoLBA/auto_lba.hpp @@ -1,6 +1,6 @@ #ifndef __JABYENGINE_AUTO_LBA_HPP__ #define __JABYENGINE_AUTO_LBA_HPP__ -#include "../../stdint.h" +#include "../Auxiliary/bits.hpp" namespace JabyEngine { #define __jabyengine_start_lba_request @@ -8,8 +8,36 @@ namespace JabyEngine { #define __jabyengine_end_lba_request EndOfRequest struct __attribute__((packed)) AutoLBAEntry { - uint16_t lba; - uint16_t size_words; + // This layout should make it a bit easier to read the "BitRange" values + static constexpr auto SizeInSectors = BitRange::from_to(22, 31); + static constexpr auto IsLZ4Compressed = Bit(19); + static constexpr auto LBAValue = BitRange::from_to(0, 18); + + uint32_t value; + + constexpr uint32_t get_lba() const { + return bit::value::get_normalized(this->value, AutoLBAEntry::LBAValue); + } + + constexpr uint32_t get_lba() const volatile { + return const_cast(this)->get_lba(); + } + + constexpr uint32_t get_size_in_sectors() const { + return this->value >> SizeInSectors.pos; + } + + constexpr uint32_t get_size_in_sectors() const volatile { + return const_cast(this)->get_size_in_sectors(); + } + + constexpr bool isLZ4() const { + return bit::is_set(this->value, AutoLBAEntry::IsLZ4Compressed); + } + + constexpr bool isLZ4() const volatile { + return const_cast(this)->isLZ4(); + } }; } diff --git a/src/Library/internal-include/CD/cd_internal.hpp b/src/Library/internal-include/CD/cd_internal.hpp index aab215c5..aad04e32 100644 --- a/src/Library/internal-include/CD/cd_internal.hpp +++ b/src/Library/internal-include/CD/cd_internal.hpp @@ -44,7 +44,7 @@ namespace JabyEngine { return const_cast(current_state); } - void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); + void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator); void continue_reading(); } } diff --git a/src/Library/internal-include/CD/cd_types.hpp b/src/Library/internal-include/CD/cd_types.hpp index cfb75e54..5e1f07d6 100644 --- a/src/Library/internal-include/CD/cd_types.hpp +++ b/src/Library/internal-include/CD/cd_types.hpp @@ -17,15 +17,6 @@ namespace JabyEngine { Error, }; - struct FileInfo { - uint16_t lba; - uint16_t sectors; - - static constexpr FileInfo from(const AutoLBAEntry& entry) { - return FileInfo{entry.lba, CD_IO::DataSector::words_to_sectors(entry.size_words)}; - } - }; - class SectorBufferAllocator { private: typedef CD_IO::DataSector* (*AllocatorFunction)(void* ctx); @@ -61,17 +52,13 @@ namespace JabyEngine { uint8_t sec; uint8_t sector; - static constexpr CDTimeStamp from(uint16_t lba) { - const auto [min, new_lba] = div_and_mod(lba, static_cast(MaxSector*MaxSeconds)); - const auto [sec, sectors] = div_and_mod(new_lba, static_cast(MaxSector)); + static constexpr CDTimeStamp from(uint32_t lba) { + const auto [min, new_lba] = div_and_mod(lba, MaxSector*MaxSeconds); + const auto [sec, sectors] = div_and_mod(new_lba, MaxSector); return CDTimeStamp{static_cast(min), static_cast(sec), static_cast(sectors)}; } - static constexpr CDTimeStamp from(const FileInfo& file_info) { - return CDTimeStamp::from(file_info.lba); - } - constexpr uint8_t get_min_cd() const { return to_bcd(this->min); } diff --git a/src/Library/src/CD/cd.cpp b/src/Library/src/CD/cd.cpp index 66590264..9ef12677 100644 --- a/src/Library/src/CD/cd.cpp +++ b/src/Library/src/CD/cd.cpp @@ -12,8 +12,8 @@ namespace JabyEngine { static void interrupt_handler(uint32_t); static SectorBufferAllocator sector_allocator; - static uint16_t cur_lba; - static uint16_t dst_lba; + 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; @@ -30,7 +30,7 @@ namespace JabyEngine { } // Requires Index0 - static void read_cd(uint16_t lba) { + static void read_cd(uint32_t lba) { const auto loc = CDTimeStamp::from(lba); Command::send_wait(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd()); @@ -117,16 +117,16 @@ namespace JabyEngine { __syscall_ReturnFromException(); } - void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { - cur_lba = file_info.lba; - dst_lba = file_info.lba + file_info.sectors; + void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) { + cur_lba = file_info.get_lba(); + dst_lba = cur_lba + file_info.get_size_in_sectors(); sector_allocator = buffer_allocator; Command::wait_completed(); CD_IO::PortIndex0::change_to(); Command::send_wait(CD_IO::Command::SetMode, DataSectorMode); - read_cd(file_info.lba); + read_cd(cur_lba); } void continue_reading() { diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 88b1d891..5e191bb9 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -7,7 +7,6 @@ namespace JabyEngine { static constexpr auto DisabledCircularBufferSize = 512; void CDFileProcessor :: start_cur_job() { - using CD::internal::FileInfo; using CD::internal::SectorBufferAllocator; const auto configurate_for = [this](const CDFile& file) { const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { @@ -47,13 +46,13 @@ namespace JabyEngine { const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; configurate_for(cur_job); - CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, + CD::internal::read_file(cur_lba, SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* { CDFileProcessor &self = *reinterpret_cast(ctx); return self.circular_buffer.allocate(); })); - printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.lba, cur_lba.size_words); + printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.get_lba(), cur_lba.get_size_in_sectors()); } bool CDFileProcessor :: process_data() { diff --git a/src/Tools/psxcdgen_ex/src/types/bits.rs b/src/Tools/psxcdgen_ex/src/types/bits.rs new file mode 100644 index 00000000..c9b899df --- /dev/null +++ b/src/Tools/psxcdgen_ex/src/types/bits.rs @@ -0,0 +1,42 @@ +pub struct BitRange { + start: usize, + length: usize +} + +impl BitRange { + pub const fn from_to(start_bit: usize, end_bit: usize) -> Self { + Self{start: start_bit, length: (end_bit - start_bit) + 1} + } + + pub const fn get_mask(&self) -> usize { + self.max_value() + } + + pub const fn max_value(&self) -> usize { + (1 << self.length) - 1 + } + + pub const fn or_value(&self, dst_value: usize, value: usize) -> usize { + dst_value | ((value & self.get_mask()) << self.start) + } +} + +pub struct Bit { + pos: usize +} + +impl Bit { + pub const fn at(pos: usize) -> Self { + Bit{pos} + } + + pub const fn or_value(&self, dst_value: usize, is_set: bool) -> usize { + if is_set { + dst_value | (1 << self.pos) + } + + else { + dst_value + } + } +} \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index 68d00414..60023c9e 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -1,3 +1,4 @@ +pub mod bits; pub (super) mod helper; pub mod layout; pub mod file_map; diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index 512ace87..6bca45e0 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -1,4 +1,4 @@ -use super::{layout::Layout, File, FileSystemMap}; +use super::{bits::{Bit, BitRange}, layout::Layout, File, FileSystemMap}; use super::super::encoder::LengthCalculatorFunction; use std::path::PathBuf; use no_comment::{IntoWithoutComments as _, languages}; @@ -8,32 +8,39 @@ pub type LBANameVec = Vec; mod main; +/* +Size in sectors [22, 31]; +Is LZ4 compressed [19]; +LBA value [0, 18] +*/ #[repr(packed)] struct LBAEntry { - lba: u16, - size_words: u16, + raw: u32, } impl LBAEntry { - pub fn write_entry(&mut self, lba: u16, mut size_bytes: usize) -> Result<(), Error> { - const WORD_SIZE:usize = std::mem::size_of::(); + const SIZE_IN_SECTOR_RANGE:BitRange = BitRange::from_to(22, 31); + const _IS_LZ4_COMPRESSED:Bit = Bit::at(19); + const LBA_VALUE_RANGE:BitRange = BitRange::from_to(0, 18); - if self.lba != 0 || self.size_words != 0 { + pub fn write_entry(&mut self, lba: usize, size_bytes: usize) -> Result<(), Error> { + if lba > Self::LBA_VALUE_RANGE.max_value() { + return Err(Error::from_text(format!("LBA of value {} is impossible and can not be encoded! Maximum LBA value is: {}", lba, Self::LBA_VALUE_RANGE.max_value()))); + } + + let size_in_sectors = cdtypes::types::helper::sector_count_mode2_form1(size_bytes); + if size_in_sectors > Self::SIZE_IN_SECTOR_RANGE.max_value() { + return Err(Error::from_text(format!("{} sectors can not be encoded into 10bit", size_in_sectors))); + } + + let lba = usize::from_ne_bytes(lba.to_le_bytes()); + let size_in_sectors = usize::from_ne_bytes(size_in_sectors.to_le_bytes()); + + if self.raw != 0 { return Err(Error::from_str("LBA Entry will overwrite non-zero value!\nIs no space allocated for the LBA Entries?")); } - size_bytes = (size_bytes + (WORD_SIZE - 1))/WORD_SIZE; - - if (size_bytes as u16) as usize != size_bytes { - return Err(Error::from_text(format!("{} words can not be encoded into 16bit", size_bytes))); - } - - let lba = lba.to_le_bytes(); - let size_bytes = (size_bytes as u16).to_le_bytes(); - - self.lba = u16::from_ne_bytes(lba); - self.size_words = u16::from_ne_bytes(size_bytes); - + self.raw = Self::SIZE_IN_SECTOR_RANGE.or_value(Self::LBA_VALUE_RANGE.or_value(0, lba), size_in_sectors) as u32; Ok(()) } } @@ -71,13 +78,13 @@ pub fn update_content_for_main(content: &mut Vec, lba_names: &LBANameVec, fi Ok(content.clone()) } -fn for_each_lba_name Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> { +fn for_each_lba_name Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> { let mut idx = 0; for lba_name in lba_names { if let Some(file) = file_map.get(lba_name) { let (lba, bytes) = (format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes); - functor(idx, (lba as u16, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?; + functor(idx, (lba, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?; idx += 1; } From 9d7e77393fefc1a15c6c25997f995823fc08965f Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 13 Apr 2023 21:06:24 +0200 Subject: [PATCH 36/47] Prepare to support enconding of LZ4 --- .../psxcdgen_ex/src/config_reader/mod.rs | 7 ++++ .../psxcdgen_ex/src/config_reader/xml.rs | 39 +++++++++++++++---- src/Tools/psxcdgen_ex/src/lib.rs | 15 +++++-- src/Tools/psxcdgen_ex/src/types/mod.rs | 5 ++- .../psxcdgen_ex/src/types/overlay/mod.rs | 22 ++++++----- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/Tools/psxcdgen_ex/src/config_reader/mod.rs b/src/Tools/psxcdgen_ex/src/config_reader/mod.rs index e497e2a7..566db654 100644 --- a/src/Tools/psxcdgen_ex/src/config_reader/mod.rs +++ b/src/Tools/psxcdgen_ex/src/config_reader/mod.rs @@ -2,6 +2,12 @@ use super::Error; use std::path::PathBuf; mod xml; +pub enum LZ4State { + None, + AlreadyCompressed, + Compress, +} + pub struct Configuration { pub publisher: Option, pub license_path: Option, @@ -17,6 +23,7 @@ impl Configuration { pub struct CommonProperties { pub name: String, pub is_hidden: bool, + pub lz4_state: LZ4State, pub padded_size: Option, } diff --git a/src/Tools/psxcdgen_ex/src/config_reader/xml.rs b/src/Tools/psxcdgen_ex/src/config_reader/xml.rs index 9f6c49bc..991e7eb8 100644 --- a/src/Tools/psxcdgen_ex/src/config_reader/xml.rs +++ b/src/Tools/psxcdgen_ex/src/config_reader/xml.rs @@ -2,13 +2,14 @@ use std::path::PathBuf; use tool_helper::{format_if_error, path_with_env_from}; use crate::config_reader::Directory; -use super::{CommonProperties, Configuration, Error, File, FileKind}; +use super::{CommonProperties, Configuration, Error, File, FileKind, LZ4State}; mod attribute_names { pub const NAME: &'static str = "name"; pub const HIDDEN: &'static str = "hidden"; pub const PADDED_SIZE: &'static str = "padded_size"; pub const LBA_SOURCE: &'static str = "lba_source"; + pub const LZ4_STATE: &'static str = "lz4"; } pub fn parse(xml: String) -> Result { @@ -57,27 +58,28 @@ fn parse_description(description: roxmltree::Node, config: &mut Configuration) - fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(), Error> { fn parse_regular_file(file: roxmltree::Node, is_hidden: bool) -> Result { - let common = read_common_properties(&file, is_hidden)?; + let common = read_common_properties(&file, is_hidden, None)?; let path = path_from_node(&file, &common.name)?; Ok(File{common, path, kind: FileKind::Regular}) } - fn parse_main_file(file: roxmltree::Node, is_hidden: bool) -> Result { + fn parse_main_file(file: roxmltree::Node) -> Result { if let Some(lba_path) = file.attribute(attribute_names::LBA_SOURCE) { - let common = read_common_properties(&file, is_hidden)?; + let common = read_common_properties(&file, false, Some(LZ4State::None))?; let path = path_from_node(&file, &common.name)?; Ok(File{common, path, kind: FileKind::Main(PathBuf::from(lba_path))}) } else { - parse_regular_file(file, is_hidden) + parse_regular_file(file, false) } } fn parse_overlay_file(file: roxmltree::Node, is_hidden: bool) -> Result { - let common = read_common_properties(&file, is_hidden)?; + // v they will be compressed automatically + let common = read_common_properties(&file, is_hidden, Some(LZ4State::AlreadyCompressed))?; let path = path_from_node(&file, &common.name)?; Ok(File{common, path, kind: FileKind::Overlay(PathBuf::from(file.attribute(attribute_names::LBA_SOURCE).unwrap_or_default()))}) @@ -88,7 +90,7 @@ fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(), if node.is_element() { match node.tag_name().name() { "File" => root.add_file(parse_regular_file(node, is_hidden)?), - "Main" => root.add_file(parse_main_file(node, is_hidden)?), + "Main" => root.add_file(parse_main_file(node)?), "Overlay" => root.add_file(parse_overlay_file(node, is_hidden)?), "Directory" => { is_hidden |= parse_boolean_attribute(&node, attribute_names::HIDDEN)?; @@ -108,10 +110,31 @@ fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(), parse_file_system(track, &mut config.root, false) } -fn read_common_properties(xml: &roxmltree::Node, is_hidden: bool) -> Result { +fn read_common_properties(xml: &roxmltree::Node, is_hidden: bool, force_lz4_state: Option) -> Result { + let lz4_state = { + if let Some(forced_lz4_state) = force_lz4_state { + forced_lz4_state + } + + else { + if let Some(state_str) = xml.attribute(attribute_names::LZ4_STATE) { + match state_str.to_lowercase().as_str() { + "yes" => LZ4State::Compress, + "already" => LZ4State::AlreadyCompressed, + _ => LZ4State::None, + } + } + + else { + LZ4State::None + } + } + }; + Ok(CommonProperties{ name: String::from(xml.attribute(attribute_names::NAME).unwrap_or_default()), is_hidden: is_hidden | parse_boolean_attribute(&xml, attribute_names::HIDDEN)?, + lz4_state, padded_size: read_padded_size(&xml)? }) } diff --git a/src/Tools/psxcdgen_ex/src/lib.rs b/src/Tools/psxcdgen_ex/src/lib.rs index 388478f1..028acab7 100644 --- a/src/Tools/psxcdgen_ex/src/lib.rs +++ b/src/Tools/psxcdgen_ex/src/lib.rs @@ -5,6 +5,7 @@ pub mod encoder; pub mod file_writer; pub mod types; +use config_reader::LZ4State; use encoder::{LbaCalculatorFunction, LengthCalculatorFunction}; use tool_helper::{format_if_error, Output, read_file}; use types::{layout::Layout, CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr}; @@ -158,15 +159,23 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc, config_reader::DirMember::File(file) => { let (mut desc_file, needs_treatment) = { match file.kind { - config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), read_file(&file.path)?)?, false), - config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), read_file(&file.path)?, lba_source)?, true), - config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), file.path, lba_source)?, true), + config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), read_file(&file.path)?)?, false), + config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), read_file(&file.path)?, lba_source)?, true), + config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), } }; desc_file.properties.padded_size_bytes = file.common.padded_size; desc_file.properties.is_hidden = file.common.is_hidden; + match file.common.lz4_state { + LZ4State::None => desc_file.properties.is_lz4 = false, + LZ4State::AlreadyCompressed => desc_file.properties.is_lz4 = true, + LZ4State::Compress => { + return Err(Error::from_text(format!("LZ4 compression requested for file {} but feature is not supported yet", &file.path.to_string_lossy()))); + } + } + let new_file = dst_dir.add_file(desc_file); if needs_treatment { lba_embedded_files.push(new_file); diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index 60023c9e..a25af325 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -316,7 +316,8 @@ pub struct Properties { pub(super) lba: LBA, pub(super) size_bytes: usize, pub(super) padded_size_bytes: Option, - pub(super) is_hidden: bool + pub(super) is_hidden: bool, + pub(super) is_lz4: bool, } impl Properties { @@ -341,7 +342,7 @@ impl Properties { impl Default for Properties { fn default() -> Self { - Properties{lba: LBA::default(), size_bytes: 0, padded_size_bytes: None, is_hidden: false} + Properties{lba: LBA::default(), size_bytes: 0, padded_size_bytes: None, is_hidden: false, is_lz4: false} } } diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index 6bca45e0..140e7824 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -23,7 +23,7 @@ impl LBAEntry { const _IS_LZ4_COMPRESSED:Bit = Bit::at(19); const LBA_VALUE_RANGE:BitRange = BitRange::from_to(0, 18); - pub fn write_entry(&mut self, lba: usize, size_bytes: usize) -> Result<(), Error> { + pub fn write_entry(&mut self, lba: usize, size_bytes: usize, _is_lz4: bool) -> Result<(), Error> { if lba > Self::LBA_VALUE_RANGE.max_value() { return Err(Error::from_text(format!("LBA of value {} is impossible and can not be encoded! Maximum LBA value is: {}", lba, Self::LBA_VALUE_RANGE.max_value()))); } @@ -45,8 +45,8 @@ impl LBAEntry { } } -pub fn load_from(file_name: &str, file_path: PathBuf, lba_source: PathBuf) -> Result { - let content = read_file(&file_path)?; +pub fn load_from(file_name: &str, file_path: &PathBuf, lba_source: PathBuf) -> Result { + let content = read_file(file_path)?; let lba_names = load_lba_names(lba_source)?; let content_size = format_if_error!(tool_helper::compress::psx_default::lz4(&content), "Compressing {} failed with \"{error_text}\"", file_path.to_string_lossy())?.len(); @@ -61,8 +61,8 @@ pub fn update_content(content: &mut Vec, lba_names: &LBANameVec, file_map: & let lba_header = skip_to_lba_header(content); let lba_header = unsafe{std::slice::from_raw_parts_mut(lba_header.as_mut_ptr() as *mut LBAEntry, lba_names.len())}; - for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes)| { - lba_header[idx].write_entry(lba, bytes) + for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes), is_lz4| { + lba_header[idx].write_entry(lba, bytes, is_lz4) })?; Ok(tool_helper::compress::psx_default::lz4(content)?) @@ -71,20 +71,22 @@ pub fn update_content(content: &mut Vec, lba_names: &LBANameVec, file_map: & pub fn update_content_for_main(content: &mut Vec, lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction) -> Result, Error> { let lba_header = unsafe{std::slice::from_raw_parts_mut(main::skip_to_lba_area(content).as_mut_ptr() as *mut LBAEntry, lba_names.len())}; - for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes)| { - lba_header[idx].write_entry(lba, bytes) + for_each_lba_name(lba_names, file_map, length_func, |idx, (lba, bytes), is_lz4| { + lba_header[idx].write_entry(lba, bytes, is_lz4) })?; Ok(content.clone()) } -fn for_each_lba_name Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> { +fn for_each_lba_name Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> { let mut idx = 0; for lba_name in lba_names { if let Some(file) = file_map.get(lba_name) { - let (lba, bytes) = (format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes); + let file_ref = format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?; + let (lba, bytes) = (file_ref.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes); + let is_lz4 = file_ref.properties.is_lz4; - functor(idx, (lba, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?; + functor(idx, (lba, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?), is_lz4)?; idx += 1; } From 37156a1432df48e2feb3bc3eb93305c9a4cd3ea8 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 13 Apr 2023 21:22:49 +0200 Subject: [PATCH 37/47] Improve error messages for not finding LBA sources --- src/Tools/psxcdgen_ex/src/lib.rs | 2 +- .../psxcdgen_ex/src/types/overlay/mod.rs | 4 ++-- src/Tools/tool_helper/src/lib.rs | 19 +++++++++++++------ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Tools/psxcdgen_ex/src/lib.rs b/src/Tools/psxcdgen_ex/src/lib.rs index 028acab7..d2f93eed 100644 --- a/src/Tools/psxcdgen_ex/src/lib.rs +++ b/src/Tools/psxcdgen_ex/src/lib.rs @@ -161,7 +161,7 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc, match file.kind { config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), read_file(&file.path)?)?, false), config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), read_file(&file.path)?, lba_source)?, true), - config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), + config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), } }; diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index 140e7824..74feb9f4 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -2,7 +2,7 @@ use super::{bits::{Bit, BitRange}, layout::Layout, File, FileSystemMap}; use super::super::encoder::LengthCalculatorFunction; use std::path::PathBuf; use no_comment::{IntoWithoutComments as _, languages}; -use tool_helper::{Error, format_if_error, read_file, format_if_error_drop_cause}; +use tool_helper::{Error, format_if_error, read_file, read_file_to_string, format_if_error_drop_cause}; pub type LBANameVec = Vec; @@ -121,7 +121,7 @@ fn load_lba_names(lba_source: PathBuf) -> Result { Ok(file[start..end].to_owned()) } - let file = std::fs::read_to_string(&lba_source)?.chars().without_comments(languages::c()).collect::(); + let file = read_file_to_string(&lba_source)?.chars().without_comments(languages::c()).collect::(); let file = get_part_of_interest(file, &lba_source)?; let mut lba_names = Vec::new(); diff --git a/src/Tools/tool_helper/src/lib.rs b/src/Tools/tool_helper/src/lib.rs index 105e214c..bc5bc548 100644 --- a/src/Tools/tool_helper/src/lib.rs +++ b/src/Tools/tool_helper/src/lib.rs @@ -184,11 +184,18 @@ pub fn input_to_vec(input: Input) -> Result, Error> { pub fn read_file(file_path: &PathBuf) -> Result, Error> { match std::fs::read(file_path) { - Ok(data) => { - Ok(data) - }, - Err(error) => { - Err(Error::from_text(format!("Failed reading file {} with error: \"{}\"", file_path.display(), error))) - } + Ok(data) => Ok(data), + Err(error) => create_file_read_error(file_path, error), } +} + +pub fn read_file_to_string(file_path: &PathBuf) -> Result { + match std::fs::read_to_string(file_path) { + Ok(string) => Ok(string), + Err(error) => create_file_read_error(file_path, error), + } +} + +fn create_file_read_error(file_path: &PathBuf, error: std::io::Error) -> Result { + Err(Error::from_text(format!("Failed reading file {} with error: \"{}\"", file_path.display(), error))) } \ No newline at end of file From 30561183fd6fb59d1c119ba681f94f01f42f7715 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 13 Apr 2023 21:51:45 +0200 Subject: [PATCH 38/47] Detect LZ4 files correctly now --- include/PSX/AutoLBA/auto_lba.hpp | 6 +++--- .../src/File/Processor/cd_file_processor.cpp | 2 +- src/Tools/psxcdgen_ex/src/types/overlay/mod.rs | 15 +++++++-------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/include/PSX/AutoLBA/auto_lba.hpp b/include/PSX/AutoLBA/auto_lba.hpp index e1dc7358..51291181 100644 --- a/include/PSX/AutoLBA/auto_lba.hpp +++ b/include/PSX/AutoLBA/auto_lba.hpp @@ -31,12 +31,12 @@ namespace JabyEngine { return const_cast(this)->get_size_in_sectors(); } - constexpr bool isLZ4() const { + constexpr bool is_lz4() const { return bit::is_set(this->value, AutoLBAEntry::IsLZ4Compressed); } - constexpr bool isLZ4() const volatile { - return const_cast(this)->isLZ4(); + constexpr bool is_lz4() const volatile { + return const_cast(this)->is_lz4(); } }; } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 5e191bb9..e25b286c 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -52,7 +52,7 @@ namespace JabyEngine { return self.circular_buffer.allocate(); })); - printf(">>> CD needs to load LBA: %i -> %i\n", cur_lba.get_lba(), cur_lba.get_size_in_sectors()); + printf(">>> CD needs to load LBA: %i -> %i (is LZ4: [%s])\n", cur_lba.get_lba(), cur_lba.get_size_in_sectors(), cur_lba.is_lz4() ? "Yes" : "No"); } bool CDFileProcessor :: process_data() { diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index 74feb9f4..2cb8482b 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -8,11 +8,6 @@ pub type LBANameVec = Vec; mod main; -/* -Size in sectors [22, 31]; -Is LZ4 compressed [19]; -LBA value [0, 18] -*/ #[repr(packed)] struct LBAEntry { raw: u32, @@ -20,10 +15,10 @@ struct LBAEntry { impl LBAEntry { const SIZE_IN_SECTOR_RANGE:BitRange = BitRange::from_to(22, 31); - const _IS_LZ4_COMPRESSED:Bit = Bit::at(19); + const IS_LZ4_COMPRESSED:Bit = Bit::at(19); const LBA_VALUE_RANGE:BitRange = BitRange::from_to(0, 18); - pub fn write_entry(&mut self, lba: usize, size_bytes: usize, _is_lz4: bool) -> Result<(), Error> { + pub fn write_entry(&mut self, lba: usize, size_bytes: usize, is_lz4: bool) -> Result<(), Error> { if lba > Self::LBA_VALUE_RANGE.max_value() { return Err(Error::from_text(format!("LBA of value {} is impossible and can not be encoded! Maximum LBA value is: {}", lba, Self::LBA_VALUE_RANGE.max_value()))); } @@ -40,7 +35,11 @@ impl LBAEntry { return Err(Error::from_str("LBA Entry will overwrite non-zero value!\nIs no space allocated for the LBA Entries?")); } - self.raw = Self::SIZE_IN_SECTOR_RANGE.or_value(Self::LBA_VALUE_RANGE.or_value(0, lba), size_in_sectors) as u32; + let new_raw = Self::LBA_VALUE_RANGE.or_value(0, lba); + let new_raw = Self::SIZE_IN_SECTOR_RANGE.or_value(new_raw, size_in_sectors); + let new_raw = Self::IS_LZ4_COMPRESSED.or_value(new_raw, is_lz4); + + self.raw = new_raw as u32; Ok(()) } } From e21d7c5d505c1de363542420d7b5927d26085ec5 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 13 Apr 2023 22:10:34 +0200 Subject: [PATCH 39/47] Use LZ4 file info --- include/PSX/File/cd_file_types.hpp | 3 +- .../src/File/Processor/cd_file_processor.cpp | 57 ++++++++++--------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/include/PSX/File/cd_file_types.hpp b/include/PSX/File/cd_file_types.hpp index b6ff973f..67634209 100644 --- a/include/PSX/File/cd_file_types.hpp +++ b/include/PSX/File/cd_file_types.hpp @@ -7,7 +7,6 @@ namespace JabyEngine { enum struct CDFileType : uint8_t { SimpleTIM = 0, CopyTo, - Overlay, }; struct __no_align CDFile { @@ -35,7 +34,7 @@ namespace JabyEngine { } static constexpr CDFile overlay(uint8_t rel_lba_idx, uint32_t* overlay_dst) { - return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::Overlay, .payload = {.overlay = Overlay{overlay_dst}}}; + return CDFile{.rel_lba_idx = rel_lba_idx, .type = CDFileType::CopyTo, .payload = {.overlay = Overlay{overlay_dst}}}; } }; } diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index e25b286c..5d62d3f7 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -8,44 +8,49 @@ namespace JabyEngine { void CDFileProcessor :: start_cur_job() { using CD::internal::SectorBufferAllocator; - const auto configurate_for = [this](const CDFile& file) { - const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { - uint8_t*const dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + const auto configurate_for = [this](const CDFile& file, bool is_lz4) -> FileProcessor::State { + const uint32_t* data_adr = [this](const CDFile& file, bool is_lz4) -> const uint32_t* { + const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { + uint8_t*const dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); - this->lz4_decomp.disable(); - return overwrite_dst ? overwrite_dst : reinterpret_cast(dst_adr); - }; + this->lz4_decomp.disable(); + return overwrite_dst ? overwrite_dst : reinterpret_cast(dst_adr); + }; - const auto enable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* override_dst = nullptr) -> uint32_t* { - uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); - - if(override_dst) { - dst_adr = reinterpret_cast(override_dst); + const auto enable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* override_dst = nullptr) -> uint32_t* { + uint8_t* dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + + if(override_dst) { + dst_adr = reinterpret_cast(override_dst); + } + + this->lz4_decomp.setup(dst_adr); + return reinterpret_cast(dst_adr); + }; + + if(file.type == CDFileType::CopyTo) { + return is_lz4 ? enable_lz4(this->tmp_area, NormalCircularBufferSize, file.payload.overlay.dst) : disable_lz4(file.payload.copy_to.dst, DisabledCircularBufferSize); } - - this->lz4_decomp.setup(dst_adr); - return reinterpret_cast(dst_adr); - }; + + else { + return is_lz4 ? enable_lz4(this->tmp_area, NormalCircularBufferSize) : disable_lz4(this->tmp_area, DisabledCircularBufferSize); + } + }(file, is_lz4); switch(file.type) { case CDFileType::SimpleTIM: - this->file_state = FileProcessor::create(enable_lz4(this->tmp_area, NormalCircularBufferSize), file.payload.simple_tim); - break; - + return FileProcessor::create(data_adr, file.payload.simple_tim); + case CDFileType::CopyTo: - this->file_state = FileProcessor::create(disable_lz4(file.payload.copy_to.dst, 512), Nothing()); - break; - - case CDFileType::Overlay: - this->file_state = FileProcessor::create(enable_lz4(this->tmp_area, NormalCircularBufferSize, file.payload.overlay.dst), Nothing()); - break; - } + default: + return FileProcessor::create(data_adr, Nothing()); + } }; const auto& cur_job = *this->jobs.files; const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; - configurate_for(cur_job); + this->file_state = configurate_for(cur_job, cur_lba.is_lz4()); CD::internal::read_file(cur_lba, SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* { CDFileProcessor &self = *reinterpret_cast(ctx); From e4657337f934b1784c1ca78e2bb363b93fd73d64 Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 16 Apr 2023 21:11:10 +0200 Subject: [PATCH 40/47] Reduce CDFileProcessor size and add configuratable buffer size --- .../PSX/File/Processor/cd_file_processor.hpp | 32 +++++++++++-------- .../src/File/Processor/cd_file_processor.cpp | 28 +++++++--------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/PSX/File/Processor/cd_file_processor.hpp b/include/PSX/File/Processor/cd_file_processor.hpp index 552541b4..42b408c5 100644 --- a/include/PSX/File/Processor/cd_file_processor.hpp +++ b/include/PSX/File/Processor/cd_file_processor.hpp @@ -12,6 +12,18 @@ extern "C" uint32_t __heap_base; namespace JabyEngine { class CDFileProcessor { public: + struct BufferConfiguration { + static constexpr size_t SmallSectorCount = 5; + static constexpr size_t MediumSectorCount = 16; + + uint32_t* adr = nullptr; + size_t sector_count = 0; + + static constexpr BufferConfiguration new_default() { + return {&__heap_base, BufferConfiguration::MediumSectorCount}; + } + }; + struct JobArray { const CDFile* files = nullptr; size_t size = 0; @@ -29,27 +41,25 @@ namespace JabyEngine { CircularBuffer circular_buffer; LZ4Decompressor lz4_decomp; JobArray jobs; - const AutoLBAEntry* lba = nullptr; - uint32_t* tmp_area = nullptr; - void start_cur_job(); + void start_cur_job(const AutoLBAEntry* lba, const BufferConfiguration& buf_cfg); bool process_data(); public: CDFileProcessor() = default; - void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area = &__heap_base); - + void setup(const volatile AutoLBAEntry* lba, JobArray jobs, const BufferConfiguration& buf_cfg); + template - void setup(const volatile AutoLBAEntry* lba, const CDFile (&file_array)[N], uint32_t* tmp_area = &__heap_base) { - CDFileProcessor::setup(lba, JobArray{file_array, N}, tmp_area); + void setup(const volatile AutoLBAEntry* lba, const CDFile (&file_array)[N], const BufferConfiguration& buf_cfg) { + CDFileProcessor::setup(lba, JobArray{file_array, N}, buf_cfg); } Progress process(); - bool next() { + bool next(const volatile AutoLBAEntry* lba, const BufferConfiguration& buf_cfg) { if(this->jobs.next()) { - CDFileProcessor::start_cur_job(); + CDFileProcessor::start_cur_job(const_cast(lba), buf_cfg); return true; } @@ -58,8 +68,4 @@ namespace JabyEngine { }; } -// This will be used as the file processor but will work on cd types -// Will probably use file_processor -// Will also setup the circular buffer for the CD code - #endif //!__JABYENGINE_CD_FILE_PROCESSOR_HPP__ \ No newline at end of file diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 5d62d3f7..3ff5c844 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -3,13 +3,12 @@ #include namespace JabyEngine { - static constexpr auto NormalCircularBufferSize = 5; static constexpr auto DisabledCircularBufferSize = 512; - void CDFileProcessor :: start_cur_job() { + void CDFileProcessor :: start_cur_job(const AutoLBAEntry* lba, const BufferConfiguration& buf_cfg) { using CD::internal::SectorBufferAllocator; - const auto configurate_for = [this](const CDFile& file, bool is_lz4) -> FileProcessor::State { - const uint32_t* data_adr = [this](const CDFile& file, bool is_lz4) -> const uint32_t* { + const auto configurate_for = [this](const CDFile& file, const BufferConfiguration& buf_cfg, bool is_lz4) -> FileProcessor::State { + const uint32_t* data_adr = [this](const CDFile& file, const BufferConfiguration& buf_cfg, bool is_lz4) -> const uint32_t* { const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { uint8_t*const dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); @@ -29,13 +28,13 @@ namespace JabyEngine { }; if(file.type == CDFileType::CopyTo) { - return is_lz4 ? enable_lz4(this->tmp_area, NormalCircularBufferSize, file.payload.overlay.dst) : disable_lz4(file.payload.copy_to.dst, DisabledCircularBufferSize); + return is_lz4 ? enable_lz4(buf_cfg.adr, buf_cfg.sector_count, file.payload.overlay.dst) : disable_lz4(file.payload.copy_to.dst, DisabledCircularBufferSize); } else { - return is_lz4 ? enable_lz4(this->tmp_area, NormalCircularBufferSize) : disable_lz4(this->tmp_area, DisabledCircularBufferSize); + return is_lz4 ? enable_lz4(buf_cfg.adr, buf_cfg.sector_count) : disable_lz4(buf_cfg.adr, DisabledCircularBufferSize); } - }(file, is_lz4); + }(file, buf_cfg, is_lz4); switch(file.type) { case CDFileType::SimpleTIM: @@ -48,9 +47,9 @@ namespace JabyEngine { }; const auto& cur_job = *this->jobs.files; - const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; + const auto& cur_lba = lba[cur_job.rel_lba_idx]; - this->file_state = configurate_for(cur_job, cur_lba.is_lz4()); + this->file_state = configurate_for(cur_job, buf_cfg, cur_lba.is_lz4()); CD::internal::read_file(cur_lba, SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* { CDFileProcessor &self = *reinterpret_cast(ctx); @@ -82,12 +81,9 @@ namespace JabyEngine { return true; } - void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area) { - this->lba = const_cast(lba); - this->jobs = jobs; - - this->tmp_area = tmp_area; - CDFileProcessor::start_cur_job(); + void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, const BufferConfiguration& buf_cfg) { + this->jobs = jobs; + CDFileProcessor::start_cur_job(const_cast(lba), buf_cfg); } Progress CDFileProcessor :: process() { @@ -100,7 +96,7 @@ namespace JabyEngine { We are done now! The user decides if he wants the next value */ - //while(this->file_state.process(0) != Progress::Done); + //while(this->file_state.process(0) != Progress::Done); return Progress::Done; case CD::internal::State::BufferFull: From e6042808eeb3e12b9e77adc89def6141f9c9c3ce Mon Sep 17 00:00:00 2001 From: jaby Date: Sun, 16 Apr 2023 21:39:47 +0200 Subject: [PATCH 41/47] Remove BootFiles. Setup code needs improving --- include/PSX/jabyengine.hpp | 29 +------------------ lib/PSEXETarget.mk | 4 --- src/Library/Makefile | 14 ++------- .../BootLoader/boot_loader.hpp | 6 +--- .../src/BootLoader/boot_file/main_boot.cpp | 17 ----------- .../src/BootLoader/boot_file/overlay_boot.cpp | 13 --------- src/Library/src/BootLoader/start_boot.cpp | 3 +- src/Library/src/startup.cpp | 29 +++++-------------- 8 files changed, 13 insertions(+), 102 deletions(-) delete mode 100644 src/Library/src/BootLoader/boot_file/main_boot.cpp delete mode 100644 src/Library/src/BootLoader/boot_file/overlay_boot.cpp diff --git a/include/PSX/jabyengine.hpp b/include/PSX/jabyengine.hpp index 867d8f16..8842bde9 100644 --- a/include/PSX/jabyengine.hpp +++ b/include/PSX/jabyengine.hpp @@ -3,34 +3,7 @@ #include "../stdint.h" namespace JabyEngine { - struct NextRoutine { - static constexpr uintptr_t OverlayBit = (1 << ((sizeof(uintptr_t)*8) - 2)); - typedef NextRoutine (*MainRoutine)(); - - uintptr_t value; - - constexpr static NextRoutine null() { - return {.value = 0}; - } - - static NextRoutine from(MainRoutine function) { - return {.value = reinterpret_cast(function)}; - } - - constexpr bool is_overlay() const { - return (this->value & OverlayBit); - } - - constexpr bool is_absolute() const { - return !NextRoutine::is_overlay(); - } - - constexpr bool is_null() const { - return this->value == 0; - } - }; - - typedef NextRoutine::MainRoutine MainRoutine; + typedef void (*MainRoutine)(); } #endif //!__JABYENGINE__HPP__ \ No newline at end of file diff --git a/lib/PSEXETarget.mk b/lib/PSEXETarget.mk index 295089a9..7445dd7d 100644 --- a/lib/PSEXETarget.mk +++ b/lib/PSEXETarget.mk @@ -7,10 +7,6 @@ include $(AUTO_OVERLAY_DIR)/Overlays.mk JABY_ENGINE_LIB_DIR = $(JABY_ENGINE_DIR)/lib/PSX-$(BUILD_PROFILE) JABY_ENGINE_LIB_NAME = JabyEngine_$(TV_FORMAT) -#Bind this to the overlay.json file maybe? -BOOT_TYPE = main -OBJS += $(JABY_ENGINE_LIB_DIR)/$(BOOT_TYPE)_boot.o - #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$(JABY_ENGINE_LIB_NAME) $(LIBS) diff --git a/src/Library/Makefile b/src/Library/Makefile index 688e59aa..4183fabe 100644 --- a/src/Library/Makefile +++ b/src/Library/Makefile @@ -16,9 +16,7 @@ SRCS += src/syscall_printf.asm include ../../lib/Makefile LIB_DIR = ../../lib/$(CONFIG_NAME) -MAIN_BOOT_OBJ = $(filter %/main_boot.o,$(OBJS)) -OVERLAY_BOOT_OBJ = $(filter %/overlay_boot.o,$(OBJS)) -MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS)) +MAIN_LIB_OBJS = $(filter-out $(MAIN_BOOT_OBJ) $(OVERLAY_BOOT_OBJ),$(OBJS)) #$(info $$var is [${MAIN_BOOT_OBJ}]) #$(info $$var2 is [${MAIN_LIB_OBJS}]) @@ -33,14 +31,6 @@ $(LIB_DIR)/$(ARTIFACT).a: $(TARGET).a @mkdir -p $(LIB_DIR) cp $(TARGET).a $(LIB_DIR)/$(ARTIFACT).a -$(LIB_DIR)/$(notdir $(MAIN_BOOT_OBJ)): $(MAIN_BOOT_OBJ) - @mkdir -p $(LIB_DIR) - cp $(MAIN_BOOT_OBJ) $(LIB_DIR)/$(notdir $(MAIN_BOOT_OBJ)) - -$(LIB_DIR)/$(notdir $(OVERLAY_BOOT_OBJ)): $(OVERLAY_BOOT_OBJ) - @mkdir -p $(LIB_DIR) - cp $(OVERLAY_BOOT_OBJ) $(LIB_DIR)/$(notdir $(OVERLAY_BOOT_OBJ)) - # Improve later # rule to make the boot image $(SPLASH_IMAGE): ressources/Splash.png @@ -50,7 +40,7 @@ $(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 $(LIB_DIR)/$(notdir $(MAIN_BOOT_OBJ)) $(LIB_DIR)/$(notdir $(OVERLAY_BOOT_OBJ)) +all: $(SPLASH_IMAGE) $(SPLASH_IMAGE_NTSC) $(LIB_DIR)/$(ARTIFACT).a clean: rm -fr $(SPLASH_IMAGE) diff --git a/src/Library/internal-include/BootLoader/boot_loader.hpp b/src/Library/internal-include/BootLoader/boot_loader.hpp index 8153adc8..68b24c93 100644 --- a/src/Library/internal-include/BootLoader/boot_loader.hpp +++ b/src/Library/internal-include/BootLoader/boot_loader.hpp @@ -5,10 +5,6 @@ namespace JabyEngine { //boot namespace? namespace boot { - namespace BootFile { - JabyEngine::NextRoutine setup(); - } - namespace CD { void setup(); } @@ -24,7 +20,7 @@ namespace JabyEngine { } namespace Start { - JabyEngine::NextRoutine setup(); + void setup(); } namespace Timer { diff --git a/src/Library/src/BootLoader/boot_file/main_boot.cpp b/src/Library/src/BootLoader/boot_file/main_boot.cpp deleted file mode 100644 index 711ead13..00000000 --- a/src/Library/src/BootLoader/boot_file/main_boot.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "../../../internal-include/BootLoader/boot_loader.hpp" -#include - -#include - -extern JabyEngine::NextRoutine main(); - -namespace JabyEngine { - namespace boot { - namespace BootFile { - JabyEngine::NextRoutine setup() { - printf("Running main!\n"); - return JabyEngine::NextRoutine::from(main); - } - } - } -} \ No newline at end of file diff --git a/src/Library/src/BootLoader/boot_file/overlay_boot.cpp b/src/Library/src/BootLoader/boot_file/overlay_boot.cpp deleted file mode 100644 index decd2942..00000000 --- a/src/Library/src/BootLoader/boot_file/overlay_boot.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "../../../internal-include/BootLoader/boot_loader.hpp" -#include - -namespace JabyEngine { - namespace boot { - namespace BootFile { - JabyEngine::NextRoutine setup() { - printf("Overlay boot not implemented!\n"); - return JabyEngine::NextRoutine::null(); - } - } - } -} \ 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 ee4bf32d..2fce71e4 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -13,7 +13,7 @@ namespace JabyEngine { DMA_IO::DPCR = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable).set(DMA_IO::DPCR_t::CDROMEnable); } - JabyEngine::NextRoutine setup() { + void setup() { enable_DMA(); SPU::stop_voices(); @@ -31,7 +31,6 @@ namespace JabyEngine { //Pause?? SPU::setup(); - return BootFile::setup(); } } } diff --git a/src/Library/src/startup.cpp b/src/Library/src/startup.cpp index 78c2ede0..59bcb99a 100644 --- a/src/Library/src/startup.cpp +++ b/src/Library/src/startup.cpp @@ -1,29 +1,16 @@ #include "../internal-include/BootLoader/boot_loader.hpp" #include +extern void main(); + namespace JabyEngine { - static NextRoutine execute(NextRoutine routine) { - // Support currently only direct call - return reinterpret_cast((routine.value & ~JabyEngine::NextRoutine::OverlayBit))(); - } - void start() { - NextRoutine next_routine = JabyEngine::NextRoutine::from(boot::Start::setup); - - printf("Starting Planschbecken 0x%p\n", next_routine.value); - while(true) { - if(next_routine.is_null()) { - break; - } - - if(next_routine.is_overlay()) { - printf("Overlay not supported yet!\n"); - break; - } - - next_routine = execute(next_routine); - } - printf("Stop!\n"); + printf("Starting Planschbecken\n"); + boot::Start::setup(); + + printf("Running main...\n"); + main(); + printf("Stop!!\n"); while(true); } } \ No newline at end of file From e833b758cc090967cf495d7c3b44d4fe4238f6c0 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 17 Apr 2023 20:21:32 +0200 Subject: [PATCH 42/47] Improve starting of the game and reduce persistent memory usage --- include/PSX/jabyengine.hpp | 2 +- include/PSX/jabyengine_defines.h | 1 + .../internal-include/BootLoader/boot_loader.hpp | 7 ++----- src/Library/src/BootLoader/start_boot.cpp | 10 +++++++++- src/Library/src/run.cpp | 12 ++++++++++++ src/Library/src/startup.cpp | 16 ---------------- 6 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 src/Library/src/run.cpp delete mode 100644 src/Library/src/startup.cpp diff --git a/include/PSX/jabyengine.hpp b/include/PSX/jabyengine.hpp index 8842bde9..65a33360 100644 --- a/include/PSX/jabyengine.hpp +++ b/include/PSX/jabyengine.hpp @@ -1,6 +1,6 @@ #ifndef __JABYENGINE__HPP__ #define __JABYENGINE__HPP__ -#include "../stdint.h" +#include "jabyengine_defines.h" namespace JabyEngine { typedef void (*MainRoutine)(); diff --git a/include/PSX/jabyengine_defines.h b/include/PSX/jabyengine_defines.h index a0957d14..8c838cb7 100644 --- a/include/PSX/jabyengine_defines.h +++ b/include/PSX/jabyengine_defines.h @@ -6,6 +6,7 @@ #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__ diff --git a/src/Library/internal-include/BootLoader/boot_loader.hpp b/src/Library/internal-include/BootLoader/boot_loader.hpp index 68b24c93..888c1b54 100644 --- a/src/Library/internal-include/BootLoader/boot_loader.hpp +++ b/src/Library/internal-include/BootLoader/boot_loader.hpp @@ -3,7 +3,6 @@ #include namespace JabyEngine { - //boot namespace? namespace boot { namespace CD { void setup(); @@ -19,13 +18,11 @@ namespace JabyEngine { void setup(); } - namespace Start { - void setup(); - } - namespace Timer { void setup(); } } + + void __no_return run(); } #endif //!BOOT_LOADER_HPP \ 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 2fce71e4..111c5fbf 100644 --- a/src/Library/src/BootLoader/start_boot.cpp +++ b/src/Library/src/BootLoader/start_boot.cpp @@ -13,7 +13,7 @@ namespace JabyEngine { DMA_IO::DPCR = DMA_IO::DPCR_t(DMA_IO::DPCR).set(DMA_IO::DPCR_t::SPUEnable).set(DMA_IO::DPCR_t::GPUEnable).set(DMA_IO::DPCR_t::CDROMEnable); } - void setup() { + static void setup() { enable_DMA(); SPU::stop_voices(); @@ -34,4 +34,12 @@ namespace JabyEngine { } } } + + void start() { + printf("Starting Planschbecken\n"); + boot::Start::setup(); + + printf("Running main...\n"); + run(); + } } \ No newline at end of file diff --git a/src/Library/src/run.cpp b/src/Library/src/run.cpp new file mode 100644 index 00000000..37038004 --- /dev/null +++ b/src/Library/src/run.cpp @@ -0,0 +1,12 @@ +#include + +extern void main(); + +namespace JabyEngine { + // Executes the game + void __no_return run() { + main(); + printf("Stop!!\n"); + while(true); + } +} \ No newline at end of file diff --git a/src/Library/src/startup.cpp b/src/Library/src/startup.cpp deleted file mode 100644 index 59bcb99a..00000000 --- a/src/Library/src/startup.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "../internal-include/BootLoader/boot_loader.hpp" -#include - -extern void main(); - -namespace JabyEngine { - void start() { - printf("Starting Planschbecken\n"); - boot::Start::setup(); - - printf("Running main...\n"); - main(); - printf("Stop!!\n"); - while(true); - } -} \ No newline at end of file From 6481e06808626184b3e7c7b76c081ee164851074 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 17 Apr 2023 21:05:22 +0200 Subject: [PATCH 43/47] Fix disabled LZ4 bug --- src/Library/src/File/Processor/cd_file_processor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Library/src/File/Processor/cd_file_processor.cpp b/src/Library/src/File/Processor/cd_file_processor.cpp index 3ff5c844..04bf7f8a 100644 --- a/src/Library/src/File/Processor/cd_file_processor.cpp +++ b/src/Library/src/File/Processor/cd_file_processor.cpp @@ -10,10 +10,10 @@ namespace JabyEngine { const auto configurate_for = [this](const CDFile& file, const BufferConfiguration& buf_cfg, bool is_lz4) -> FileProcessor::State { const uint32_t* data_adr = [this](const CDFile& file, const BufferConfiguration& buf_cfg, bool is_lz4) -> const uint32_t* { const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { - uint8_t*const dst_adr = reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); + reinterpret_cast(this->circular_buffer.setup(reinterpret_cast(work_area), size)); this->lz4_decomp.disable(); - return overwrite_dst ? overwrite_dst : reinterpret_cast(dst_adr); + return overwrite_dst ? overwrite_dst : reinterpret_cast(work_area); }; const auto enable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* override_dst = nullptr) -> uint32_t* { From 8a43b836cb5d87da54da7b58ca864d5f5ee1d228 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 17 Apr 2023 21:34:24 +0200 Subject: [PATCH 44/47] Support LZ4 compression in psxcdgen_ex --- src/Tools/psxcdgen_ex/src/lib.rs | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Tools/psxcdgen_ex/src/lib.rs b/src/Tools/psxcdgen_ex/src/lib.rs index d2f93eed..2525acd4 100644 --- a/src/Tools/psxcdgen_ex/src/lib.rs +++ b/src/Tools/psxcdgen_ex/src/lib.rs @@ -9,6 +9,7 @@ use config_reader::LZ4State; use encoder::{LbaCalculatorFunction, LengthCalculatorFunction}; use tool_helper::{format_if_error, Output, read_file}; use types::{layout::Layout, CDDesc, Directory, File, FileType, FileSystemMap, Properties, SharedPtr}; +use std::path::PathBuf; pub type LBAEmbeddedFiles = Vec>; @@ -157,25 +158,31 @@ fn parse_configuration(config: config_reader::Configuration) -> Result<(CDDesc, }, config_reader::DirMember::File(file) => { + let lz4_state = file.common.lz4_state; let (mut desc_file, needs_treatment) = { + fn handle_file_load(file_path: &PathBuf, lz4_state: &LZ4State) -> Result, Error> { + let file_content = read_file(file_path)?; + + if matches!(lz4_state, LZ4State::Compress) { + tool_helper::compress::psx_default::lz4(&file_content) + } + + else { + Ok(file_content) + } + } + match file.kind { - config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), read_file(&file.path)?)?, false), - config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), read_file(&file.path)?, lba_source)?, true), - config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), + config_reader::FileKind::Regular => (types::File::new_regular(file.common.name.as_str(), handle_file_load(&file.path, &lz4_state)?)?, false), + config_reader::FileKind::Main(lba_source) => (types::overlay::load_for_main(file.common.name.as_str(), handle_file_load(&file.path, &lz4_state)?, lba_source)?, true), + config_reader::FileKind::Overlay(lba_source) => (types::overlay::load_from(file.common.name.as_str(), &file.path, lba_source)?, true), } }; desc_file.properties.padded_size_bytes = file.common.padded_size; desc_file.properties.is_hidden = file.common.is_hidden; + desc_file.properties.is_lz4 = !matches!(lz4_state, LZ4State::None); - match file.common.lz4_state { - LZ4State::None => desc_file.properties.is_lz4 = false, - LZ4State::AlreadyCompressed => desc_file.properties.is_lz4 = true, - LZ4State::Compress => { - return Err(Error::from_text(format!("LZ4 compression requested for file {} but feature is not supported yet", &file.path.to_string_lossy()))); - } - } - let new_file = dst_dir.add_file(desc_file); if needs_treatment { lba_embedded_files.push(new_file); From dff169ae10ae9339f582a3c08f54a209b96a8e68 Mon Sep 17 00:00:00 2001 From: jaby Date: Mon, 17 Apr 2023 21:45:03 +0200 Subject: [PATCH 45/47] Create wslpath project --- src/Tools/.config_build_all/recommended.bat | 2 +- src/Tools/Tools.code-workspace | 2 +- src/Tools/psxcdgen_ex/Cargo.toml | 2 +- src/Tools/wslpath/Cargo.toml | 8 ++++++++ src/Tools/wslpath/src/lib.rs | 14 ++++++++++++++ src/Tools/wslpath/src/main.rs | 3 +++ 6 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/Tools/wslpath/Cargo.toml create mode 100644 src/Tools/wslpath/src/lib.rs create mode 100644 src/Tools/wslpath/src/main.rs diff --git a/src/Tools/.config_build_all/recommended.bat b/src/Tools/.config_build_all/recommended.bat index be37466e..4779c8f0 100644 --- a/src/Tools/.config_build_all/recommended.bat +++ b/src/Tools/.config_build_all/recommended.bat @@ -1,4 +1,4 @@ -set bin_projects=psxcdgen psxcdread psxcdgen_ex +set bin_projects=psxcdgen psxcdread psxcdgen_ex wslpath set bin_linux_projects=cpp_out jaby_engine_fconv mkoverlay set clean_projects=cdtypes set clean_projects_linux=tool_helper \ No newline at end of file diff --git a/src/Tools/Tools.code-workspace b/src/Tools/Tools.code-workspace index dd1e23fb..a1732433 100644 --- a/src/Tools/Tools.code-workspace +++ b/src/Tools/Tools.code-workspace @@ -59,7 +59,7 @@ { "id": "project", "type": "pickString", - "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxcdgen", "psxcdgen_ex", "psxcdread", "tool_helper"], + "options": ["cdtypes", "cpp_out", "jaby_engine_fconv", "mkoverlay", "psxcdgen", "psxcdgen_ex", "psxcdread", "tool_helper", "wslpath"], "description": "project to build" }, { diff --git a/src/Tools/psxcdgen_ex/Cargo.toml b/src/Tools/psxcdgen_ex/Cargo.toml index 1a5ed62b..5805d87c 100644 --- a/src/Tools/psxcdgen_ex/Cargo.toml +++ b/src/Tools/psxcdgen_ex/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "psxcdgen_ex" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/Tools/wslpath/Cargo.toml b/src/Tools/wslpath/Cargo.toml new file mode 100644 index 00000000..9448e724 --- /dev/null +++ b/src/Tools/wslpath/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "wslpath" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/Tools/wslpath/src/lib.rs b/src/Tools/wslpath/src/lib.rs new file mode 100644 index 00000000..7d12d9af --- /dev/null +++ b/src/Tools/wslpath/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/src/Tools/wslpath/src/main.rs b/src/Tools/wslpath/src/main.rs new file mode 100644 index 00000000..90550e0f --- /dev/null +++ b/src/Tools/wslpath/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello Planschi"); +} \ No newline at end of file From 919d208a781ea019cd8f278ccfde6314459a2316 Mon Sep 17 00:00:00 2001 From: jaby Date: Tue, 18 Apr 2023 21:58:34 +0200 Subject: [PATCH 46/47] Finish wslpath --- src/Tools/wslpath/Cargo.toml | 3 ++- src/Tools/wslpath/src/lib.rs | 45 +++++++++++++++++++++++++++-------- src/Tools/wslpath/src/main.rs | 18 +++++++++++++- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/Tools/wslpath/Cargo.toml b/src/Tools/wslpath/Cargo.toml index 9448e724..38c5a00d 100644 --- a/src/Tools/wslpath/Cargo.toml +++ b/src/Tools/wslpath/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "wslpath" -version = "0.1.0" +version = "1.0.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap = {version = "*", features = ["derive"]} \ No newline at end of file diff --git a/src/Tools/wslpath/src/lib.rs b/src/Tools/wslpath/src/lib.rs index 7d12d9af..28b2a23e 100644 --- a/src/Tools/wslpath/src/lib.rs +++ b/src/Tools/wslpath/src/lib.rs @@ -1,14 +1,39 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right +pub fn convert(path: String) -> String { + replace_drive_letter(convert_slashes(path)) } -#[cfg(test)] -mod tests { - use super::*; +fn convert_slashes(path: String) -> String { + path.replace('\\', "/") +} - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); +fn replace_drive_letter(mut path: String) -> String { + let has_drive_letter = { + let drive_letter = path.get(0..2); + + if let Some(drive_letter) = drive_letter { + let starts_with_letter = drive_letter.chars().nth(0).unwrap_or('1').is_alphabetic(); + let has_seperator = drive_letter.chars().nth(1).unwrap_or('x') == ':'; + + starts_with_letter && has_seperator + } + + else { + false + } + }; + + if has_drive_letter { + path.replace_range(1..2, ""); // Removes : + if let Some(start_char) = path.get(0..1) { // Convert drive letter to lower case + path.replace_range(0..1, start_char.to_lowercase().as_str()); + } + + if path.len() == 3 { + path.push('/'); + } + + path.insert_str(0, "/mnt/"); } -} + + path +} \ No newline at end of file diff --git a/src/Tools/wslpath/src/main.rs b/src/Tools/wslpath/src/main.rs index 90550e0f..c9f05efe 100644 --- a/src/Tools/wslpath/src/main.rs +++ b/src/Tools/wslpath/src/main.rs @@ -1,3 +1,19 @@ +use clap::Parser; + +#[derive(Parser)] +#[clap(about = "A copy of the wslpath tool from wsl for faster execution", long_about = None)] +struct CommandLine { + #[clap(value_parser, help="The input path to convert to WSL")] + path_string: String +} + fn main() { - println!("Hello Planschi"); + match CommandLine::try_parse() { + Ok(cmd_line) => { + print!("{}", wslpath::convert(cmd_line.path_string)); + }, + Err(error) => { + eprintln!("{}", error); + } + } } \ No newline at end of file From f6de41dc87bbef10365a378e38e9799612ba85d6 Mon Sep 17 00:00:00 2001 From: jaby Date: Thu, 20 Apr 2023 21:01:27 +0200 Subject: [PATCH 47/47] Move the bit types to tool_helper and merge them --- src/Tools/psxcdgen_ex/src/types/bits.rs | 42 ------------------- src/Tools/psxcdgen_ex/src/types/mod.rs | 1 - .../psxcdgen_ex/src/types/overlay/mod.rs | 4 +- src/Tools/tool_helper/src/bits.rs | 42 ++++++++++++++++--- 4 files changed, 39 insertions(+), 50 deletions(-) delete mode 100644 src/Tools/psxcdgen_ex/src/types/bits.rs diff --git a/src/Tools/psxcdgen_ex/src/types/bits.rs b/src/Tools/psxcdgen_ex/src/types/bits.rs deleted file mode 100644 index c9b899df..00000000 --- a/src/Tools/psxcdgen_ex/src/types/bits.rs +++ /dev/null @@ -1,42 +0,0 @@ -pub struct BitRange { - start: usize, - length: usize -} - -impl BitRange { - pub const fn from_to(start_bit: usize, end_bit: usize) -> Self { - Self{start: start_bit, length: (end_bit - start_bit) + 1} - } - - pub const fn get_mask(&self) -> usize { - self.max_value() - } - - pub const fn max_value(&self) -> usize { - (1 << self.length) - 1 - } - - pub const fn or_value(&self, dst_value: usize, value: usize) -> usize { - dst_value | ((value & self.get_mask()) << self.start) - } -} - -pub struct Bit { - pos: usize -} - -impl Bit { - pub const fn at(pos: usize) -> Self { - Bit{pos} - } - - pub const fn or_value(&self, dst_value: usize, is_set: bool) -> usize { - if is_set { - dst_value | (1 << self.pos) - } - - else { - dst_value - } - } -} \ No newline at end of file diff --git a/src/Tools/psxcdgen_ex/src/types/mod.rs b/src/Tools/psxcdgen_ex/src/types/mod.rs index a25af325..cad43dd0 100644 --- a/src/Tools/psxcdgen_ex/src/types/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/mod.rs @@ -1,4 +1,3 @@ -pub mod bits; pub (super) mod helper; pub mod layout; pub mod file_map; diff --git a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs index 2cb8482b..58cf1b65 100644 --- a/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs +++ b/src/Tools/psxcdgen_ex/src/types/overlay/mod.rs @@ -1,8 +1,8 @@ -use super::{bits::{Bit, BitRange}, layout::Layout, File, FileSystemMap}; +use super::{layout::Layout, File, FileSystemMap}; use super::super::encoder::LengthCalculatorFunction; use std::path::PathBuf; use no_comment::{IntoWithoutComments as _, languages}; -use tool_helper::{Error, format_if_error, read_file, read_file_to_string, format_if_error_drop_cause}; +use tool_helper::{bits::{Bit, BitRange}, Error, format_if_error, read_file, read_file_to_string, format_if_error_drop_cause}; pub type LBANameVec = Vec; diff --git a/src/Tools/tool_helper/src/bits.rs b/src/Tools/tool_helper/src/bits.rs index 3f03cf56..7dec95a7 100644 --- a/src/Tools/tool_helper/src/bits.rs +++ b/src/Tools/tool_helper/src/bits.rs @@ -1,11 +1,43 @@ pub struct BitRange { - pub start: usize, - pub len: usize, + start: usize, + length: usize } impl BitRange { - pub const fn from_to(start: usize, end: usize) -> BitRange { - BitRange{start, len: (end - start + 1)} + pub const fn from_to(start_bit: usize, end_bit: usize) -> Self { + Self{start: start_bit, length: (end_bit - start_bit) + 1} + } + + pub const fn get_mask(&self) -> usize { + self.max_value() + } + + pub const fn max_value(&self) -> usize { + (1 << self.length) - 1 + } + + pub const fn or_value(&self, dst_value: usize, value: usize) -> usize { + dst_value | ((value & self.get_mask()) << self.start) + } +} + +pub struct Bit { + pos: usize +} + +impl Bit { + pub const fn at(pos: usize) -> Self { + Bit{pos} + } + + pub const fn or_value(&self, dst_value: usize, is_set: bool) -> usize { + if is_set { + dst_value | (1 << self.pos) + } + + else { + dst_value + } } } @@ -13,7 +45,7 @@ macro_rules! create_bit_functions { ($type_val:ty) => { paste::item! { const fn [< get_mask_ $type_val >](range: &BitRange) -> $type_val { - (1 << range.len) - 1 + range.get_mask() as $type_val } pub const fn [< clear_value_ $type_val >](dst: $type_val, range: &BitRange) -> $type_val {