From 7f4d79d84052287c77981c89be968fc3f7a363b6 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Tue, 17 Jun 2025 12:00:56 +0900 Subject: [PATCH] fix(interpreter): always read word from memory It's not possible to know if a word or byte is requested, or rather it would be a pain to retrieve that information. It is much easier to just read a full word and then discard the top half, if just a byte is needed. --- src/interpreter/memory.rs | 73 +++++++++++++------------------------ src/interpreter/register.rs | 18 ++++----- 2 files changed, 34 insertions(+), 57 deletions(-) diff --git a/src/interpreter/memory.rs b/src/interpreter/memory.rs index 460d68f..84f7033 100644 --- a/src/interpreter/memory.rs +++ b/src/interpreter/memory.rs @@ -48,60 +48,37 @@ impl Memory { idx: MemoryIndex, val: ImmediateOperand, ) { - match Memory::calc_memidx(regs, idx) { - ImmediateOperand::Byte(idx_byte) => match val { - ImmediateOperand::Byte(value) => { - log::debug!("Writing byte {value:#04x} to memory location {idx_byte:#04x}"); - self.memory[idx_byte as usize] = value - } - ImmediateOperand::Word(_) => panic!("Cannot add Word to Byte Memory Index"), - }, - ImmediateOperand::Word(idx_word) => match val { - ImmediateOperand::Word(value) => { - let byte1 = idx_word / 2; - let byte2 = idx_word / 2 + 1; - let [low, high]: [u8; 2] = value.to_le_bytes(); - log::debug!( - "Writing bytes {low:#04x} and {high:#04x} to memory location {byte1:#04x} and {byte2:#04x}" - ); - self.memory[byte1 as usize] = low; - self.memory[byte1 as usize] = high; - } - ImmediateOperand::Byte(value) => { - self.memory[(idx_word * 2) as usize] = value; - } - }, + let idx = Memory::calc_memidx(regs, idx); + match val { + ImmediateOperand::Byte(b) => { + log::debug!("Writing byte {b:#04x} to memory location {idx:#04x}"); + self.memory[idx as usize] = b + } + ImmediateOperand::Word(value) => { + let byte1 = idx / 2; + let byte2 = idx / 2 + 1; + let [low, high]: [u8; 2] = value.to_le_bytes(); + log::debug!( + "Writing bytes {low:#04x} and {high:#04x} to memory location {byte1:#04x} and {byte2:#04x}" + ); + self.memory[byte1 as usize] = low; + self.memory[byte1 as usize] = high; + } } } /// Read into memory with a [`MemoryIndex`] as index. - pub fn read( - &self, - regs: &crate::interpreter::register::Register, - idx: MemoryIndex, - ) -> ImmediateOperand { - match Memory::calc_memidx(regs, idx) { - ImmediateOperand::Byte(byte) => { - log::debug!("Reading byte {byte:#04x} from memory"); - ImmediateOperand::Byte(self.memory[byte as usize]) - } - ImmediateOperand::Word(word) => { - let byte1 = word / 2; - let byte2 = word / 2 + 1; - log::debug!("Reading bytes {byte1:#04x} and {byte2:#04x} from memory"); - ImmediateOperand::Word(Word::from_le_bytes([ - self.memory[byte1 as usize], - self.memory[byte2 as usize], - ])) - } - } + /// Always reads a whole word. + pub fn read(&self, regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Word { + let idx = Self::calc_memidx(regs, idx); + let byte1 = idx / 2; + let byte2 = idx / 2 + 1; + log::debug!("Reading bytes {byte1:#04x} and {byte2:#04x} from memory"); + Word::from_le_bytes([self.memory[byte1 as usize], self.memory[byte2 as usize]]) } /// Calculate the absolute memory address from a [`MemoryIndex`] struct. - pub fn calc_memidx( - regs: &crate::interpreter::register::Register, - idx: MemoryIndex, - ) -> ImmediateOperand { + pub fn calc_memidx(regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Word { let mut base = ImmediateOperand::Word(0); let mut index = ImmediateOperand::Word(0); let mut disp = Displacement::IWord(0); @@ -116,6 +93,6 @@ impl Memory { disp = displacement; } - base + index + disp + (base + index + disp).into() } } diff --git a/src/interpreter/register.rs b/src/interpreter/register.rs index 857fd33..be2f08d 100644 --- a/src/interpreter/register.rs +++ b/src/interpreter/register.rs @@ -93,24 +93,24 @@ impl Register { crate::register::Register::SP => self.sp = Word::from_le_bytes([0x0, byte]), }, ImmediateOperand::Word(word) => { + let [low, high] = word.to_le_bytes(); match reg { crate::register::Register::AX => self.ax.write(word), crate::register::Register::BX => self.bx.write(word), crate::register::Register::CX => self.cx.write(word), crate::register::Register::DX => self.dx.write(word), - // crate::register::Register::AH => {} - // crate::register::Register::AL => {} - // crate::register::Register::BL => {} - // crate::register::Register::BH => {} - // crate::register::Register::CH => {} - // crate::register::Register::CL => {} - // crate::register::Register::DH => {} - // crate::register::Register::DL => {} + crate::register::Register::AH => self.ax.upper = high, + crate::register::Register::AL => self.ax.lower = low, + crate::register::Register::BH => self.ax.upper = high, + crate::register::Register::BL => self.ax.lower = low, + crate::register::Register::CH => self.ax.upper = high, + crate::register::Register::CL => self.ax.lower = low, + crate::register::Register::DH => self.ax.upper = high, + crate::register::Register::DL => self.ax.lower = low, crate::register::Register::DI => self.di = word, crate::register::Register::SI => self.si = word, crate::register::Register::BP => self.bp = word, crate::register::Register::SP => self.sp = word, - _ => panic!("Tried writing Word to Byte-sized register"), } } }