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.
This commit is contained in:
@@ -48,60 +48,37 @@ impl Memory {
|
|||||||
idx: MemoryIndex,
|
idx: MemoryIndex,
|
||||||
val: ImmediateOperand,
|
val: ImmediateOperand,
|
||||||
) {
|
) {
|
||||||
match Memory::calc_memidx(regs, idx) {
|
let idx = Memory::calc_memidx(regs, idx);
|
||||||
ImmediateOperand::Byte(idx_byte) => match val {
|
match val {
|
||||||
ImmediateOperand::Byte(value) => {
|
ImmediateOperand::Byte(b) => {
|
||||||
log::debug!("Writing byte {value:#04x} to memory location {idx_byte:#04x}");
|
log::debug!("Writing byte {b:#04x} to memory location {idx:#04x}");
|
||||||
self.memory[idx_byte as usize] = value
|
self.memory[idx as usize] = b
|
||||||
}
|
}
|
||||||
ImmediateOperand::Word(_) => panic!("Cannot add Word to Byte Memory Index"),
|
ImmediateOperand::Word(value) => {
|
||||||
},
|
let byte1 = idx / 2;
|
||||||
ImmediateOperand::Word(idx_word) => match val {
|
let byte2 = idx / 2 + 1;
|
||||||
ImmediateOperand::Word(value) => {
|
let [low, high]: [u8; 2] = value.to_le_bytes();
|
||||||
let byte1 = idx_word / 2;
|
log::debug!(
|
||||||
let byte2 = idx_word / 2 + 1;
|
"Writing bytes {low:#04x} and {high:#04x} to memory location {byte1:#04x} and {byte2:#04x}"
|
||||||
let [low, high]: [u8; 2] = value.to_le_bytes();
|
);
|
||||||
log::debug!(
|
self.memory[byte1 as usize] = low;
|
||||||
"Writing bytes {low:#04x} and {high:#04x} to memory location {byte1:#04x} and {byte2:#04x}"
|
self.memory[byte1 as usize] = high;
|
||||||
);
|
}
|
||||||
self.memory[byte1 as usize] = low;
|
|
||||||
self.memory[byte1 as usize] = high;
|
|
||||||
}
|
|
||||||
ImmediateOperand::Byte(value) => {
|
|
||||||
self.memory[(idx_word * 2) as usize] = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read into memory with a [`MemoryIndex`] as index.
|
/// Read into memory with a [`MemoryIndex`] as index.
|
||||||
pub fn read(
|
/// Always reads a whole word.
|
||||||
&self,
|
pub fn read(&self, regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Word {
|
||||||
regs: &crate::interpreter::register::Register,
|
let idx = Self::calc_memidx(regs, idx);
|
||||||
idx: MemoryIndex,
|
let byte1 = idx / 2;
|
||||||
) -> ImmediateOperand {
|
let byte2 = idx / 2 + 1;
|
||||||
match Memory::calc_memidx(regs, idx) {
|
log::debug!("Reading bytes {byte1:#04x} and {byte2:#04x} from memory");
|
||||||
ImmediateOperand::Byte(byte) => {
|
Word::from_le_bytes([self.memory[byte1 as usize], self.memory[byte2 as usize]])
|
||||||
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],
|
|
||||||
]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the absolute memory address from a [`MemoryIndex`] struct.
|
/// Calculate the absolute memory address from a [`MemoryIndex`] struct.
|
||||||
pub fn calc_memidx(
|
pub fn calc_memidx(regs: &crate::interpreter::register::Register, idx: MemoryIndex) -> Word {
|
||||||
regs: &crate::interpreter::register::Register,
|
|
||||||
idx: MemoryIndex,
|
|
||||||
) -> ImmediateOperand {
|
|
||||||
let mut base = ImmediateOperand::Word(0);
|
let mut base = ImmediateOperand::Word(0);
|
||||||
let mut index = ImmediateOperand::Word(0);
|
let mut index = ImmediateOperand::Word(0);
|
||||||
let mut disp = Displacement::IWord(0);
|
let mut disp = Displacement::IWord(0);
|
||||||
@@ -116,6 +93,6 @@ impl Memory {
|
|||||||
disp = displacement;
|
disp = displacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
base + index + disp
|
(base + index + disp).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,24 +93,24 @@ impl Register {
|
|||||||
crate::register::Register::SP => self.sp = Word::from_le_bytes([0x0, byte]),
|
crate::register::Register::SP => self.sp = Word::from_le_bytes([0x0, byte]),
|
||||||
},
|
},
|
||||||
ImmediateOperand::Word(word) => {
|
ImmediateOperand::Word(word) => {
|
||||||
|
let [low, high] = word.to_le_bytes();
|
||||||
match reg {
|
match reg {
|
||||||
crate::register::Register::AX => self.ax.write(word),
|
crate::register::Register::AX => self.ax.write(word),
|
||||||
crate::register::Register::BX => self.bx.write(word),
|
crate::register::Register::BX => self.bx.write(word),
|
||||||
crate::register::Register::CX => self.cx.write(word),
|
crate::register::Register::CX => self.cx.write(word),
|
||||||
crate::register::Register::DX => self.dx.write(word),
|
crate::register::Register::DX => self.dx.write(word),
|
||||||
// crate::register::Register::AH => {}
|
crate::register::Register::AH => self.ax.upper = high,
|
||||||
// crate::register::Register::AL => {}
|
crate::register::Register::AL => self.ax.lower = low,
|
||||||
// crate::register::Register::BL => {}
|
crate::register::Register::BH => self.ax.upper = high,
|
||||||
// crate::register::Register::BH => {}
|
crate::register::Register::BL => self.ax.lower = low,
|
||||||
// crate::register::Register::CH => {}
|
crate::register::Register::CH => self.ax.upper = high,
|
||||||
// crate::register::Register::CL => {}
|
crate::register::Register::CL => self.ax.lower = low,
|
||||||
// crate::register::Register::DH => {}
|
crate::register::Register::DH => self.ax.upper = high,
|
||||||
// crate::register::Register::DL => {}
|
crate::register::Register::DL => self.ax.lower = low,
|
||||||
crate::register::Register::DI => self.di = word,
|
crate::register::Register::DI => self.di = word,
|
||||||
crate::register::Register::SI => self.si = word,
|
crate::register::Register::SI => self.si = word,
|
||||||
crate::register::Register::BP => self.bp = word,
|
crate::register::Register::BP => self.bp = word,
|
||||||
crate::register::Register::SP => self.sp = word,
|
crate::register::Register::SP => self.sp = word,
|
||||||
_ => panic!("Tried writing Word to Byte-sized register"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user