Prepare new LBA representation

This commit is contained in:
Jaby 2023-04-12 21:59:36 +02:00
parent 12e1b54ce9
commit a2c7af2e12
8 changed files with 114 additions and 50 deletions

View File

@ -1,6 +1,6 @@
#ifndef __JABYENGINE_AUTO_LBA_HPP__ #ifndef __JABYENGINE_AUTO_LBA_HPP__
#define __JABYENGINE_AUTO_LBA_HPP__ #define __JABYENGINE_AUTO_LBA_HPP__
#include "../../stdint.h" #include "../Auxiliary/bits.hpp"
namespace JabyEngine { namespace JabyEngine {
#define __jabyengine_start_lba_request #define __jabyengine_start_lba_request
@ -8,8 +8,36 @@ namespace JabyEngine {
#define __jabyengine_end_lba_request EndOfRequest #define __jabyengine_end_lba_request EndOfRequest
struct __attribute__((packed)) AutoLBAEntry { struct __attribute__((packed)) AutoLBAEntry {
uint16_t lba; // This layout should make it a bit easier to read the "BitRange" values
uint16_t size_words; static constexpr auto SizeInSectors = BitRange::from_to(22, 31);
static constexpr auto IsLZ4Compressed = Bit(19);
static constexpr auto LBAValue = BitRange::from_to(0, 18);
uint32_t value;
constexpr uint32_t get_lba() const {
return bit::value::get_normalized(this->value, AutoLBAEntry::LBAValue);
}
constexpr uint32_t get_lba() const volatile {
return const_cast<const AutoLBAEntry*>(this)->get_lba();
}
constexpr uint32_t get_size_in_sectors() const {
return this->value >> SizeInSectors.pos;
}
constexpr uint32_t get_size_in_sectors() const volatile {
return const_cast<const AutoLBAEntry*>(this)->get_size_in_sectors();
}
constexpr bool isLZ4() const {
return bit::is_set(this->value, AutoLBAEntry::IsLZ4Compressed);
}
constexpr bool isLZ4() const volatile {
return const_cast<const AutoLBAEntry*>(this)->isLZ4();
}
}; };
} }

View File

@ -44,7 +44,7 @@ namespace JabyEngine {
return const_cast<volatile State&>(current_state); return const_cast<volatile State&>(current_state);
} }
void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator); void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator);
void continue_reading(); void continue_reading();
} }
} }

View File

