Prepare new LBA representation

This commit is contained in:
jaby 2023-04-12 21:59:36 +02:00
parent 1a0d175779
commit 320fa8934c
8 changed files with 114 additions and 50 deletions

View File

@ -1,6 +1,6 @@
#ifndef __JABYENGINE_AUTO_LBA_HPP__
#define __JABYENGINE_AUTO_LBA_HPP__
#include "../../stdint.h"
#include "../Auxiliary/bits.hpp"
namespace JabyEngine {
#define __jabyengine_start_lba_request
@ -8,8 +8,36 @@ namespace JabyEngine {
#define __jabyengine_end_lba_request EndOfRequest
struct __attribute__((packed)) AutoLBAEntry {
uint16_t lba;
uint16_t size_words;
// This layout should make it a bit easier to read the "BitRange" values
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);
}
void read_file(FileInfo file_info, const SectorBufferAllocator& buffer_allocator);
void read_file(AutoLBAEntry file_info, const SectorBufferAllocator& buffer_allocator);
void continue_reading();
}
}

View File

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

View File

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

View File

@ -7,7 +7,6 @@ namespace JabyEngine {
static constexpr auto DisabledCircularBufferSize = 512;
void CDFileProcessor :: start_cur_job() {
using CD::internal::FileInfo;
using CD::internal::SectorBufferAllocator;
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* {
@ -47,13 +46,13 @@ namespace JabyEngine {
const auto& cur_lba = this->lba[cur_job.rel_lba_idx];
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* {
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.get_lba(), cur_lba.get_size_in_sectors());
}
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 mod layout;
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 std::path::PathBuf;
use no_comment::{IntoWithoutComments as _, languages};
@ -8,32 +8,39 @@ pub type LBANameVec = Vec<String>;
mod main;
/*
Size in sectors [22, 31];
Is LZ4 compressed [19];
LBA value [0, 18]
*/
#[repr(packed)]
struct LBAEntry {
lba: u16,
size_words: u16,
raw: u32,
}
impl LBAEntry {
pub fn write_entry(&mut self, lba: u16, mut size_bytes: usize) -> Result<(), Error> {
const WORD_SIZE:usize = std::mem::size_of::<u32>();
const SIZE_IN_SECTOR_RANGE:BitRange = BitRange::from_to(22, 31);
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?"));
}
size_bytes = (size_bytes + (WORD_SIZE - 1))/WORD_SIZE;
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);
self.raw = Self::SIZE_IN_SECTOR_RANGE.or_value(Self::LBA_VALUE_RANGE.or_value(0, lba), size_in_sectors) as u32;
Ok(())
}
}
@ -71,13 +78,13 @@ pub fn update_content_for_main(content: &mut Vec<u8>, lba_names: &LBANameVec, fi
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;
for lba_name in lba_names {
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);
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;
}