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