@ -17,15 +17,6 @@ namespace JabyEngine {
Error, Error,
}; };
struct FileInfo {
uint16_t lba;
uint16_t sectors;
static constexpr FileInfo from(const AutoLBAEntry& entry) {
return FileInfo{entry.lba, CD_IO::DataSector::words_to_sectors(entry.size_words)};
}
};
class SectorBufferAllocator { class SectorBufferAllocator {
private: private:
typedef CD_IO::DataSector* (*AllocatorFunction)(void* ctx); typedef CD_IO::DataSector* (*AllocatorFunction)(void* ctx);
@ -61,17 +52,13 @@ namespace JabyEngine {
uint8_t sec; uint8_t sec;
uint8_t sector; uint8_t sector;
static constexpr CDTimeStamp from(uint16_t lba) { static constexpr CDTimeStamp from(uint32_t lba) {
const auto [min, new_lba] = div_and_mod(lba, static_cast<uint16_t>(MaxSector*MaxSeconds)); const auto [min, new_lba] = div_and_mod(lba, MaxSector*MaxSeconds);
const auto [sec, sectors] = div_and_mod(new_lba, static_cast<uint16_t>(MaxSector)); const auto [sec, sectors] = div_and_mod(new_lba, MaxSector);
return CDTimeStamp{static_cast<uint8_t>(min), static_cast<uint8_t>(sec), static_cast<uint8_t>(sectors)}; return CDTimeStamp{static_cast<uint8_t>(min), static_cast<uint8_t>(sec), static_cast<uint8_t>(sectors)};
} }
static constexpr CDTimeStamp from(const FileInfo& file_info) {
return CDTimeStamp::from(file_info.lba);
}
constexpr uint8_t get_min_cd() const { constexpr uint8_t get_min_cd() const {
return to_bcd(this->min); return to_bcd(this->min);
} }

View File

@ -12,8 +12,8 @@ namespace JabyEngine {
static void interrupt_handler(uint32_t); static void interrupt_handler(uint32_t);
static SectorBufferAllocator sector_allocator; static SectorBufferAllocator sector_allocator;
static uint16_t cur_lba; static uint32_t cur_lba;
static uint16_t dst_lba; static uint32_t dst_lba;
CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None; CD_IO::Interrupt::Type last_interrupt = CD_IO::Interrupt::Type::None;
uint8_t cmd_interrupt_bit = 0; uint8_t cmd_interrupt_bit = 0;
@ -30,7 +30,7 @@ namespace JabyEngine {
} }
// Requires Index0 // Requires Index0
static void read_cd(uint16_t lba) { static void read_cd(uint32_t lba) {
const auto loc = CDTimeStamp::from(lba); const auto loc = CDTimeStamp::from(lba);
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());
@ -117,16 +117,16 @@ namespace JabyEngine {
__syscall_ReturnFromException(); __syscall_ReturnFromException();
} }
void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator) { void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator) {
cur_lba = file_info.lba; cur_lba = file_info.get_lba();
dst_lba = file_info.lba + file_info.sectors; dst_lba = cur_lba + file_info.get_size_in_sectors();
sector_allocator = buffer_allocator; sector_allocator = buffer_allocator;
Command::wait_completed(); Command::wait_completed();
CD_IO::PortIndex0::change_to(); CD_IO::PortIndex0::change_to();
Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode); Command::send_wait<CD_IO::PortIndex0>(CD_IO::Command::SetMode, DataSectorMode);
read_cd(file_info.lba); read_cd(cur_lba);
} }
void continue_reading() { void continue_reading() {

View File

@ -7,7 +7,6 @@ namespace JabyEngine {
static constexpr auto DisabledCircularBufferSize = 512; static constexpr auto DisabledCircularBufferSize = 512;
void CDFileProcessor :: start_cur_job() { void CDFileProcessor :: start_cur_job() {
using CD::internal::FileInfo;
using CD::internal::SectorBufferAllocator; using CD::internal::SectorBufferAllocator;
const auto configurate_for = [this](const CDFile& file) { const auto configurate_for = [this](const CDFile& file) {
const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* { const auto disable_lz4 = [this](uint32_t* work_area, size_t size, uint32_t* overwrite_dst = nullptr) -> uint32_t* {
@ -47,13 +46,13 @@ namespace JabyEngine {
const auto& cur_lba = this->lba[cur_job.rel_lba_idx]; const auto& cur_lba = this->lba[cur_job.rel_lba_idx];
configurate_for(cur_job); configurate_for(cur_job);
CD::internal::read_file(FileInfo::from(cur_lba), SectorBufferAllocator::create(this, CD::internal::read_file(cur_lba, SectorBufferAllocator::create(this,
[](void* ctx) -> CD_IO::DataSector* { [](void* ctx) -> CD_IO::DataSector* {
CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(ctx); CDFileProcessor &self = *reinterpret_cast<CDFileProcessor*>(ctx);
return self.circular_buffer.allocate(); 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.get_lba(), cur_lba.get_size_in_sectors());
} }
bool CDFileProcessor :: process_data() { bool CDFileProcessor :: process_data() {

View File

@ -0,0 +1,42 @@
pub struct BitRange {
start: usize,
length: usize
}
impl BitRange {
pub const fn from_to(start_bit: usize, end_bit: usize) -> Self {
Self{start: start_bit, length: (end_bit - start_bit) + 1}
}
pub const fn get_mask(&self) -> usize {
self.max_value()
}
pub const fn max_value(&self) -> usize {
(1 << self.length) - 1
}
pub const fn or_value(&self, dst_value: usize, value: usize) -> usize {
dst_value | ((value & self.get_mask()) << self.start)
}
}
pub struct Bit {
pos: usize
}
impl Bit {
pub const fn at(pos: usize) -> Self {
Bit{pos}
}
pub const fn or_value(&self, dst_value: usize, is_set: bool) -> usize {
if is_set {
dst_value | (1 << self.pos)
}
else {
dst_value
}
}
}

View File

@ -1,3 +1,4 @@
pub mod bits;
pub (super) mod helper; pub (super) mod helper;
pub mod layout; pub mod layout;
pub mod file_map; pub mod file_map;

View File

@ -1,4 +1,4 @@
use super::{layout::Layout, File, FileSystemMap}; use super::{bits::{Bit, BitRange}, layout::Layout, File, FileSystemMap};
use super::super::encoder::LengthCalculatorFunction; use super::super::encoder::LengthCalculatorFunction;
use std::path::PathBuf; use std::path::PathBuf;
use no_comment::{IntoWithoutComments as _, languages}; use no_comment::{IntoWithoutComments as _, languages};
@ -8,32 +8,39 @@ pub type LBANameVec = Vec<String>;
mod main; mod main;
/*
Size in sectors [22, 31];
Is LZ4 compressed [19];
LBA value [0, 18]
*/
#[repr(packed)] #[repr(packed)]
struct LBAEntry { struct LBAEntry {
lba: u16, raw: u32,
size_words: u16,
} }
impl LBAEntry { impl LBAEntry {
pub fn write_entry(&mut self, lba: u16, mut size_bytes: usize) -> Result<(), Error> { const SIZE_IN_SECTOR_RANGE:BitRange = BitRange::from_to(22, 31);
const WORD_SIZE:usize = std::mem::size_of::<u32>(); const _IS_LZ4_COMPRESSED:Bit = Bit::at(19);
const LBA_VALUE_RANGE:BitRange = BitRange::from_to(0, 18);
if self.lba != 0 || self.size_words != 0 { pub fn write_entry(&mut self, lba: usize, size_bytes: usize) -> Result<(), Error> {
if lba > Self::LBA_VALUE_RANGE.max_value() {
return Err(Error::from_text(format!("LBA of value {} is impossible and can not be encoded! Maximum LBA value is: {}", lba, Self::LBA_VALUE_RANGE.max_value())));
}
let size_in_sectors = cdtypes::types::helper::sector_count_mode2_form1(size_bytes);
if size_in_sectors > Self::SIZE_IN_SECTOR_RANGE.max_value() {
return Err(Error::from_text(format!("{} sectors can not be encoded into 10bit", size_in_sectors)));
}
let lba = usize::from_ne_bytes(lba.to_le_bytes());
let size_in_sectors = usize::from_ne_bytes(size_in_sectors.to_le_bytes());
if self.raw != 0 {
return Err(Error::from_str("LBA Entry will overwrite non-zero value!\nIs no space allocated for the LBA Entries?")); return Err(Error::from_str("LBA Entry will overwrite non-zero value!\nIs no space allocated for the LBA Entries?"));
} }
size_bytes = (size_bytes + (WORD_SIZE - 1))/WORD_SIZE; self.raw = Self::SIZE_IN_SECTOR_RANGE.or_value(Self::LBA_VALUE_RANGE.or_value(0, lba), size_in_sectors) as u32;
if (size_bytes as u16) as usize != size_bytes {
return Err(Error::from_text(format!("{} words can not be encoded into 16bit", size_bytes)));
}
let lba = lba.to_le_bytes();
let size_bytes = (size_bytes as u16).to_le_bytes();
self.lba = u16::from_ne_bytes(lba);
self.size_words = u16::from_ne_bytes(size_bytes);
Ok(()) Ok(())
} }
} }
@ -71,13 +78,13 @@ pub fn update_content_for_main(content: &mut Vec<u8>, lba_names: &LBANameVec, fi
Ok(content.clone()) Ok(content.clone())
} }
fn for_each_lba_name<F: FnMut(usize, (u16, usize)) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> { fn for_each_lba_name<F: FnMut(usize, (usize, usize)) -> Result<(), Error>>(lba_names: &LBANameVec, file_map: &FileSystemMap, length_func: LengthCalculatorFunction, mut functor: F) -> Result<(), Error> {
let mut idx = 0; let mut idx = 0;
for lba_name in lba_names { for lba_name in lba_names {
if let Some(file) = file_map.get(lba_name) { if let Some(file) = file_map.get(lba_name) {
let (lba, bytes) = (format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes); let (lba, bytes) = (format_if_error_drop_cause!(file.try_borrow(), "Failed accessing file \"{}\" for writing LBA information.\nNote: You can not inject the LBA information of a file into itself.", lba_name)?.get_absolute_lba(), length_func(&Layout::File(file.clone())).bytes);
functor(idx, (lba as u16, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?; functor(idx, (lba, bytes.ok_or(Error::from_text(format!("{} does not contain a size!", lba_name)))?))?;
idx += 1; idx += 1;
} }