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 = 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::()) } } enum Rectyp { Data, EndOfFile, //ExtendedSegAddr, //StartSegAddr, //ExtendedLinearAddr, //StartLinearAddr, } struct HexLine { rectyp: Rectyp, offset: u16, data: Vec, } impl HexLine { fn from(s: &str) -> Result { // 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::().unwrap(); // TODO: handle unwrap let bytecount = (&s[1..3]).parse::().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::().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 } } }