lifeblood_os/turntable/src/main.rs

203 lines
5.5 KiB
Rust
Raw Normal View History

2025-09-08 20:52:06 -07:00
#![no_std]
#![no_main]
use crate::terminal::{print, println};
use liblbos::fs::{DirectoryReader, FileSystem};
static TEST: &[u8] = b"test";
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
liblbos::syscalls::write_terminal(b"abort\n");
loop {}
}
fn lsdir() {
let mut fs = FileSystem::empty();
if liblbos::ktask::ktask_fsopen(&mut fs) != 0 {
println("failed to open fs");
return;
}
let mut dir = DirectoryReader::empty();
if liblbos::ktask::ktask_fsopendir(&fs, &mut dir, b"/") != 0 {
println("failed to open dir");
return;
}
let mut record = liblbos::fs::Record {
name: [0; 12],
record_type: 0,
target: 0,
total_size_bytes: 0,
};
while liblbos::ktask::ktask_fsreaddir(&fs, &mut dir, &mut record) == 0 {
print("\n");
if record.record_type == 0 {
println("unexpected eod");
break;
}
print(" - ");
liblbos::syscalls::write_terminal(
&record.name[..record.name.iter().position(|&x| x == 0).unwrap_or(11)],
);
if record.record_type == liblbos::fs::RecordType::Directory as u8 {
print(" (dir)");
} else {
print(" (file)");
}
}
print("\n");
}
fn attempt_run_file(name: &str) {
print("\n");
if name.len() > 11 {
println("filename too long");
return;
}
let mut fs = FileSystem::empty();
if liblbos::ktask::ktask_fsopen(&mut fs) != 0 {
println("failed to open fs");
return;
}
let mut dir = DirectoryReader::empty();
if liblbos::ktask::ktask_fsopendir(&fs, &mut dir, b"/") != 0 {
println("failed to open dir");
return;
}
let mut record = liblbos::fs::Record {
name: [0; 12],
record_type: 0,
target: 0,
total_size_bytes: 0,
};
fn namecmp(record: &liblbos::fs::Record, name: &[u8]) -> bool {
let record_name = &record.name[..record.name.iter().position(|&x| x == 0).unwrap_or(11)];
record_name == name
}
while !namecmp(&record, name.as_bytes()) {
if liblbos::ktask::ktask_fsreaddir(&fs, &mut dir, &mut record) != 0 {
println("file not found");
return;
}
if record.record_type == 0 {
println("unexpected eod");
return;
}
if record.record_type == liblbos::fs::RecordType::Directory as u8
&& namecmp(&record, name.as_bytes())
{
println("not a file");
return;
}
}
// found, load the file
let mut reader = liblbos::fs::FileReader::empty();
if liblbos::ktask::ktask_fsopenfile(&fs, &record, &mut reader) != 0 {
println("failed to open file");
return;
}
let size = record.total_size_bytes as usize;
let buf = liblbos::syscalls::alloc_blocks(size.div_ceil(512));
if liblbos::ktask::ktask_fsreadfile(&fs, &mut reader, unsafe { core::slice::from_raw_parts_mut(buf as *mut _, size) }) != 0 {
println("failed to read file");
}
let mut task_setup = liblbos::TaskSetup {
epc: 0,
ddi_first_addr: 0,
ddi_size: 0,
wait_for_task_exit: true,
};
if liblbos::ktask::ktask_loadddifile(buf, size, &mut task_setup as *mut _ as usize) != 0 {
println("failed to load ddi");
liblbos::syscalls::free_blocks(buf, size.div_ceil(512));
return;
}
liblbos::syscalls::free_blocks(buf, size.div_ceil(512));
let task_id = liblbos::syscalls::create_task(task_setup);
println("\ntask exited\n");
}
fn execute(cmd: &str) {
print("\n");
let mut split = cmd.split_ascii_whitespace();
if let Some(cmd) = split.next() {
match cmd {
"ls" => {
lsdir();
}
_ => {
attempt_run_file(cmd);
}
}
}
}
fn hex(mut n: u8) -> [u8; 2] {
let mut buf = [0u8; 2];
for i in (0..2).rev() {
let num = n & 0b1111;
n >>= 4;
if num < 10 {
buf[i] = b'0' + num;
} else {
buf[i] = b'a' + (num - 10);
}
}
buf
}
mod arch;
mod terminal;
#[unsafe(no_mangle)]
extern "C" fn main() {
print("\n\n");
print("turntable v");
const VERSION: &str = env!("CARGO_PKG_VERSION");
print(VERSION);
print("\n");
println("(c) 2025 Real Microsoft, LLC");
print("> ");
let mut cmdbuf = [0u8; 256];
let mut cmdbuf_len = 0;
let mut inbuf = [0u8; 8];
loop {
let read = liblbos::syscalls::read_inbuf(&mut inbuf);
if read > 0 {
for c in &inbuf[0..read] {
if cmdbuf_len >= cmdbuf.len() {
print("\x07");
} else {
// backspace
if *c == 0x7f && cmdbuf_len > 0 {
cmdbuf_len -= 1;
print("\x08 \x08");
} else {
cmdbuf[cmdbuf_len] = *c;
cmdbuf_len += 1;
if *c == b'\r' {
execute(unsafe {
core::str::from_utf8_unchecked(&cmdbuf[0..cmdbuf_len - 1])
});
cmdbuf_len = 0;
print("> ");
break;
} else {
liblbos::syscalls::write_terminal(&[*c]);
}
}
}
}
}
}
}