Simulated load of a file

This commit is contained in:
Björn Gaier 2023-03-03 14:33:29 +01:00
parent e80922ed64
commit d593dd97d1
7 changed files with 106 additions and 38 deletions

View File

@ -17,10 +17,12 @@ namespace JabyEngine {
public: public:
FastCircularBuffer() = default; FastCircularBuffer() = default;
void setup(T* buffer_start_adr) { size_t setup(T* buffer_start_adr) {
this->start_adr = buffer_start_adr; this->start_adr = buffer_start_adr;
this->read_idx = 0; this->read_idx = 0;
this->write_idx = 0; this->write_idx = 0;
return (sizeof(T)*ElementCount);
} }
T* allocate() { T* allocate() {

View File

@ -1,7 +1,9 @@
#ifndef __JABYENGINE_CD_FILE_PROCESSOR_HPP__ #ifndef __JABYENGINE_CD_FILE_PROCESSOR_HPP__
#define __JABYENGINE_CD_FILE_PROCESSOR_HPP__ #define __JABYENGINE_CD_FILE_PROCESSOR_HPP__
#include "../../AutoLBA/auto_lba.hpp" #include "../../AutoLBA/auto_lba.hpp"
#include "../../Auxiliary/circular_buffer.hpp"
#include "../../Auxiliary/lz4_decompressor.hpp" #include "../../Auxiliary/lz4_decompressor.hpp"
#include "../../System/IOPorts/cd_io.hpp"
#include "../cd_file_types.hpp" #include "../cd_file_types.hpp"
#include "file_processor.hpp" #include "file_processor.hpp"
@ -16,11 +18,12 @@ namespace JabyEngine {
}; };
private: private:
FileProcessor::State file_pro_state; FileProcessor::State file_pro_state;
LZ4Decompressor lz4_decomp; FastCircularBuffer<CD_IO::DataSector, 8> circular_buffer;
JobArray jobs; LZ4Decompressor lz4_decomp;
uint8_t* work_area = nullptr; JobArray jobs;
const AutoLBAEntry* lba = nullptr; uint8_t* work_area = nullptr;
const AutoLBAEntry* lba = nullptr;
void start_cur_job(); void start_cur_job();

View File

@ -4,6 +4,18 @@
namespace JabyEngine { namespace JabyEngine {
namespace CD_IO { 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 { enum Index {
Index0 = 0, Index0 = 0,
Index1 = 1, Index1 = 1,

View File

@ -1,16 +1,24 @@
#ifndef __JABYENGINE_CD_INTERNAL_HPP__ #ifndef __JABYENGINE_CD_INTERNAL_HPP__
#define __JABYENGINE_CD_INTERNAL_HPP__ #define __JABYENGINE_CD_INTERNAL_HPP__
#include "cd_types.hpp" #include "cd_types.hpp"
#include <PSX/System/IOPorts/cd_io.hpp>
namespace JabyEngine { namespace JabyEngine {
namespace CD { namespace CD {
namespace internal { 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 { struct Command {
static void wait_until(CD_IO::Interrupt::Type irq) { static void wait_until(CD_IO::Interrupt::Type irq) {
while(last_interrupt.read() != irq); while(read_last_interrupt() != irq);
} }
template<typename...ARGS> 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__ #define __JABYENGINE_INTERNAL_CD_TYPES_HPP__
#include <PSX/AutoLBA/auto_lba.hpp> #include <PSX/AutoLBA/auto_lba.hpp>
#include <PSX/Auxiliary/math_helper.hpp> #include <PSX/Auxiliary/math_helper.hpp>
#include <PSX/System/IOPorts/cd_io.hpp>
#include <stddef.h> #include <stddef.h>
namespace JabyEngine { namespace JabyEngine {
@ -16,30 +17,18 @@ namespace JabyEngine {
Error, 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 { struct FileInfo {
uint16_t lba; uint16_t lba;
uint16_t sectors; uint16_t sectors;
static constexpr FileInfo from(const AutoLBAEntry& entry) { 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 { class SectorBufferAllocator {
private: private:
typedef DataSector* (*AllocatorFunction)(void* ctx); typedef CD_IO::DataSector* (*AllocatorFunction)(void* ctx);
private: private:
void* ctx = nullptr; void* ctx = nullptr;
@ -54,6 +43,10 @@ namespace JabyEngine {
static constexpr SectorBufferAllocator create(void* obj, AllocatorFunction function) { static constexpr SectorBufferAllocator create(void* obj, AllocatorFunction function) {
return SectorBufferAllocator(obj, function); return SectorBufferAllocator(obj, function);
} }
inline CD_IO::DataSector* allocate_sector() const {
return this->allocate(this->ctx);
}
}; };
struct CDTimeStamp { struct CDTimeStamp {

View File

@ -25,20 +25,46 @@ namespace JabyEngine {
static uint16_t sectors_left; static uint16_t sectors_left;
static InterruptVerifierResult interrupt_verifier() { 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)) { if(Interrupt::is_irq(Interrupt::CDROM)) {
const uint8_t old_idx = (CD_IO::IndexStatus.read() & 0x3); const uint8_t old_idx = (CD_IO::IndexStatus.read() & 0x3);
CD_IO::PortIndex1::change_to(); 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::InterruptFlagRegister);
last_interrupt.write(cur_irq); last_interrupt = cur_irq;
CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlagRegister); CD_IO::Interrupt::ack(CD_IO::PortIndex1::InterruptFlagRegister);
if(cur_irq == CD_IO::Interrupt::DataReady) { if(cur_irq == CD_IO::Interrupt::DataReady) {
sectors_left--; //Obtain sector content here
if(sectors_left == 0) { auto* sector = sector_allocator.allocate_sector();
CD_IO::PortIndex0::change_to(); if(sector) {
Command::send<CD_IO::PortIndex0>(CD_IO::Command::Pause); //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}); CD_IO::IndexStatus.write({old_idx});
@ -55,14 +81,15 @@ namespace JabyEngine {
__syscall_ReturnFromException(); __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 = { InterrupCallback callback = {
.next = nullptr, .next = nullptr,
.handler_function = reinterpret_cast<InterruptHandler>(interrupt_handler), .handler_function = reinterpret_cast<InterruptHandler>(interrupt_handler),
.verifier_function = interrupt_verifier .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; sector_allocator = buffer_allocator;
sectors_left = file_info.sectors; 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_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); Command::send<CD_IO::PortIndex0>(CD_IO::Command::ReadN);
current_state = State::Reading;
printf("Now reading: %i\n", file_info.lba); 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::FileInfo;
using CD::internal::SectorBufferAllocator; 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* { CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, [](void* ctx) -> CD_IO::DataSector* {
printf("Blubb?!\n"); CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(ctx);
return nullptr;
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);
@ -19,13 +21,34 @@ namespace JabyEngine {
void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) { void CDFileProcessor :: setup(const volatile AutoLBAEntry* lba, JobArray jobs, uint8_t* work_area) {
this->lba = const_cast<const AutoLBAEntry*>(lba); 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; this->jobs = jobs;
CDFileProcessor::start_cur_job(); CDFileProcessor::start_cur_job();
} }
Progress CDFileProcessor :: process() { 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; return Progress::Error;
} }
} }