summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core.rs45
-rw-r--r--src/main.rs29
-rw-r--r--src/memory.rs18
-rw-r--r--src/rom.rs37
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)
+ }
+}
diff --git a/src/rom.rs b/src/rom.rs
index 77e6431..c054575 100644
--- a/src/rom.rs
+++ b/src/rom.rs
@@ -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;
}
}