diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core.rs | 45 | ||||
-rw-r--r-- | src/main.rs | 29 | ||||
-rw-r--r-- | src/memory.rs | 18 | ||||
-rw-r--r-- | src/rom.rs | 37 |
4 files changed, 90 insertions, 39 deletions
diff --git a/src/core.rs b/src/core.rs index ef3c115..a85d830 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,4 +1,5 @@ use crate::rom::Rom; +use crate::memory::Memory; use std::fmt; #[derive(Debug, Clone, Copy)] @@ -360,21 +361,21 @@ impl IncompleteOp { impl Core { /// Constructor - pub fn new_with_rom_from_hex(hex: String) -> Result<Self, String> { - let mut ram: [u8; u8::max_value() as usize + 1] = [0; u8::max_value() as usize + 1]; + pub fn new() -> Self { + let mut ram = [0; u8::max_value() as usize + 1]; ram[RAM_OFFSET_SP as usize] = RESET_VALUE_SP; ram[RAM_OFFSET_ACC as usize] = RESET_VALUE_ACC; - let progmem = match Rom::from_hex(hex) { - Ok(value) => value, - Err(err_string) => return Err(err_string), - }; - let extmem: [u8; u16::max_value() as usize + 1] = [0xFF; u16::max_value() as usize + 1]; - Ok(Self { + Self { pc: 0, ram, - progmem, - extmem, - }) + progmem: Rom::new(), + extmem: [0xFF; u16::max_value() as usize + 1], + } + } + + pub fn rom(mut self, rom: Rom) -> Self { + self.progmem = rom; + self } /// Fetch and execute one instruction @@ -391,14 +392,14 @@ impl Core { /// Get current instruction pub fn op(&self) -> Op { - let op = IncompleteOp::from_u8(self.progmem.array[self.pc as usize]); + let op = IncompleteOp::from_u8(self.progmem.get(self.pc)); let operand1 = if let Some(incomplete_operand) = op.operand1 { Some(self.fetch_operand(incomplete_operand, 1)) } else { None }; let operand2_offset = match &operand1 { - Some(operand) => operand.size(), + Some(operand) => operand.size() as u16, _ => 0, }; let operand2 = if let Some(incomplete_operand) = op.operand2 { @@ -452,18 +453,18 @@ impl Core { } /// Get operand by offset, based on meta information - fn fetch_operand(&self, operand: IncompleteOperand, offset: usize) -> Operand { + fn fetch_operand(&self, operand: IncompleteOperand, offset: u16) -> Operand { match operand { IncompleteOperand::Acc => Operand::Acc, IncompleteOperand::Direct => { - Operand::Direct(self.progmem.array[(self.pc as usize + offset)]) + Operand::Direct(self.progmem.get(self.pc + offset)) } IncompleteOperand::Data => { - Operand::Data(self.progmem.array[(self.pc as usize + offset)]) + Operand::Data(self.progmem.get(self.pc + offset)) } IncompleteOperand::Data16 => Operand::Data16({ - let high = self.progmem.array[(self.pc as usize + offset)]; - let low = self.progmem.array[(self.pc as usize + offset + 1)]; + let high = self.progmem.get(self.pc + offset); + let low = self.progmem.get(self.pc + offset + 1); u16::from(high) << 8 & u16::from(low) }), IncompleteOperand::Dptr => Operand::Dptr, @@ -471,15 +472,15 @@ impl Core { IncompleteOperand::Indirect(r) => Operand::Indirect(r), IncompleteOperand::Register(r) => Operand::Register(r), IncompleteOperand::Reladdr => { - Operand::Reladdr(self.progmem.array[(self.pc as usize + offset)] as i8) + Operand::Reladdr(self.progmem.get(self.pc + offset) as i8) } IncompleteOperand::Addr11(high) => Operand::Addr11({ - let low = self.progmem.array[(self.pc as usize + offset)]; + let low = self.progmem.get(self.pc + offset); u16::from(high) << 8 & u16::from(low) }), IncompleteOperand::Addr16 => Operand::Addr16({ - let high = self.progmem.array[(self.pc as usize + offset)]; - let low = self.progmem.array[(self.pc as usize + offset + 1)]; + let high = self.progmem.get(self.pc + offset); + let low = self.progmem.get(self.pc + offset + 1); u16::from(high) << 8 & u16::from(low) }), } diff --git a/src/main.rs b/src/main.rs index 8f1acad..05b32c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,10 @@ use std::time::Duration; mod core; mod rom; +mod memory; + use self::core::Core; +use self::rom::Rom; enum Control { Run(bool), @@ -126,34 +129,34 @@ fn main() { .value_of("file") .expect("No file name provided"); - let controller = { - let controller_type_name = cli_args_matches - .value_of("interface") - .expect("No interface type specified"); - new_controller(controller_type_name) - .unwrap_or_else(|_| panic!("Unknown controller type \"{}\"", controller_type_name)) - }; - /* Read program and instantiate a simulator */ let data = fs::read_to_string(filename).unwrap_or_else(|_| panic!("Unable to read file {}", filename)); - let core = match Core::new_with_rom_from_hex(data) { + let core = Core::new().rom(match Rom::from_hex(data) { Ok(value) => value, Err(err_string) => { println!("{}", err_string); return; } - }; + }); /* Run core worker and controller */ let (bound_core, bound_controller) = new_bound_pair(); + core_worker(core, bound_core); + thread::spawn(move || { - core_worker(core, bound_core); + let controller = { + let controller_type_name = cli_args_matches + .value_of("interface") + .expect("No interface type specified"); + new_controller(controller_type_name) + .unwrap_or_else(|_| panic!("Unknown controller type \"{}\"", controller_type_name)) + }; + + controller(bound_controller); }); - - controller(bound_controller); } diff --git a/src/memory.rs b/src/memory.rs new file mode 100644 index 0000000..372a029 --- /dev/null +++ b/src/memory.rs @@ -0,0 +1,18 @@ +extern crate num_traits; + +pub trait Memory<Addr> + where Addr: Copy + core::ops::Add<Output = Addr> + num_traits::identities::One +{ + fn get(&self, a: Addr) -> u8; + + fn set(&mut self, a: Addr, v: u8); + + fn get_word(&self, a: Addr) -> u16 { + u16::from(self.get(a)) | (u16::from(self.get(a + Addr::one())) << 8) + } + + fn set_word(&mut self, a: Addr, v: u16) { + self.set(a, (v & 0xFF) as u8); + self.set(a + Addr::one(), (v >> 8) as u8) + } +} @@ -1,7 +1,8 @@ use std::fmt; +use crate::memory::Memory; pub struct Rom { - pub array: [u8; u16::max_value() as usize + 1], + array: [u8; u16::max_value() as usize + 1], } impl fmt::Debug for Rom { @@ -83,8 +84,26 @@ impl HexLine { } impl Rom { + /// Empty constructor + pub fn new() -> Self { + Self { array: [0; u16::max_value() as usize + 1] } + } + + /// Constructor from hex pub fn from_hex(hex: String) -> Result<Self, String> { - let mut array = [0; u16::max_value() as usize + 1]; + Self::new().hex(hex) + } + + /// Method for sequential consuming building + pub fn hex(mut self, hex: String) -> Result<Self, String> { + match self.load_hex(hex) { + Ok(_) => Ok(self), + Err(string) => Err(string), + } + } + + /// Method for occasional incremental hex loading + pub fn load_hex(&mut self, hex: String) -> Result<(), String> { for (linenum, line) in hex.lines().enumerate() { let hex_line = match HexLine::from(line) { Ok(value) => value, @@ -94,12 +113,22 @@ impl Rom { match hex_line.rectyp { Rectyp::Data => { for (ptr, byte) in hex_line.data.iter().enumerate() { - array[ptr + offset as usize] = *byte; + self.array[ptr + offset as usize] = *byte; } } Rectyp::EndOfFile => {} } } - Ok(Self { array }) + Ok(()) + } +} + +impl Memory<u16> for Rom { + fn get(&self, a: u16) -> u8 { + self.array[a as usize] + } + + fn set(&mut self, a: u16, v: u8) { + self.array[a as usize] = v; } } |