ft(interpreter): expose data to memory

This commit is contained in:
2025-07-01 11:00:22 +09:00
parent 13cb907977
commit f3fd655908
4 changed files with 28 additions and 25 deletions

View File

@@ -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())

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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 {