diff --git a/Cargo.lock b/Cargo.lock index 495c3d5..a4fcddd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,4 +13,20 @@ name = "lc3" version = "0.1.0" dependencies = [ "byteorder", + "termios", +] + +[[package]] +name = "libc" +version = "0.2.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" + +[[package]] +name = "termios" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b" +dependencies = [ + "libc", ] diff --git a/Cargo.toml b/Cargo.toml index ecf7be9..62d08be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] byteorder = "1.5.0" +termios = "0.3.3" diff --git a/src/vm/memory.rs b/src/vm/memory.rs new file mode 100644 index 0000000..27ab6e9 --- /dev/null +++ b/src/vm/memory.rs @@ -0,0 +1,32 @@ +////////////////////////////// +////// memory and memory-mapped registers +////////////////////////////// + +//////////////// +// memory interface +//////////////// + +pub const MEM_SIZE: usize = 1 << 16; + +pub struct Memory { + data: [u16; MEM_SIZE], +} + +impl Memory { + pub fn new() -> Memory { + Memory { + data: [0; MEM_SIZE], + } + } + + pub fn set_mem(&mut self, addr: u16, val: u16) { + self.data[addr as usize] = val; + } + + pub fn get_mem(&self, addr: u16) -> u16 { + if addr >= 0xFE00 { + unimplemented!("mem-map: {:#X}", addr); + } + return self.data[addr as usize]; + } +} diff --git a/src/vm/mod.rs b/src/vm/mod.rs index efbe191..0c67a04 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -12,13 +12,14 @@ use byteorder::{BigEndian, ReadBytesExt}; use std::{fs::File, io::BufReader}; mod instruction; +mod memory; //////////////// // registers //////////////// // condition flags (COND register) -pub enum CondFlags { +enum CondFlags { // positive (P) POS = 1 << 0, // zero (Z) @@ -105,38 +106,12 @@ impl Registers { } } -//////////////// -// memory -//////////////// - -const MEM_SIZE: usize = 1 << 16; - -struct Memory { - data: [u16; MEM_SIZE], -} - -impl Memory { - fn new() -> Memory { - Memory { - data: [0; MEM_SIZE], - } - } - - fn set_mem(&mut self, addr: u16, val: u16) { - self.data[addr as usize] = val; - } - - fn get_mem(&self, addr: u16) -> u16 { - return self.data[addr as usize]; - } -} - //////////////// // VM interface //////////////// pub struct VM { - mem: Memory, + mem: memory::Memory, registers: Registers, running: bool, } @@ -144,7 +119,7 @@ pub struct VM { impl VM { pub fn new() -> VM { VM { - mem: Memory::new(), + mem: memory::Memory::new(), registers: Registers::new(), running: false, } @@ -198,7 +173,7 @@ impl VM { // remember PC points to the *next* instruction at all times // disallow reading past memory bounds - if self.registers.pc as usize == MEM_SIZE - 1 { + if self.registers.pc as usize == memory::MEM_SIZE - 1 { self.running = false } else { self.registers.pc += 1;