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

View File

@@ -1,8 +1,6 @@
use crate::operands::{Byte, ImmediateOperand, Word}; use crate::operands::{Byte, ImmediateOperand, Word};
use core::fmt; use core::fmt;
use super::interpreter::InterpreterError;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Register { pub struct Register {
pub ax: AX, pub ax: AX,

View File

@@ -539,6 +539,16 @@ pub struct MemoryIndex {
pub displacement: Option<ImmediateOperand>, 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 { impl fmt::Display for MemoryIndex {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.base { match &self.base {