Compare commits
4 Commits
21234a882d
...
39dae2aa6b
| Author | SHA1 | Date | |
|---|---|---|---|
| 39dae2aa6b | |||
| 142f3eb468 | |||
| 0eb67c0e10 | |||
| 4ff00404d4 |
@ -48,6 +48,25 @@ _start:
|
|||||||
mov r0, 0
|
mov r0, 0
|
||||||
mov [counter], r0
|
mov [counter], r0
|
||||||
|
|
||||||
|
mov r1, 0
|
||||||
|
.loop_body:
|
||||||
|
mov r2, r1
|
||||||
|
add r2, 32
|
||||||
|
|
||||||
|
add rsp, 4
|
||||||
|
mov [rsp-4], r1
|
||||||
|
mov [rsp-2], r2
|
||||||
|
call term_putc
|
||||||
|
mov r1, [rsp-4]
|
||||||
|
sub rsp, 4
|
||||||
|
|
||||||
|
add r1, 1
|
||||||
|
.loop_cond:
|
||||||
|
cmp r1, 127 - 32
|
||||||
|
mov r0, rfl
|
||||||
|
and r0, fl_lt
|
||||||
|
jnz r0, .loop_body
|
||||||
|
|
||||||
main_loop:
|
main_loop:
|
||||||
hlt
|
hlt
|
||||||
jmp main_loop
|
jmp main_loop
|
||||||
@ -76,7 +95,7 @@ key_press_int:
|
|||||||
and r2, fl_eq
|
and r2, fl_eq
|
||||||
jnz r2, .print_dot
|
jnz r2, .print_dot
|
||||||
|
|
||||||
add r1, 61 ; scancode letter -> ascii
|
add r1, 93 ; scancode letter -> ascii
|
||||||
mov [rsp], r1
|
mov [rsp], r1
|
||||||
add rsp, 2
|
add rsp, 2
|
||||||
call term_putc
|
call term_putc
|
||||||
|
|||||||
75
src/fs.cpp
Normal file
75
src/fs.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "fs.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace vc5::filesys {
|
||||||
|
|
||||||
|
constexpr auto Ok = Status::Ok;
|
||||||
|
|
||||||
|
using BlockData = std::array<uint8_t, block_size>;
|
||||||
|
|
||||||
|
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<uint16_t>(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<SuperBlockData*>(&block[0]);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status Fs::write_superblock()
|
||||||
|
{
|
||||||
|
m_disk->write(
|
||||||
|
reinterpret_cast<const uint8_t*>(&m_super), super_block_location);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
73
src/fs.hpp
Normal file
73
src/fs.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "block_device.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
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<uint8_t, name_max_len> 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<uint16_t, inode_blocks_count> 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<uint16_t, sb_block_bitmap_count> block_bitmap;
|
||||||
|
std::array<uint16_t, sb_inode_bitmap_count> inode_bitmap;
|
||||||
|
std::array<uint16_t, sb_inode_blocks_count> 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,6 +20,21 @@ constexpr uint64_t char_data(uint8_t ch)
|
|||||||
switch (ch) {
|
switch (ch) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
case ' ': return 0x0000000000000000;
|
case ' ': return 0x0000000000000000;
|
||||||
|
case '!': return 0x0018181818001818;
|
||||||
|
case '"': return 0x0066660000000000;
|
||||||
|
case '#': return 0x00247e24247e2400;
|
||||||
|
case '$': return 0x00187e6218467e18;
|
||||||
|
case '%': return 0x0022562c18346a44;
|
||||||
|
case '&': return 0x00784c38724a4638;
|
||||||
|
case '\'': return 0x0018181800000000;
|
||||||
|
case '(': return 0x000c18303030180c;
|
||||||
|
case ')': return 0x0030180c0c0c1830;
|
||||||
|
case '*': return 0x0000241818240000;
|
||||||
|
case '+': return 0x000018187e7e1818;
|
||||||
|
case ',': return 0x0000000000181830;
|
||||||
|
case '-': return 0x000000007e7e0000;
|
||||||
|
case '.': return 0x0000000000181800;
|
||||||
|
case '/': return 0x0002060c18306040;
|
||||||
|
|
||||||
case '0': return 0x003C666E7666663C;
|
case '0': return 0x003C666E7666663C;
|
||||||
case '1': return 0x001838181818183C;
|
case '1': return 0x001838181818183C;
|
||||||
@ -32,6 +47,14 @@ constexpr uint64_t char_data(uint8_t ch)
|
|||||||
case '8': return 0x003C66663C66663C;
|
case '8': return 0x003C66663C66663C;
|
||||||
case '9': return 0x003C66663E06663C;
|
case '9': return 0x003C66663E06663C;
|
||||||
|
|
||||||
|
case ':': return 0x0018180000181800;
|
||||||
|
case ';': return 0x0000181800181830;
|
||||||
|
case '<': return 0x00060c1830180c06;
|
||||||
|
case '=': return 0x00007e7e007e7e00;
|
||||||
|
case '>': return 0x006030180c183060;
|
||||||
|
case '?': return 0x003e660c18001818;
|
||||||
|
case '@': return 0x003c664a564e603c;
|
||||||
|
|
||||||
case 'A': return 0x00187E66667E6666;
|
case 'A': return 0x00187E66667E6666;
|
||||||
case 'B': return 0x00787E667C667E7C;
|
case 'B': return 0x00787E667C667E7C;
|
||||||
case 'C': return 0x003C7E6060607E3C;
|
case 'C': return 0x003C7E6060607E3C;
|
||||||
@ -59,7 +82,42 @@ constexpr uint64_t char_data(uint8_t ch)
|
|||||||
case 'Y': return 0x0066663C18181818;
|
case 'Y': return 0x0066663C18181818;
|
||||||
case 'Z': return 0x007E7E0C18307E7E;
|
case 'Z': return 0x007E7E0C18307E7E;
|
||||||
|
|
||||||
case ':': return 0x0018180000181800;
|
case '[': return 0x003c30303030303c;
|
||||||
|
case '\\': return 0x00406030180c0602;
|
||||||
|
case ']': return 0x003c0c0c0c0c0c3c;
|
||||||
|
case '^': return 0x0010386c44000000;
|
||||||
|
case '_': return 0x00000000000000ff;
|
||||||
|
case '`': return 0x0030181800000000;
|
||||||
|
case 'a': return 0x0000003c023e423e;
|
||||||
|
case 'b': return 0x004040407c42427c;
|
||||||
|
case 'c': return 0x000000003c40403c;
|
||||||
|
case 'd': return 0x000202023e42423e;
|
||||||
|
case 'e': return 0x0000003c427c403c;
|
||||||
|
case 'f': return 0x00000c103c101010;
|
||||||
|
case 'g': return 0x003e645840784438;
|
||||||
|
case 'h': return 0x0020202038242424;
|
||||||
|
case 'i': return 0x0000181800181818;
|
||||||
|
case 'j': return 0x000606000606361c;
|
||||||
|
case 'k': return 0x0020202c3830382c;
|
||||||
|
case 'l': return 0x003010101010100c;
|
||||||
|
case 'm': return 0x000000203e2a2a2a;
|
||||||
|
case 'n': return 0x0000000038242424;
|
||||||
|
case 'o': return 0x0000000018242418;
|
||||||
|
case 'p': return 0x0000001c223c2020;
|
||||||
|
case 'q': return 0x00000018241c0404;
|
||||||
|
case 'r': return 0x0000002038242020;
|
||||||
|
case 's': return 0x0000003840380438;
|
||||||
|
case 't': return 0x0000103c1010100c;
|
||||||
|
case 'u': return 0x000000002424241e;
|
||||||
|
case 'v': return 0x0000002424243c18;
|
||||||
|
case 'w': return 0x0000000063222a3e;
|
||||||
|
case 'x': return 0x000000663c183c66;
|
||||||
|
case 'y': return 0x00000024241c0438;
|
||||||
|
case 'z': return 0x0000003e060c183e;
|
||||||
|
case '{': return 0x000c18183018180c;
|
||||||
|
case '|': return 0x1818181818181818;
|
||||||
|
case '}': return 0x003018180c181830;
|
||||||
|
case '~': return 0x0000307a5e0c0000;
|
||||||
|
|
||||||
default: return 0x55AA55AA55AA55AA;
|
default: return 0x55AA55AA55AA55AA;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|||||||
@ -195,6 +195,11 @@ struct InsReader {
|
|||||||
VM* vm;
|
VM* vm;
|
||||||
uint16_t ins;
|
uint16_t ins;
|
||||||
|
|
||||||
|
auto op() -> Op
|
||||||
|
{
|
||||||
|
return static_cast<Op>(ins & 0b11'1111);
|
||||||
|
}
|
||||||
|
|
||||||
auto to_u16() const -> uint16_t
|
auto to_u16() const -> uint16_t
|
||||||
{
|
{
|
||||||
return ins;
|
return ins;
|
||||||
@ -277,7 +282,8 @@ int VM::run_instruction()
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
auto ins = InsReader(*this);
|
auto ins = InsReader(*this);
|
||||||
auto op = static_cast<Op>(ins.to_u16() & 0b11'1111);
|
auto op = ins.op();
|
||||||
|
|
||||||
std::println(
|
std::println(
|
||||||
" [{: >3x}]: 0x{:04x} {: <6} {:04b} {:04b} {:04b} {:04b} {:04x}",
|
" [{: >3x}]: 0x{:04x} {: <6} {:04b} {:04b} {:04b} {:04b} {:04x}",
|
||||||
ip,
|
ip,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user