Prepare new LBA representation
This commit is contained in:
parent
12e1b54ce9
commit
a2c7af2e12
|
@ -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();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue