ft(interpreter): expose data to memory
This commit is contained in:
@@ -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<Byte>) -> 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} <op> {: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())
|
||||
|
||||
@@ -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<Instruction>,
|
||||
data: Vec<Byte>,
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn new(instructions: Vec<Instruction>, data: Vec<Byte>) -> 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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -539,6 +539,16 @@ pub struct MemoryIndex {
|
||||
pub displacement: Option<ImmediateOperand>,
|
||||
}
|
||||
|
||||
impl Into<MemoryIndex> 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 {
|
||||
|
||||
Reference in New Issue
Block a user