Simulated load of a file

This commit is contained in:
Jaby 2023-03-03 14:33:29 +01:00 committed by Jaby
parent b18b326b75
commit c92b0d8a2e
7 changed files with 106 additions and 38 deletions

View File

@ -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() {

View File

@ -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<CD_IO::DataSector, 8> circular_buffer;
LZ4Decompressor lz4_decomp;
JobArray jobs;
uint8_t* work_area = nullptr;
const AutoLBAEntry* lba = nullptr;
void start_cur_job();

View File

@ -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<typename T>
static constexpr T words_to_sectors(T size) {
return (size + static_cast<T>(DataSector::SizeWords - 1))/static_cast<T>(DataSector::SizeWords);
}
};
enum Index {
Index0 = 0,
Index1 = 1,

View File

@ -1,16 +1,24 @@
#ifndef __JABYENGINE_CD_INTERNAL_HPP__
#define __JABYENGINE_CD_INTERNAL_HPP__
#include "cd_types.hpp"
#include <PSX/System/IOPorts/cd_io.hpp>
namespace JabyEngine {
namespace CD {
namespace internal {
extern VolatilePOD<CD_IO::Interrupt::Type> last_interrupt;
extern CD_IO::Interrupt::Type last_interrupt;
extern State current_state;
static CD_IO::Interrupt::Type read_last_interrupt() {
return const_cast<volatile CD_IO::Interrupt::Type&>(last_interrupt);
}
static State read_current_state() {
return const_cast<volatile State&>(current_state);
}
struct Command {
static void wait_until(CD_IO::Interrupt::Type irq) {
while(last_interrupt.read() != irq);
while(read_last_interrupt() != irq);
}
template<typename...ARGS>
@ -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);
}
}
}

View File

@ -2,6 +2,7 @@
#define __JABYENGINE_INTERNAL_CD_TYPES_HPP__
#include <PSX/AutoLBA/auto_lba.hpp>
#include <PSX/Auxiliary/math_helper.hpp>
#include <PSX/System/IOPorts/cd_io.hpp>
#include <stddef.h>
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<typename T>
static constexpr T words_to_sectors(T size) {
return (size + static_cast<T>(DataSector::SizeWords - 1))/static_cast<T>(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 {

View File

@ -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::PortIndex0>(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::PortIndex0>(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<char*>(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<CD_IO::Interrupt::Type> 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<InterruptHandler>(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::PortIndex0>(CD_IO::Command::SetLoc, loc.get_min_cd(), loc.get_sec_cd(), loc.get_sector_cd());
Command::send<CD_IO::PortIndex0>(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;
}
}
}

View File

@ -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<CDFileProcessor*>(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<const AutoLBAEntry*>(lba);
this->work_area = work_area;
this->work_area = (work_area + this->circular_buffer.setup(reinterpret_cast<CD_IO::DataSector*>(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;
}
}