Support Overlays #2
|
@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
pub struct BitRange {
|
||||
jaby marked this conversation as resolved
Outdated
|
||||
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 mod layout;
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
is this same bits structure structure repeated between multiple projects in the same repo? if so is it important that they stay exactly in sync? It may be a candidate to lift to a support library.
You were right, there was actually already a similiar Rusts struct in a helper lib. I'm pushing the changes in a bit