use std; use rustv::isa; use rustv::memory::SharedMemory; use rustv::register_file::RegisterFile; use rustv::syscall; use rustv::trap::Trap; pub struct SyscallHandler<'a> { memory: SharedMemory<'a>, } impl<'a> SyscallHandler<'a> { pub fn new(memory: SharedMemory<'a>) -> SyscallHandler<'a> { SyscallHandler { memory: memory } } } impl<'a> SyscallHandler<'a> { fn print(&mut self, registers: &mut RegisterFile) -> Option { let mut base = registers.read_word(isa::Register::X11); let mut string = vec![]; loop { let c = self.memory.borrow_mut().read_byte(base); if let Ok(0x00) = c { break; } else if let Ok(c) = c { string.push(c); } base += 1; } let result = std::str::from_utf8(&string); if let Ok(string) = result { println!("{}", string); } else { println!("Error printing string: not valid UTF-8: {:?}", result); } None } } impl<'a> syscall::SyscallHandler for SyscallHandler<'a> { // TODO: is trap really appropriate here? fn syscall(&mut self, registers: &mut RegisterFile) -> Option { let syscall_number = registers.read_word(isa::Register::X10); match syscall_number { 22 => { self.print(registers) } _ => { // TODO: some sort of error reporting None } } } }