src/vm/terminal_io: setup termios

This commit is contained in:
dogeystamp 2024-01-06 18:05:35 -05:00
parent f965108172
commit 04fa5454ef
Signed by: dogeystamp
GPG Key ID: 7225FE3592EFFA38
7 changed files with 155 additions and 4 deletions

101
Cargo.lock generated
View File

@ -2,17 +2,41 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ctrlc"
version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b"
dependencies = [
"nix",
"windows-sys",
]
[[package]]
name = "lc3"
version = "0.1.0"
dependencies = [
"byteorder",
"ctrlc",
"libc",
"termios",
]
@ -22,6 +46,17 @@ version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "termios"
version = "0.3.3"
@ -30,3 +65,69 @@ checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
dependencies = [
"libc",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"

View File

@ -7,4 +7,6 @@ edition = "2021"
[dependencies]
byteorder = "1.5.0"
ctrlc = "3.4.2"
libc = "0.2.151"
termios = "0.3.3"

View File

@ -3,11 +3,13 @@
//////////////////////////////
mod vm;
use crate::vm::VM;
use crate::vm::{terminal_io, VM};
use std::env;
fn main() {
let args : Vec<_> = env::args().collect();
let args: Vec<_> = env::args().collect();
terminal_io::setup_terminal();
let mut vm = VM::new();
vm.read_program(args.get(1).expect("No program file given"));

View File

@ -224,7 +224,10 @@ fn op_add(vm: &mut VM, instr: u16) {
if (instr >> 5) & 1 == 0 {
let sr2 = instr & 0b111;
let res = vm.registers.get_reg(sr1).wrapping_add(vm.registers.get_reg(sr2));
let res = vm
.registers
.get_reg(sr1)
.wrapping_add(vm.registers.get_reg(sr2));
vm.registers.set_reg_with_cond(dr, res);
} else {
let imm = instr & 0x1f;

View File

@ -6,6 +6,8 @@
// memory interface
////////////////
use super::terminal_io;
pub const MEM_SIZE: usize = 1 << 16;
pub struct Memory {
@ -25,7 +27,9 @@ impl Memory {
pub fn get_mem(&self, addr: u16) -> u16 {
if addr >= 0xFE00 {
unimplemented!("mem-map: {:#X}", addr);
match addr {
_ => unimplemented!("mem-map: {:#X}", addr),
}
}
return self.data[addr as usize];
}

View File

@ -13,6 +13,7 @@ use std::{fs::File, io::BufReader};
mod instruction;
mod memory;
pub mod terminal_io;
////////////////
// registers

38
src/vm/terminal_io.rs Normal file
View File

@ -0,0 +1,38 @@
//////////////////////////////
////// terminal input/output
//////////////////////////////
extern crate termios;
use termios::*;
extern crate libc;
use libc::STDIN_FILENO;
extern crate ctrlc;
/// Configure raw input (see termios(3) man-page)
pub fn setup_terminal() {
let mut term: Termios = Termios::from_fd(STDIN_FILENO).unwrap();
// ICANON (canonical) is line-by-line input (i.e. press enter to send)
// ECHO is showing the characters you type
// what this means is that LC-3 will receive characters immediately and without displaying them
term.c_lflag &= !(ICANON | ECHO);
// TCSANOW: "the change occurs immediately"
tcsetattr(STDIN_FILENO, TCSANOW, &term).unwrap();
// when leaving the program we want to be polite and undo the above changes
ctrlc::set_handler(|| {
restore_terminal();
// typical CTRL-C exit code
std::process::exit(130);
})
.expect("Failed to set CTRL-C handler");
}
/// Restore terminal to initial state
fn restore_terminal() {
// Ideally we'd store the original state but I was too lazy
let mut term: Termios = Termios::from_fd(STDIN_FILENO).unwrap();
term.c_lflag |= ICANON | ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &term).unwrap()
}