diff --git a/src/interpreter/computer.rs b/src/interpreter/computer.rs index 36afb5c..f114573 100644 --- a/src/interpreter/computer.rs +++ b/src/interpreter/computer.rs @@ -3,7 +3,7 @@ use core::fmt; use crate::{ Args, - operands::{ImmediateOperand, ImmediateOperandSigned, MemoryIndex, ModRmTarget, Word}, + operands::{Byte, ImmediateOperand, ImmediateOperandSigned, MemoryIndex, ModRmTarget, Word}, }; use super::{ @@ -31,21 +31,20 @@ pub struct Computer { } impl Computer { - pub fn new() -> Self { + pub fn new(data: Vec) -> Self { let mut computer = Self { regs: Register::new(), sregs: SegmentRegister::new(), flags: Flags::new(), memory: Memory::new(), }; - // Initialization cannot fail computer.init_stack().unwrap(); - // for (idx, val) in computer.memory.raw.iter().enumerate() { - // if idx > 0xfff9 && idx <= 0xffff { - // log::debug!("MEMORY {idx}: {val}"); - // } - // } + // Copy static data to 0x0000; + for (addr, b) in data.iter().enumerate() { + let val = ImmediateOperand::Byte(*b); + computer.write(val, (addr as Word).into()).unwrap(); + } computer } @@ -328,6 +327,7 @@ impl Computer { ArithmeticOperand::ModRmTarget(target) => self.read_modrm(target)?, }; let result = op(lhs, rhs); + log::debug!("{:04x} {:04x} = {:04x}", lhs, rhs, result); if write { self.write_modrm(dest, result)?; } @@ -460,7 +460,7 @@ mod tests { #[test] fn test_push() { - let mut c = Computer::new(); + let mut c = Computer::new(Vec::from([0])); let val = ImmediateOperand::Word(0x1234); println!("{}", c.regs); assert_eq!(val, c.pop_stack().unwrap().into()) diff --git a/src/interpreter/interpreter.rs b/src/interpreter/interpreter.rs index 9cfff84..3ae41b9 100644 --- a/src/interpreter/interpreter.rs +++ b/src/interpreter/interpreter.rs @@ -20,7 +20,6 @@ type InstructionPointer<'a> = std::slice::Iter<'a, Instruction>; #[derive(Debug, Clone)] pub enum InterpreterError { - EndOfData, InvalidSyscall(Byte), InstructionNotFound(Word), MemoryOutOfBound(Word), @@ -29,7 +28,6 @@ pub enum InterpreterError { impl fmt::Display for InterpreterError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - InterpreterError::EndOfData => write!(f, "Read beyond the available data section"), InterpreterError::InvalidSyscall(id) => { write!(f, "The syscall with ID {} is unknown", id) } @@ -50,15 +48,13 @@ impl fmt::Display for InterpreterError { pub struct Interpreter { computer: Computer, instructions: Vec, - data: Vec, } impl Interpreter { pub fn new(instructions: Vec, data: Vec) -> Self { Self { - computer: Computer::new(), + computer: Computer::new(data), instructions, - data, } } @@ -781,14 +777,13 @@ impl Interpreter { } fn interpret_interrupt(&self, id: u8) -> Result<(), InterpreterError> { - let bx = self.computer.regs.bx.read() as usize; - // a message is always 8 words aligned - let len = 2 * 8; - let data = self - .data - .get(bx..bx + len) - .ok_or(InterpreterError::EndOfData)? - .to_owned(); + let bx = self.computer.regs.bx.read(); + let w1 = self.computer.read(bx.into())?; + let w2 = self.computer.read((bx + 2).into())?; + + let mut data = Vec::new(); + data.extend_from_slice(&w1.to_le_bytes()); + data.extend_from_slice(&w2.to_le_bytes()); let msg = InterruptMessage::new(&data); @@ -812,7 +807,7 @@ impl Interpreter { let len = data.i2; let location = data.p1; log::info!("executing write({}, {}, {})", fd, location, len); - for byte in &self.data[location as usize..] { + for byte in &self.computer.memory.raw[location as usize..] { if *byte == 0x00 { break; } else { diff --git a/src/interpreter/register.rs b/src/interpreter/register.rs index 6df45e5..675c33b 100644 --- a/src/interpreter/register.rs +++ b/src/interpreter/register.rs @@ -1,8 +1,6 @@ use crate::operands::{Byte, ImmediateOperand, Word}; use core::fmt; -use super::interpreter::InterpreterError; - #[derive(Debug, Clone, Copy)] pub struct Register { pub ax: AX, diff --git a/src/operands.rs b/src/operands.rs index e943a47..4ed9a62 100644 --- a/src/operands.rs +++ b/src/operands.rs @@ -539,6 +539,16 @@ pub struct MemoryIndex { pub displacement: Option, } +impl Into for u16 { + fn into(self) -> MemoryIndex { + MemoryIndex { + base: None, + index: None, + displacement: Some(self.into()), + } + } +} + impl fmt::Display for MemoryIndex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self.base {