diff options
author | Oxore <oxore@protonmail.com> | 2019-09-30 03:56:26 +0300 |
---|---|---|
committer | Oxore <oxore@protonmail.com> | 2019-09-30 03:56:26 +0300 |
commit | 615ef873ca3aff557b21658b54a7cb1081404d86 (patch) | |
tree | 434c30a9d3f918a031cca85ddb6e1b1276bca512 | |
parent | 48030bad83a067388e473cba08f7b48b846c5468 (diff) |
Implement basic ram loader from hex
-rw-r--r-- | src/core.rs | 15 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/ram.rs | 87 |
3 files changed, 99 insertions, 8 deletions
diff --git a/src/core.rs b/src/core.rs index b51cf80..6d9a5e1 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,3 +1,4 @@ +use crate::ram::Ram; use std::fmt; #[derive(Debug, Clone)] @@ -37,12 +38,12 @@ impl fmt::Display for Op { pub struct Core { pc: u16, - ram: [u8; u16::max_value() as usize + 1], + ram: Ram, } impl Core { - pub fn new() -> Self { - Self { pc: 0, ram: [0; u16::max_value() as usize + 1] } + pub fn with_ram_from_hex(hex: String) -> Self { + Self { pc: 0, ram: Ram::from_hex(hex) } } pub fn step(&mut self) -> u16 { @@ -52,7 +53,7 @@ impl Core { } pub fn op(&self) -> Opcode { - self.ram[self.pc as usize].op().0 + self.ram.array[self.pc as usize].op().0 } /// @@ -61,10 +62,10 @@ impl Core { /// fn fetch(&mut self) -> Op { let mut operand1 = None; - let opcode = self.ram[self.pc as usize].opcode(); - let size = self.ram[self.pc as usize].opsize(); + let opcode = self.ram.array[self.pc as usize].opcode(); + let size = self.ram.array[self.pc as usize].opsize(); if size == 2 { - operand1 = Some(self.ram[self.pc as usize]); + operand1 = Some(self.ram.array[self.pc as usize]); } self.pc += size as u16; Op { diff --git a/src/main.rs b/src/main.rs index 974ff5c..0d79c33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,10 @@ use std::io::prelude::*; use std::{thread, time}; use std::thread::sleep; use std::sync::{Arc, Mutex, Condvar}; +use std::string::String; mod core; +mod ram; use self::core::Core; fn core_worker(mut core: Core, should_stop: &Mutex<bool>, cvar: &Condvar) { @@ -42,10 +44,11 @@ fn cli_controller(asyncpair: Arc<(Mutex<bool>, Condvar)>) { } fn main() { - let core = Core::new(); let asyncpair = Arc::new((Mutex::new(false), Condvar::new())); let asyncpair2 = asyncpair.clone(); + let core = Core::with_ram_from_hex(String::from(":0300000075800008\n:00000001FF\n")); + thread::spawn(move || { let (ref should_stop, ref condvar) = *asyncpair2; core_worker(core, should_stop, condvar); diff --git a/src/ram.rs b/src/ram.rs new file mode 100644 index 0000000..c7c4d43 --- /dev/null +++ b/src/ram.rs @@ -0,0 +1,87 @@ +use std::fmt; + +pub struct Ram { + pub array: [u8; u16::max_value() as usize + 1], +} + +impl fmt::Debug for Ram { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut c = 0; + let mut v: Vec<char> = vec![]; + for x in self.array.into_iter() { + for hex_char in format!("{:02X}", *x).chars() { + v.push(hex_char); + } + v.push(' '); + if c % 8 == 7 { + v.push('\n'); + } + c += 1; + } + write!(f, "{}", v.iter().collect::<String>()) + } +} + +enum Rectyp { + Data, + EndOfFile, + //ExtendedSegAddr, + //StartSegAddr, + //ExtendedLinearAddr, + //StartLinearAddr, +} + +struct HexLine { + rectyp: Rectyp, + offset: u16, + data: Vec<u8>, +} + +impl HexLine { + fn from(s: &str) -> Result<Self, i32> { + // The shortest possible sequence is EOF (:00000001FF) + if s.len() < 11 { + return Err(1) + } + if &s[0..1] != ":" { + return Err(2) + } + let offset = (&s[3..7]).parse::<u16>().unwrap(); // TODO: handle unwrap + let bytecount = (&s[1..3]).parse::<usize>().unwrap(); // TODO: handle unwrap + + // If EOF reached + if &s[7..9] == "01" { + return Ok(HexLine { rectyp: Rectyp::EndOfFile, offset, data: vec![0] }) + } else if &s[7..9] == "00" { + let mut counter = 9; + let mut data = vec![]; + while counter < s.len() - 2 && counter < (9 + bytecount * 2) { + data.push((&s[counter..counter+2]).parse::<u8>().unwrap()); // TODO handle unwrap + counter += 2; + } + // TODO: check checksum + return Ok(HexLine { rectyp: Rectyp::Data, offset, data }) + } + + Err(3) + } +} + +impl Ram { + pub fn from_hex(hex: String) -> Self { + let mut array = [0; u16::max_value() as usize + 1]; + for line in hex.lines() { + let hex_line = HexLine::from(line).unwrap(); // TODO: handle unwrap + let offset = hex_line.offset; + match hex_line.rectyp { + Rectyp::Data => { + for (ptr, byte) in hex_line.data.iter().enumerate() { + array[ptr + offset as usize] = *byte; + } + } + Rectyp::EndOfFile => {} + } + } + Self { array } + } +} |