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