From e8287097adc348076bc3b11c679dce87131f21a7 Mon Sep 17 00:00:00 2001 From: ry755 Date: Wed, 2 Feb 2022 04:18:57 -0800 Subject: [PATCH] fox32: Use the instruction size when reading from an immediate pointer Previously, Operand::ImmediatePtr always read 32 bits from memory, then truncated the value if the instruction size was smaller. Technically this worked, but it would cause fox32 to print warnings if reading a value at the very end of memory, because it would attempt to read past the end of memory. Now, Operand::ImmediatePtr contains the instruction size which is used by read_source(). This reverts commit 634a776a631c8e34f138dfbbfebf1c5cc74b6f05 --- src/cpu.rs | 68 +++++++++++++++++++++++++++------------------------ src/main.rs | 12 +++------ src/memory.rs | 4 +-- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/cpu.rs b/src/cpu.rs index 6bd252a..801980b 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -112,9 +112,13 @@ impl Cpu { instruction_pointer_offset += 4; // increment past 32 bit immediate value } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(size) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); - let value = self.bus.memory.read_32(pointer); + let value = match size { + Size::Byte => self.bus.memory.read_8(pointer) as u32, + Size::Half => self.bus.memory.read_16(pointer) as u32, + Size::Word => self.bus.memory.read_32(pointer), + }; instruction_pointer_offset += 4; // increment past 32 bit pointer value } @@ -359,7 +363,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -458,7 +462,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -557,7 +561,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -656,7 +660,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -755,7 +759,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -848,7 +852,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -944,7 +948,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1037,7 +1041,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1128,7 +1132,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1218,7 +1222,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1308,7 +1312,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1398,7 +1402,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1494,7 +1498,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1593,7 +1597,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1692,7 +1696,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1791,7 +1795,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1890,7 +1894,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -1978,7 +1982,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2059,7 +2063,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2140,7 +2144,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2228,7 +2232,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2306,7 +2310,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2450,7 +2454,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.relative_to_absolute(self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset)); if should_run { self.bus.memory.write_32(pointer, self.relative_to_absolute(source_value)); @@ -2537,7 +2541,7 @@ impl Cpu { } instruction_pointer_offset += 1; // increment past 8 bit register number } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); match size { Size::Byte => { @@ -2608,7 +2612,7 @@ impl Cpu { self.bus.memory.write_32(pointer, value); } } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); let value = self.bus.read_io(source_value); instruction_pointer_offset += 4; // increment past 32 bit pointer @@ -2639,7 +2643,7 @@ impl Cpu { self.bus.write_io(self.bus.memory.read_32(pointer), source_value); } } - Operand::ImmediatePtr => { + Operand::ImmediatePtr(_) => { let pointer = self.bus.memory.read_32(self.instruction_pointer + instruction_pointer_offset); instruction_pointer_offset += 4; // increment past 32 bit pointer if should_run { @@ -2680,10 +2684,10 @@ enum Operand { Immediate8, Immediate16, Immediate32, - ImmediatePtr, + ImmediatePtr(Size), } -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] enum Size { Byte, Half, @@ -2775,13 +2779,13 @@ impl Instruction { Size::Half => Operand::Immediate16, Size::Word => Operand::Immediate32, }, - 0x03 => Operand::ImmediatePtr, + 0x03 => Operand::ImmediatePtr(size), _ => return None, }; let destination = match (((half & 0x000F) >> 2) as u8) & 0b00000011 { 0x00 => Operand::Register, 0x01 => Operand::RegisterPtr, - 0x02 => Operand::ImmediatePtr, + 0x02 => Operand::ImmediatePtr(size), _ => return None, }; let condition = match (half & 0x00F0) as u8 { diff --git a/src/main.rs b/src/main.rs index 92ddeb3..1527512 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,25 +66,21 @@ fn main() { let mouse = Arc::new(Mutex::new(Mouse::new())); // 32 MiB of shared memory - // plus 3 bytes at the end to allow for reading the last byte of memory as an immediate pointer - // Operand::ImmediatePtr always reads 4 bytes - let shared_memory = Arc::new(Mutex::new(vec![0u8; 0x02000003])); + let shared_memory = Arc::new(Mutex::new(vec![0u8; 0x02000000])); let mut cpu = { // 32 MiB of fast memory - // plus 3 extra bytes at the end to allow for reading the last byte of memory as an immediate pointer - // Operand::ImmediatePtr always reads 4 bytes - let cpu_fast_memory = vec![0; 0x02000003]; + let cpu_fast_memory = vec![0; 0x02000000]; let cpu_shared_memory = Arc::clone(&shared_memory); let cpu_overlays = Arc::clone(&display.overlays); let cpu_read_only_memory = read_rom(); - let fast_size = cpu_fast_memory.len() - 3; + let fast_size = cpu_fast_memory.len(); let fast_bottom_address = 0x00000000; let fast_top_address = fast_bottom_address + fast_size - 1; println!("Fast: {:.2}MB mapped at {:#010X}-{:#010X}", fast_size / 1048576, fast_bottom_address, fast_top_address); - let shared_size = { cpu_shared_memory.lock().unwrap().len() - 3 }; + let shared_size = { cpu_shared_memory.lock().unwrap().len() }; let shared_bottom_address = 0x80000000; let shared_top_address = shared_bottom_address + shared_size - 1; println!("Shared: {:.2}MB mapped at {:#010X}-{:#010X}", shared_size / 1048576, shared_bottom_address, shared_top_address); diff --git a/src/memory.rs b/src/memory.rs index a9ce675..35a5ff6 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -19,9 +19,9 @@ pub struct Memory { impl Memory { pub fn new(fast_memory: Vec, shared_memory: Arc>>, overlays: Arc>>, rom: Vec) -> Self { // 3 extra bytes at the end to allow for reading the last byte of memory as an immediate pointer - let shared_memory_size = { shared_memory.lock().unwrap().len() - 3 }; + let shared_memory_size = { shared_memory.lock().unwrap().len() }; Memory { - fast_memory_size: fast_memory.len() - 3, + fast_memory_size: fast_memory.len(), fast_memory, shared_memory_size, shared_memory,