Simulated load of a file
This commit is contained in:
parent
c7923c245c
commit
45371bc2f0
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue