diff --git a/src/fs.cpp b/src/fs.cpp new file mode 100644 index 0000000..8911d28 --- /dev/null +++ b/src/fs.cpp @@ -0,0 +1,75 @@ +#include "fs.hpp" +#include + +namespace vc5::filesys { + +constexpr auto Ok = Status::Ok; + +using BlockData = std::array; + +void Fs::init() +{ + m_super = SuperBlockData { + .block_bitmap = {}, + .inode_bitmap = {}, + .inode_blocks = {}, + }; + write_superblock(); +} + +Status Fs::make_directory() +{ + uint16_t id; + if (auto result = next_inode_id(id); result != Ok) { + return result; + } + + auto node = INodeData { + .id = id, + .flags = static_cast(INodeType::Directory), + .blocks_count = 0, + .blocks = {}, + }; +} + +Status Fs::write_new_inode(INodeData& data) +{ + uint16_t block_id = data.id / inodes_per_block; + uint16_t offset = data.id % inodes_per_block * inode_size; + + BlockData block; + m_disk->read(&block[0], block_id); +} + +Status Fs::next_inode_id(uint16_t& id) +{ + for (uint16_t map_idx = 0; map_idx < sb_inode_bitmap_count; ++map_idx) { + auto& map = m_super.inode_bitmap[map_idx]; + + for (uint16_t bit_idx = 0; bit_idx < 16; ++bit_idx) { + + if ((map >> bit_idx & 1) == 0) { + id = map_idx * sb_inode_bitmap_count + bit_idx; + return Ok; + } + } + } + return Status::INodeAllocFail; +} + +Status Fs::read_superblock() +{ + BlockData block; + m_disk->read(&block[0], super_block_location); + m_super = *reinterpret_cast(&block[0]); + return Ok; +} + +Status Fs::write_superblock() +{ + m_disk->write( + reinterpret_cast(&m_super), super_block_location); + return Ok; +} + +} diff --git a/src/fs.hpp b/src/fs.hpp new file mode 100644 index 0000000..58d1df7 --- /dev/null +++ b/src/fs.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include "block_device.hpp" +#include +#include + +namespace vc5::filesys { + +enum class Status : uint16_t { + Ok, + INodeAllocFail, +}; + +constexpr uint16_t block_size = 0x200; +constexpr uint16_t name_max_len = 255; + +struct DirEntryData { + uint16_t inode; + uint16_t name_len; + std::array name; +}; + +enum class INodeType : uint16_t { + File = 0, + Directory = 1, + Symlink = 2, +}; + +constexpr uint16_t inode_size = 32; +constexpr uint16_t inodes_per_block = block_size / inode_size; +constexpr uint16_t inode_blocks_count = 8; + +struct INodeData { + uint16_t id; + uint16_t flags; + uint16_t blocks_count; + std::array blocks; +}; + +constexpr uint16_t super_block_location = 0x400; +constexpr uint16_t sb_block_bitmap_count = 8; +constexpr uint16_t sb_inode_bitmap_count = 8; +constexpr uint16_t sb_inode_blocks_count = 16; + +struct SuperBlockData { + std::array block_bitmap; + std::array inode_bitmap; + std::array inode_blocks; +}; + +class Fs { +public: + explicit Fs(BlockDevice& disk) + : m_disk(&disk) + { + } + + void init(); + +private: + Status make_directory(); + + Status write_new_inode(INodeData& data); + Status next_inode_id(uint16_t& id); + + Status read_superblock(); + Status write_superblock(); + + BlockDevice* m_disk; + SuperBlockData m_super; +}; + +} diff --git a/src/io_device.cpp b/src/io_device.cpp index fa149ea..e9d7bc8 100644 --- a/src/io_device.cpp +++ b/src/io_device.cpp @@ -26,7 +26,7 @@ constexpr uint64_t char_data(uint8_t ch) case '$': return 0x00187e6218467e18; case '%': return 0x0022562c18346a44; case '&': return 0x00784c38724a4638; - case '\'': return 0x0018180000000000; + case '\'': return 0x0018181800000000; case '(': return 0x000c18303030180c; case ')': return 0x0030180c0c0c1830; case '*': return 0x0000241818240000; @@ -91,7 +91,7 @@ constexpr uint64_t char_data(uint8_t ch) case 'a': return 0x0000003c023e423e; case 'b': return 0x004040407c42427c; case 'c': return 0x000000003c40403c; - case 'd': return 0x00020202023e423e; + case 'd': return 0x000202023e42423e; case 'e': return 0x0000003c427c403c; case 'f': return 0x00000c103c101010; case 'g': return 0x003e645840784438; diff --git a/src/vm.cpp b/src/vm.cpp index cbf7d90..755087d 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -195,6 +195,11 @@ struct InsReader { VM* vm; uint16_t ins; + auto op() -> Op + { + return static_cast(ins & 0b11'1111); + } + auto to_u16() const -> uint16_t { return ins; @@ -277,7 +282,8 @@ int VM::run_instruction() return -1; auto ins = InsReader(*this); - auto op = static_cast(ins.to_u16() & 0b11'1111); + auto op = ins.op(); + std::println( " [{: >3x}]: 0x{:04x} {: <6} {:04b} {:04b} {:04b} {:04b} {:04x}", ip,