Support CopyTo now

This commit is contained in:
Jaby 2023-03-27 22:20:42 +02:00
parent 0add2f5794
commit bdceb88fd0
4 changed files with 91 additions and 27 deletions

View File

@ -15,6 +15,13 @@ namespace JabyEngine {
struct JobArray { struct JobArray {
const CDFile* files = nullptr; const CDFile* files = nullptr;
size_t size = 0; size_t size = 0;
bool next() {
this->files += 1;
this->size -= 1;
return this->size > 0;
}
}; };
private: private:
@ -22,16 +29,27 @@ namespace JabyEngine {
CircularBuffer<CD_IO::DataSector> circular_buffer; CircularBuffer<CD_IO::DataSector> circular_buffer;
LZ4Decompressor lz4_decomp; LZ4Decompressor lz4_decomp;
JobArray jobs; JobArray jobs;
uint8_t* work_area = nullptr;
const AutoLBAEntry* lba = 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: public:
CDFileProcessor() = default; CDFileProcessor() = default;
void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area = reinterpret_cast<uint8_t*>(&__heap_base)); void setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint32_t* tmp_area = &__heap_base);
Progress process(); Progress process();
bool next() {
if(this->jobs.next()) {
CDFileProcessor::start_cur_job();
return true;
}
return false;
}
}; };
} }

View File

@ -44,6 +44,10 @@ namespace JabyEngine {
return SectorBufferAllocator(obj, function); return SectorBufferAllocator(obj, function);
} }
static constexpr SectorBufferAllocator invalid() {
return SectorBufferAllocator(nullptr, nullptr);
}
inline CD_IO::DataSector* allocate_sector() const { inline CD_IO::DataSector* allocate_sector() const {
return this->allocate(this->ctx); return this->allocate(this->ctx);
} }

View File

@ -62,7 +62,7 @@ namespace JabyEngine {
}; };
if(Interrupt::is_irq(Interrupt::CDROM)) { 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(); CD_IO::PortIndex1::change_to();
const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag); const auto cur_irq = CD_IO::Interrupt::get_type(CD_IO::PortIndex1::InterruptFlag);
@ -93,7 +93,8 @@ namespace JabyEngine {
current_state = State::Error; 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; return InterruptVerifierResult::ExecuteHandler;
} }

View File

@ -6,40 +6,83 @@ namespace JabyEngine {
void CDFileProcessor :: start_cur_job() { void CDFileProcessor :: start_cur_job() {
using CD::internal::FileInfo; using CD::internal::FileInfo;
using CD::internal::SectorBufferAllocator; 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<CDFileProcessor*>(ctx);
return self.circular_buffer.allocate();
};
static const auto direct_copy_callback = [](void* ctx) -> CD_IO::DataSector* {
auto** data_sector = reinterpret_cast<CD_IO::DataSector**>(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_job = *this->jobs.files;
const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; 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* { CD::internal::read_file(FileInfo::from(cur_lba), cfg);
CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(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.lba, cur_lba.size_words);
} }
void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) { void CDFileProcessor :: reading_state(const CDFile& file) {
this->lba = const_cast<const AutoLBAEntry*>(lba); switch(file.type) {
this->work_area = reinterpret_cast<uint8_t*>(this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(work_area), 5)); case CDFileType::SimpleTIM:
this->jobs = jobs; 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<const AutoLBAEntry*>(lba);
this->jobs = jobs;
// Setsup the circular buffer and determines where to place the temp area in
const_cast<uint32_t*&>(this->tmp_area) = reinterpret_cast<uint32_t*>(this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(tmp_area), 5));
CDFileProcessor::start_cur_job(); CDFileProcessor::start_cur_job();
} }
Progress CDFileProcessor :: process() { Progress CDFileProcessor :: process() {
const auto test_print = [this](){ const auto& cur_job = *this->jobs.files;
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()) { switch(CD::internal::read_current_state()) {
case CD::internal::State::Done: case CD::internal::State::Done:
// Need to start next job? // We are done now!
// Does the user trigger this? // The user decides if he wants the next value
test_print(); CDFileProcessor::done_state(cur_job);
return Progress::Done; return Progress::Done;
case CD::internal::State::BufferFull: case CD::internal::State::BufferFull:
@ -49,15 +92,13 @@ namespace JabyEngine {
case CD::internal::State::Reading: case CD::internal::State::Reading:
// Do we have data? Use it! // Do we have data? Use it!
test_print(); CDFileProcessor::reading_state(cur_job);
return Progress::InProgress; return Progress::InProgress;
case CD::internal::State::Error: case CD::internal::State::Error:
default:
// Error for real! // Error for real!
test_print();
return Progress::Error; return Progress::Error;
} }
return Progress::Error;
} }
} }