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
This commit is contained in:
parent
deed31144f
commit
e8287097ad
68
src/cpu.rs
68
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 {
|
||||
|
|
12
src/main.rs
12
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);
|
||||
|
|
|
@ -19,9 +19,9 @@ pub struct Memory {
|
|||
impl Memory {
|
||||
pub fn new(fast_memory: Vec<u8>, shared_memory: Arc<Mutex<Vec<u8>>>, overlays: Arc<Mutex<Vec<Overlay>>>, rom: Vec<u8>) -> 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,
|
||||
|
|
Loading…
Reference in New Issue
Block a user