aboutsummaryrefslogtreecommitdiff
path: root/src/system.rs
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2016-01-08 10:04:27 -0700
committerDavid Li <li.davidm96@gmail.com>2016-01-08 10:04:27 -0700
commitad805c698cd1c4d68d090f842fb14621c32ee8d6 (patch)
treefd357647c13c461370d34a067b84cc7aac94c7d3 /src/system.rs
parent940a5ae77a1efc8f89fe5b56fe4a4ae34a0e480d (diff)
Refactor into multiple files
Diffstat (limited to 'src/system.rs')
-rw-r--r--src/system.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/system.rs b/src/system.rs
new file mode 100644
index 0000000..faadb13
--- /dev/null
+++ b/src/system.rs
@@ -0,0 +1,67 @@
+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<Trap> {
+ 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<Trap> {
+ let syscall_number = registers.read_word(isa::Register::X10);
+
+ match syscall_number {
+ 22 => {
+ self.print(registers)
+ }
+
+ _ => {
+ // TODO: some sort of error reporting
+ None
+ }
+ }
+ }
+}