Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 0 additions & 44 deletions cli/src/dummy_terminal.rs

This file was deleted.

16 changes: 8 additions & 8 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ extern crate getopts;
extern crate riscv_emu_rust;

mod popup_terminal;
mod dummy_terminal;
mod raw_terminal;

use riscv_emu_rust::Emulator;
use riscv_emu_rust::cpu::Xlen;
use riscv_emu_rust::terminal::Terminal;
use popup_terminal::PopupTerminal;
use dummy_terminal::DummyTerminal;
use raw_terminal::RawTerminal;

use std::env;
use std::fs::File;
Expand All @@ -18,7 +18,7 @@ use getopts::Options;

enum TerminalType {
PopupTerminal,
DummyTerminal
RawTerminal,
}

fn print_usage(program: &str, opts: Options) {
Expand All @@ -29,7 +29,7 @@ fn print_usage(program: &str, opts: Options) {
fn get_terminal(terminal_type: TerminalType) -> Box<dyn Terminal> {
match terminal_type {
TerminalType::PopupTerminal => Box::new(PopupTerminal::new()),
TerminalType::DummyTerminal => Box::new(DummyTerminal::new()),
TerminalType::RawTerminal => Box::new(RawTerminal::new()),
}
}

Expand All @@ -41,7 +41,7 @@ fn main () -> std::io::Result<()> {
opts.optopt("x", "xlen", "Set bit mode. Default is auto detect from elf file", "32|64");
opts.optopt("f", "fs", "File system image file", "xv6/fs.img");
opts.optopt("d", "dtb", "Device tree file", "linux/dtb");
opts.optflag("n", "no_terminal", "No popup terminal");
opts.optflag("r", "raw_terminal", "Use a raw terminal");
opts.optflag("h", "help", "Show this help menu");
opts.optflag("p", "page_cache", "Enable experimental page cache optimization");

Expand Down Expand Up @@ -93,10 +93,10 @@ fn main () -> std::io::Result<()> {
let mut elf_contents = vec![];
elf_file.read_to_end(&mut elf_contents)?;

let terminal_type = match matches.opt_present("n") {
let terminal_type = match matches.opt_present("r") {
true => {
println!("No popup terminal mode. Output will be flushed on your terminal but you can not input.");
TerminalType::DummyTerminal
println!("Raw terminal mode.");
TerminalType::RawTerminal
},
false => TerminalType::PopupTerminal
};
Expand Down
66 changes: 66 additions & 0 deletions cli/src/raw_terminal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::str;
use std::io::{stdin, stdout, Read, Write};
use std::sync::mpsc;
use std::sync::mpsc::Receiver;
use std::thread;

use riscv_emu_rust::terminal::Terminal;

/// Raw `Terminal`. Output will be displayed in command line
/// and input will be read character-by-character from stdin
/// in a separate thread.
pub struct RawTerminal {
rx_input: Receiver<u8>,
}

impl RawTerminal {
pub fn new() -> Self {
let (tx_input, rx_input) = mpsc::channel::<u8>();
thread::spawn(move || loop {
let mut buf = [0; 1];
if let Ok(n) = stdin().read(&mut buf) {
if n > 1 {
panic!("Read {} characters into a 1 byte buffer", n);
}
if n == 1 {
tx_input.send(buf[0]).unwrap();
}
// Nothing needs to be sent for n == 0
}
});
RawTerminal {
rx_input,
}
}
}

impl Terminal for RawTerminal {
fn put_byte(&mut self, value: u8) {
let str = vec![value];
match str::from_utf8(&str) {
Ok(s) => {
print!("{}", s);
},
Err(_e) => {}
};
match stdout().flush() {
_ => {} // Ignoring error so far
};
}

fn get_input(&mut self) -> u8 {
match self.rx_input.try_recv() {
Ok(c) => return c,
_ => return 0,
}
}

// Wasm specific methods. No use.

fn put_input(&mut self, _value: u8) {
}

fn get_output(&mut self) -> u8 {
0
}
}